summaryrefslogtreecommitdiffstats
path: root/mojo/public/python/mojo_bindings/reflection.py
diff options
context:
space:
mode:
authorblundell <blundell@chromium.org>2015-01-19 09:18:33 -0800
committerCommit bot <commit-bot@chromium.org>2015-01-19 17:19:27 +0000
commit70fb54767b472a5edfb859e489beeeec7abdb0e4 (patch)
tree28e534ec774391a9f6571a1770e12a0d63ebf833 /mojo/public/python/mojo_bindings/reflection.py
parentba5f0233fa38f949e24f6274ba891fa652eab640 (diff)
downloadchromium_src-70fb54767b472a5edfb859e489beeeec7abdb0e4.zip
chromium_src-70fb54767b472a5edfb859e489beeeec7abdb0e4.tar.gz
chromium_src-70fb54767b472a5edfb859e489beeeec7abdb0e4.tar.bz2
Move //mojo/{public, edk} underneath //third_party
This CL move //mojo/public and //mojo/edk to live in the following locations: - //third_party/mojo/src/mojo/public - //third_party/mojo/src/mojo/edk It moves the related gypfiles from //mojo to //third_party/mojo and updates them as necessary to account for the file moves. It also updates clients of the mojo SDK and EDK targets in both GYP and GN. (Note that for GN, the mojo SDK and EDK build systems are maintained in the Mojo repo and designed to be flexible wrt the location of the SDK/EDK in a client repo, so no changes are needed. This CL does not update include paths to the code being moved to limit the number of moving parts, instead relying on the include_dirs that the SDK and EDK targets supply to their direct dependents to ensure that include paths continue to resolve correctly. NOPRESUBMIT=true Review URL: https://codereview.chromium.org/814543006 Cr-Commit-Position: refs/heads/master@{#312129}
Diffstat (limited to 'mojo/public/python/mojo_bindings/reflection.py')
-rw-r--r--mojo/public/python/mojo_bindings/reflection.py569
1 files changed, 0 insertions, 569 deletions
diff --git a/mojo/public/python/mojo_bindings/reflection.py b/mojo/public/python/mojo_bindings/reflection.py
deleted file mode 100644
index 5432691..0000000
--- a/mojo/public/python/mojo_bindings/reflection.py
+++ /dev/null
@@ -1,569 +0,0 @@
-# Copyright 2014 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-"""The metaclasses used by the mojo python bindings."""
-
-import itertools
-import logging
-import sys
-
-# pylint: disable=F0401
-import mojo_bindings.messaging as messaging
-import mojo_bindings.promise as promise
-import mojo_bindings.serialization as serialization
-
-
-class MojoEnumType(type):
- """Meta class for enumerations.
-
- Usage:
- class MyEnum(object):
- __metaclass__ = MojoEnumType
- VALUES = [
- ('A', 0),
- 'B',
- ('C', 5),
- ]
-
- This will define a enum with 3 values, 'A' = 0, 'B' = 1 and 'C' = 5.
- """
-
- def __new__(mcs, name, bases, dictionary):
- dictionary['__slots__'] = ()
- dictionary['__new__'] = None
- for value in dictionary.pop('VALUES', []):
- if not isinstance(value, tuple):
- raise ValueError('incorrect value: %r' % value)
- key, enum_value = value
- if isinstance(key, str) and isinstance(enum_value, int):
- dictionary[key] = enum_value
- else:
- raise ValueError('incorrect value: %r' % value)
- return type.__new__(mcs, name, bases, dictionary)
-
- def __setattr__(cls, key, value):
- raise AttributeError('can\'t set attribute')
-
- def __delattr__(cls, key):
- raise AttributeError('can\'t delete attribute')
-
-
-class MojoStructType(type):
- """Meta class for structs.
-
- Usage:
- class MyStruct(object):
- __metaclass__ = MojoStructType
- DESCRIPTOR = {
- 'constants': {
- 'C1': 1,
- 'C2': 2,
- },
- 'enums': {
- 'ENUM1': [
- ('V1', 1),
- 'V2',
- ],
- 'ENUM2': [
- ('V1', 1),
- 'V2',
- ],
- },
- 'fields': [
- SingleFieldGroup('x', _descriptor.TYPE_INT32, 0, 0),
- ],
- }
-
- This will define an struct, with:
- - 2 constants 'C1' and 'C2';
- - 2 enums 'ENUM1' and 'ENUM2', each of those having 2 values, 'V1' and
- 'V2';
- - 1 int32 field named 'x'.
- """
-
- def __new__(mcs, name, bases, dictionary):
- dictionary['__slots__'] = ('_fields')
- descriptor = dictionary.pop('DESCRIPTOR', {})
-
- # Add constants
- dictionary.update(descriptor.get('constants', {}))
-
- # Add enums
- enums = descriptor.get('enums', {})
- for key in enums:
- dictionary[key] = MojoEnumType(key, (object,), { 'VALUES': enums[key] })
-
- # Add fields
- groups = descriptor.get('fields', [])
-
- fields = list(
- itertools.chain.from_iterable([group.descriptors for group in groups]))
- fields.sort(key=lambda f: f.index)
- for field in fields:
- dictionary[field.name] = _BuildProperty(field)
-
- # Add init
- dictionary['__init__'] = _StructInit(fields)
-
- # Add serialization method
- serialization_object = serialization.Serialization(groups)
- def Serialize(self, handle_offset=0):
- return serialization_object.Serialize(self, handle_offset)
- dictionary['Serialize'] = Serialize
-
- # pylint: disable=W0212
- def AsDict(self):
- return self._fields
- dictionary['AsDict'] = AsDict
-
- def Deserialize(cls, context):
- result = cls.__new__(cls)
- fields = {}
- serialization_object.Deserialize(fields, context)
- result._fields = fields
- return result
- dictionary['Deserialize'] = classmethod(Deserialize)
-
- dictionary['__eq__'] = _StructEq(fields)
- dictionary['__ne__'] = _StructNe
-
- return type.__new__(mcs, name, bases, dictionary)
-
- # Prevent adding new attributes, or mutating constants.
- def __setattr__(cls, key, value):
- raise AttributeError('can\'t set attribute')
-
- # Prevent deleting constants.
- def __delattr__(cls, key):
- raise AttributeError('can\'t delete attribute')
-
-
-class MojoInterfaceType(type):
- """Meta class for interfaces.
-
- Usage:
- class MyInterface(object):
- __metaclass__ = MojoInterfaceType
- DESCRIPTOR = {
- 'client': MyInterfaceClient,
- 'methods': [
- {
- 'name': 'FireAndForget',
- 'ordinal': 0,
- 'parameters': [
- SingleFieldGroup('x', _descriptor.TYPE_INT32, 0, 0),
- ]
- },
- {
- 'name': 'Ping',
- 'ordinal': 1,
- 'parameters': [
- SingleFieldGroup('x', _descriptor.TYPE_INT32, 0, 0),
- ],
- 'responses': [
- SingleFieldGroup('x', _descriptor.TYPE_INT32, 0, 0),
- ],
- },
- ],
- }
- """
-
- def __new__(mcs, name, bases, dictionary):
- # If one of the base class is already an interface type, do not edit the
- # class.
- for base in bases:
- if isinstance(base, mcs):
- return type.__new__(mcs, name, bases, dictionary)
-
- descriptor = dictionary.pop('DESCRIPTOR', {})
-
- methods = [_MethodDescriptor(x) for x in descriptor.get('methods', [])]
- for method in methods:
- dictionary[method.name] = _NotImplemented
- client_class_getter = descriptor.get('client', None)
-
- interface_manager = InterfaceManager(name, methods, client_class_getter)
- dictionary.update({
- 'client': None,
- 'manager': None,
- '_interface_manager': interface_manager,
- })
-
- interface_class = type.__new__(mcs, name, bases, dictionary)
- interface_manager.interface_class = interface_class
- return interface_class
-
- @property
- def manager(cls):
- return cls._interface_manager
-
- # Prevent adding new attributes, or mutating constants.
- def __setattr__(cls, key, value):
- raise AttributeError('can\'t set attribute')
-
- # Prevent deleting constants.
- def __delattr__(cls, key):
- raise AttributeError('can\'t delete attribute')
-
-
-class InterfaceProxy(object):
- """
- A proxy allows to access a remote interface through a message pipe.
- """
- pass
-
-
-class InterfaceRequest(object):
- """
- An interface request allows to send a request for an interface to a remote
- object and start using it immediately.
- """
-
- def __init__(self, handle):
- self._handle = handle
-
- def IsPending(self):
- return self._handle.IsValid()
-
- def PassMessagePipe(self):
- result = self._handle
- self._handle = None
- return result
-
-
-class InterfaceManager(object):
- """
- Manager for an interface class. The manager contains the operation that allows
- to bind an implementation to a pipe, or to generate a proxy for an interface
- over a pipe.
- """
-
- def __init__(self, name, methods, client_class_getter):
- self.name = name
- self.methods = methods
- self.interface_class = None
- self._client_class_getter = client_class_getter
- self._client_manager = None
- self._client_manager_computed = False
- self._proxy_class = None
- self._stub_class = None
-
- @property
- def client_manager(self):
- if not self._client_manager_computed:
- self._client_manager_computed = True
- if self._client_class_getter:
- self._client_manager = self._client_class_getter().manager
- return self._client_manager
-
- def Proxy(self, handle):
- router = messaging.Router(handle)
- error_handler = _ProxyErrorHandler()
- router.SetErrorHandler(error_handler)
- router.Start()
- return self._InternalProxy(router, error_handler)
-
- # pylint: disable=W0212
- def Bind(self, impl, handle):
- router = messaging.Router(handle)
- router.SetIncomingMessageReceiver(self._Stub(impl))
- error_handler = _ProxyErrorHandler()
- router.SetErrorHandler(error_handler)
-
- # Retain the router, until an error happen.
- retainer = _Retainer(router)
- def Cleanup(_):
- retainer.release()
- error_handler.AddCallback(Cleanup)
-
- if self.client_manager:
- impl.client = self.client_manager._InternalProxy(router, error_handler)
-
- # Give an instance manager to the implementation to allow it to close
- # the connection.
- impl.manager = InstanceManager(router)
-
- router.Start()
-
- def _InternalProxy(self, router, error_handler):
- if not self._proxy_class:
- dictionary = {
- '__module__': __name__,
- '__init__': _ProxyInit,
- }
- if self.client_manager:
- dictionary['client'] = property(_ProxyGetClient, _ProxySetClient)
- dictionary['manager'] = None
- dictionary['_client_manager'] = self.client_manager
- for method in self.methods:
- dictionary[method.name] = _ProxyMethodCall(method)
- self._proxy_class = type('%sProxy' % self.name,
- (self.interface_class, InterfaceProxy),
- dictionary)
-
- proxy = self._proxy_class(router, error_handler)
- # Give an instance manager to the proxy to allow to close the connection.
- proxy.manager = InstanceManager(router)
- return proxy
-
- def _Stub(self, impl):
- if not self._stub_class:
- accept_method = _StubAccept(self.methods)
- dictionary = {
- '__module__': __name__,
- '__init__': _StubInit,
- 'Accept': accept_method,
- 'AcceptWithResponder': accept_method,
- }
- self._stub_class = type('%sStub' % self.name,
- (messaging.MessageReceiverWithResponder,),
- dictionary)
- return self._stub_class(impl)
-
-
-class InstanceManager(object):
- """
- Manager for the implementation of an interface or a proxy. The manager allows
- to control the connection over the pipe.
- """
- def __init__(self, router):
- self.router = router
-
- def Close(self):
- self.router.Close()
-
- def PassMessagePipe(self):
- return self.router.PassMessagePipe()
-
-
-class _MethodDescriptor(object):
- def __init__(self, descriptor):
- self.name = descriptor['name']
- self.ordinal = descriptor['ordinal']
- self.parameters_struct = _ConstructParameterStruct(
- descriptor['parameters'], self.name, "Parameters")
- self.response_struct = _ConstructParameterStruct(
- descriptor.get('responses'), self.name, "Responses")
-
-
-def _ConstructParameterStruct(descriptor, name, suffix):
- if descriptor is None:
- return None
- parameter_dictionary = {
- '__metaclass__': MojoStructType,
- '__module__': __name__,
- 'DESCRIPTOR': descriptor,
- }
- return MojoStructType(
- '%s%s' % (name, suffix),
- (object,),
- parameter_dictionary)
-
-
-class _ProxyErrorHandler(messaging.ConnectionErrorHandler):
- def __init__(self):
- messaging.ConnectionErrorHandler.__init__(self)
- self._callbacks = set()
-
- def OnError(self, result):
- exception = messaging.MessagingException('Mojo error: %d' % result)
- for callback in list(self._callbacks):
- callback(exception)
- self._callbacks = None
-
- def AddCallback(self, callback):
- if self._callbacks is not None:
- self._callbacks.add(callback)
-
- def RemoveCallback(self, callback):
- if self._callbacks:
- self._callbacks.remove(callback)
-
-
-class _Retainer(object):
-
- # Set to force instances to be retained.
- _RETAINED = set()
-
- def __init__(self, retained):
- self._retained = retained
- _Retainer._RETAINED.add(self)
-
- def release(self):
- self._retained = None
- _Retainer._RETAINED.remove(self)
-
-
-def _StructInit(fields):
- def _Init(self, *args, **kwargs):
- if len(args) + len(kwargs) > len(fields):
- raise TypeError('__init__() takes %d argument (%d given)' %
- (len(fields), len(args) + len(kwargs)))
- self._fields = {}
- for f, a in zip(fields, args):
- self.__setattr__(f.name, a)
- remaining_fields = set(x.name for x in fields[len(args):])
- for name in kwargs:
- if not name in remaining_fields:
- if name in (x.name for x in fields[:len(args)]):
- raise TypeError(
- '__init__() got multiple values for keyword argument %r' % name)
- raise TypeError('__init__() got an unexpected keyword argument %r' %
- name)
- self.__setattr__(name, kwargs[name])
- return _Init
-
-
-def _BuildProperty(field):
- """Build the property for the given field."""
-
- # pylint: disable=W0212
- def Get(self):
- if field.name not in self._fields:
- self._fields[field.name] = field.GetDefaultValue()
- return self._fields[field.name]
-
- # pylint: disable=W0212
- def Set(self, value):
- self._fields[field.name] = field.field_type.Convert(value)
-
- return property(Get, Set)
-
-
-def _StructEq(fields):
- def _Eq(self, other):
- if type(self) is not type(other):
- return False
- for field in fields:
- if getattr(self, field.name) != getattr(other, field.name):
- return False
- return True
- return _Eq
-
-def _StructNe(self, other):
- return not self.__eq__(other)
-
-
-def _ProxyInit(self, router, error_handler):
- self._router = router
- self._error_handler = error_handler
- self._client = None
-
-
-# pylint: disable=W0212
-def _ProxyGetClient(self):
- return self._client
-
-
-# pylint: disable=W0212
-def _ProxySetClient(self, client):
- self._client = client
- stub = self._client_manager._Stub(client)
- self._router.SetIncomingMessageReceiver(stub)
-
-
-# pylint: disable=W0212
-def _ProxyMethodCall(method):
- flags = messaging.NO_FLAG
- if method.response_struct:
- flags = messaging.MESSAGE_EXPECTS_RESPONSE_FLAG
- def _Call(self, *args, **kwargs):
- def GenerationMethod(resolve, reject):
- message = _GetMessage(method, flags, *args, **kwargs)
- if method.response_struct:
- def Accept(message):
- try:
- assert message.header.message_type == method.ordinal
- payload = message.payload
- response = method.response_struct.Deserialize(
- serialization.RootDeserializationContext(payload.data,
- payload.handles))
- as_dict = response.AsDict()
- if len(as_dict) == 1:
- value = as_dict.values()[0]
- if not isinstance(value, dict):
- response = value
- resolve(response)
- return True
- except Exception as e:
- # Adding traceback similarly to python 3.0 (pep-3134)
- e.__traceback__ = sys.exc_info()[2]
- reject(e)
- return False
- finally:
- self._error_handler.RemoveCallback(reject)
-
- self._error_handler.AddCallback(reject)
- if not self._router.AcceptWithResponder(
- message, messaging.ForwardingMessageReceiver(Accept)):
- self._error_handler.RemoveCallback(reject)
- reject(messaging.MessagingException("Unable to send message."))
- else:
- if (self._router.Accept(message)):
- resolve(None)
- else:
- reject(messaging.MessagingException("Unable to send message."))
- return promise.Promise(GenerationMethod)
- return _Call
-
-
-def _GetMessage(method, flags, *args, **kwargs):
- if flags == messaging.MESSAGE_IS_RESPONSE_FLAG:
- struct = method.response_struct(*args, **kwargs)
- else:
- struct = method.parameters_struct(*args, **kwargs)
- header = messaging.MessageHeader(method.ordinal, flags)
- data = header.Serialize()
- (payload, handles) = struct.Serialize()
- data.extend(payload)
- return messaging.Message(data, handles, header)
-
-
-def _StubInit(self, impl):
- self.impl = impl
-
-
-def _StubAccept(methods):
- methods_by_ordinal = dict((m.ordinal, m) for m in methods)
- def Accept(self, message, responder=None):
- try:
- header = message.header
- assert header.expects_response == bool(responder)
- assert header.message_type in methods_by_ordinal
- method = methods_by_ordinal[header.message_type]
- payload = message.payload
- parameters = method.parameters_struct.Deserialize(
- serialization.RootDeserializationContext(
- payload.data, payload.handles)).AsDict()
- response = getattr(self.impl, method.name)(**parameters)
- if header.expects_response:
- def SendResponse(response):
- if isinstance(response, dict):
- response_message = _GetMessage(method,
- messaging.MESSAGE_IS_RESPONSE_FLAG,
- **response)
- else:
- response_message = _GetMessage(method,
- messaging.MESSAGE_IS_RESPONSE_FLAG,
- response)
- response_message.header.request_id = header.request_id
- responder.Accept(response_message)
- p = promise.Promise.Resolve(response).Then(SendResponse)
- if self.impl.manager:
- # Close the connection in case of error.
- p.Catch(lambda _: self.impl.manager.Close())
- return True
- # pylint: disable=W0702
- except:
- # Close the connection in case of error.
- logging.warning(
- 'Error occured in accept method. Connection will be closed.')
- if self.impl.manager:
- self.impl.manager.Close()
- return False
- return Accept
-
-
-def _NotImplemented(*_1, **_2):
- raise NotImplementedError()