Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(112)

Side by Side Diff: mojo/public/python/mojo_bindings/reflection.py

Issue 2250183003: Make the fuchsia mojo/public repo the source of truth. (Closed) Base URL: https://github.com/domokit/mojo.git@master
Patch Set: Created 4 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 # Copyright 2014 The Chromium Authors. All rights reserved.
2 # Use of this source code is governed by a BSD-style license that can be
3 # found in the LICENSE file.
4
5 """The metaclasses used by the mojo python bindings."""
6
7 import itertools
8
9 # pylint: disable=F0401
10 import mojo_bindings.serialization as serialization
11
12
13 class MojoEnumType(type):
14 """Meta class for enumerations.
15
16 Usage:
17 class MyEnum(object):
18 __metaclass__ = MojoEnumType
19 VALUES = [
20 ('A', 0),
21 'B',
22 ('C', 5),
23 ]
24
25 This will define a enum with 3 values, 'A' = 0, 'B' = 1 and 'C' = 5.
26 """
27
28 def __new__(mcs, name, bases, dictionary):
29 dictionary['__slots__'] = ()
30 dictionary['__new__'] = None
31 for value in dictionary.pop('VALUES', []):
32 if not isinstance(value, tuple):
33 raise ValueError('incorrect value: %r' % value)
34 key, enum_value = value
35 if isinstance(key, str) and isinstance(enum_value, int):
36 dictionary[key] = enum_value
37 else:
38 raise ValueError('incorrect value: %r' % value)
39 return type.__new__(mcs, name, bases, dictionary)
40
41 def __setattr__(cls, key, value):
42 raise AttributeError('can\'t set attribute')
43
44 def __delattr__(cls, key):
45 raise AttributeError('can\'t delete attribute')
46
47
48 class MojoStructType(type):
49 """Meta class for structs.
50
51 Usage:
52 class MyStruct(object):
53 __metaclass__ = MojoStructType
54 DESCRIPTOR = {
55 'constants': {
56 'C1': 1,
57 'C2': 2,
58 },
59 'enums': {
60 'ENUM1': [
61 ('V1', 1),
62 'V2',
63 ],
64 'ENUM2': [
65 ('V1', 1),
66 'V2',
67 ],
68 },
69 'fields': [
70 SingleFieldGroup('x', _descriptor.TYPE_INT32, 0, 0),
71 ],
72 }
73
74 This will define an struct, with:
75 - 2 constants 'C1' and 'C2';
76 - 2 enums 'ENUM1' and 'ENUM2', each of those having 2 values, 'V1' and
77 'V2';
78 - 1 int32 field named 'x'.
79 """
80
81 def __new__(mcs, name, bases, dictionary):
82 dictionary['__slots__'] = ('_fields')
83 descriptor = dictionary.pop('DESCRIPTOR', {})
84
85 # Add constants
86 dictionary.update(descriptor.get('constants', {}))
87
88 # Add enums
89 enums = descriptor.get('enums', {})
90 for key in enums:
91 dictionary[key] = MojoEnumType(key, (object,), { 'VALUES': enums[key] })
92
93 # Add fields
94 groups = descriptor.get('fields', [])
95
96 fields = list(
97 itertools.chain.from_iterable([group.descriptors for group in groups]))
98 fields.sort(key=lambda f: f.index)
99 for field in fields:
100 dictionary[field.name] = _BuildProperty(field)
101
102 # Add init
103 dictionary['__init__'] = _StructInit(fields)
104
105 # Add serialization method
106 serialization_object = serialization.Serialization(groups)
107 def Serialize(self, handle_offset=0):
108 return serialization_object.Serialize(self, handle_offset)
109 dictionary['Serialize'] = Serialize
110
111 # pylint: disable=W0212
112 def AsDict(self):
113 return self._fields
114 dictionary['AsDict'] = AsDict
115
116 def Deserialize(cls, context):
117 result = cls.__new__(cls)
118 fields = {}
119 serialization_object.Deserialize(fields, context)
120 result._fields = fields
121 return result
122 dictionary['Deserialize'] = classmethod(Deserialize)
123
124 dictionary['__eq__'] = _StructEq(fields)
125 dictionary['__ne__'] = _StructNe
126
127 return type.__new__(mcs, name, bases, dictionary)
128
129 # Prevent adding new attributes, or mutating constants.
130 def __setattr__(cls, key, value):
131 raise AttributeError('can\'t set attribute')
132
133 # Prevent deleting constants.
134 def __delattr__(cls, key):
135 raise AttributeError('can\'t delete attribute')
136
137
138 class MojoUnionType(type):
139
140 def __new__(mcs, name, bases, dictionary):
141 dictionary['__slots__'] = ('_cur_field', '_data')
142 descriptor = dictionary.pop('DESCRIPTOR', {})
143
144 fields = descriptor.get('fields', [])
145 def _BuildUnionProperty(field):
146
147 # pylint: disable=W0212
148 def Get(self):
149 if self._cur_field != field:
150 raise AttributeError('%s is not currently set' % field.name,
151 field.name, self._cur_field.name)
152 return self._data
153
154 # pylint: disable=W0212
155 def Set(self, value):
156 self._cur_field = field
157 self._data = field.field_type.Convert(value)
158
159 return property(Get, Set)
160
161 for field in fields:
162 dictionary[field.name] = _BuildUnionProperty(field)
163
164 def UnionInit(self, **kwargs):
165 self.SetInternals(None, None)
166 items = kwargs.items()
167 if len(items) == 0:
168 return
169
170 if len(items) > 1:
171 raise TypeError('only 1 member may be set on a union.')
172
173 setattr(self, items[0][0], items[0][1])
174 dictionary['__init__'] = UnionInit
175
176 serializer = serialization.UnionSerializer(fields)
177 def SerializeUnionInline(self, handle_offset=0):
178 return serializer.SerializeInline(self, handle_offset)
179 dictionary['SerializeInline'] = SerializeUnionInline
180
181 def SerializeUnion(self, handle_offset=0):
182 return serializer.Serialize(self, handle_offset)
183 dictionary['Serialize'] = SerializeUnion
184
185 def DeserializeUnion(cls, context):
186 return serializer.Deserialize(context, cls)
187 dictionary['Deserialize'] = classmethod(DeserializeUnion)
188
189 class Tags(object):
190 __metaclass__ = MojoEnumType
191 VALUES = [(field.name, field.index) for field in fields]
192 dictionary['Tags'] = Tags
193
194 def GetTag(self):
195 return self._cur_field.index
196 dictionary['tag'] = property(GetTag, None)
197
198 def GetData(self):
199 return self._data
200 dictionary['data'] = property(GetData, None)
201
202 def IsUnknown(self):
203 return not self._cur_field
204 dictionary['IsUnknown'] = IsUnknown
205
206 def UnionEq(self, other):
207 return (
208 (type(self) is type(other))
209 and (self.tag == other.tag)
210 and (self.data == other.data))
211 dictionary['__eq__'] = UnionEq
212
213 def UnionNe(self, other):
214 return not self.__eq__(other)
215 dictionary['__ne__'] = UnionNe
216
217 def UnionStr(self):
218 return '<%s.%s(%s): %s>' % (
219 self.__class__.__name__,
220 self._cur_field.name,
221 self.tag,
222 self.data)
223 dictionary['__str__'] = UnionStr
224 dictionary['__repr__'] = UnionStr
225
226 def SetInternals(self, field, data):
227 self._cur_field = field
228 self._data = data
229 dictionary['SetInternals'] = SetInternals
230
231
232 return type.__new__(mcs, name, bases, dictionary)
233
234
235 class InterfaceRequest(object):
236 """
237 An interface request allows to send a request for an interface to a remote
238 object and start using it immediately.
239 """
240
241 def __init__(self, handle):
242 self._handle = handle
243
244 def IsPending(self):
245 return self._handle.IsValid()
246
247 def PassMessagePipe(self):
248 result = self._handle
249 self._handle = None
250 return result
251
252 def Bind(self, impl):
253 type(impl).manager.Bind(impl, self.PassMessagePipe())
254
255
256 class InterfaceProxy(object):
257 """
258 A proxy allows to access a remote interface through a message pipe.
259 """
260 pass
261
262
263 def _StructInit(fields):
264 def _Init(self, *args, **kwargs):
265 if len(args) + len(kwargs) > len(fields):
266 raise TypeError('__init__() takes %d argument (%d given)' %
267 (len(fields), len(args) + len(kwargs)))
268 self._fields = {}
269 for f, a in zip(fields, args):
270 self.__setattr__(f.name, a)
271 remaining_fields = set(x.name for x in fields[len(args):])
272 for name in kwargs:
273 if not name in remaining_fields:
274 if name in (x.name for x in fields[:len(args)]):
275 raise TypeError(
276 '__init__() got multiple values for keyword argument %r' % name)
277 raise TypeError('__init__() got an unexpected keyword argument %r' %
278 name)
279 self.__setattr__(name, kwargs[name])
280 return _Init
281
282
283 def _BuildProperty(field):
284 """Build the property for the given field."""
285
286 # pylint: disable=W0212
287 def Get(self):
288 if field.name not in self._fields:
289 self._fields[field.name] = field.GetDefaultValue()
290 return self._fields[field.name]
291
292 # pylint: disable=W0212
293 def Set(self, value):
294 self._fields[field.name] = field.field_type.Convert(value)
295
296 return property(Get, Set)
297
298
299 def _StructEq(fields):
300 def _Eq(self, other):
301 if type(self) is not type(other):
302 return False
303 for field in fields:
304 if getattr(self, field.name) != getattr(other, field.name):
305 return False
306 return True
307 return _Eq
308
309 def _StructNe(self, other):
310 return not self.__eq__(other)
OLDNEW
« no previous file with comments | « mojo/public/python/mojo_bindings/promise.py ('k') | mojo/public/python/mojo_bindings/serialization.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698