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

Side by Side Diff: mojo/public/tools/bindings/pylib/mojom/generate/module.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 2013 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 # This module's classes provide an interface to mojo modules. Modules are
6 # collections of interfaces and structs to be used by mojo ipc clients and
7 # servers.
8 #
9 # A simple interface would be created this way:
10 # module = mojom.generate.module.Module('Foo')
11 # interface = module.AddInterface('Bar')
12 # method = interface.AddMethod('Tat', 0)
13 # method.AddParameter('baz', 0, mojom.INT32)
14
15
16 class Kind(object):
17 def __init__(self, spec=None):
18 self.spec = spec
19 self.parent_kind = None
20
21
22 class ReferenceKind(Kind):
23 """ReferenceKind represents pointer types and handle types.
24 A type is nullable if null (for pointer types) or invalid handle (for handle
25 types) is a legal value for the type.
26 """
27
28 def __init__(self, spec=None, is_nullable=False):
29 assert spec is None or is_nullable == spec.startswith('?')
30 Kind.__init__(self, spec)
31 self.is_nullable = is_nullable
32 self.shared_definition = {}
33
34 def MakeNullableKind(self):
35 assert not self.is_nullable
36
37 if self == STRING:
38 return NULLABLE_STRING
39 if self == HANDLE:
40 return NULLABLE_HANDLE
41 if self == DCPIPE:
42 return NULLABLE_DCPIPE
43 if self == DPPIPE:
44 return NULLABLE_DPPIPE
45 if self == MSGPIPE:
46 return NULLABLE_MSGPIPE
47 if self == SHAREDBUFFER:
48 return NULLABLE_SHAREDBUFFER
49
50 nullable_kind = type(self)()
51 nullable_kind.shared_definition = self.shared_definition
52 if self.spec is not None:
53 nullable_kind.spec = '?' + self.spec
54 nullable_kind.is_nullable = True
55
56 return nullable_kind
57
58 @classmethod
59 def AddSharedProperty(cls, name):
60 """Adds a property |name| to |cls|, which accesses the corresponding item in
61 |shared_definition|.
62
63 The reason of adding such indirection is to enable sharing definition
64 between a reference kind and its nullable variation. For example:
65 a = Struct('test_struct_1')
66 b = a.MakeNullableKind()
67 a.name = 'test_struct_2'
68 print b.name # Outputs 'test_struct_2'.
69 """
70 def Get(self):
71 return self.shared_definition[name]
72
73 def Set(self, value):
74 self.shared_definition[name] = value
75
76 setattr(cls, name, property(Get, Set))
77
78
79 # Initialize the set of primitive types. These can be accessed by clients.
80 BOOL = Kind('b')
81 INT8 = Kind('i8')
82 INT16 = Kind('i16')
83 INT32 = Kind('i32')
84 INT64 = Kind('i64')
85 UINT8 = Kind('u8')
86 UINT16 = Kind('u16')
87 UINT32 = Kind('u32')
88 UINT64 = Kind('u64')
89 FLOAT = Kind('f')
90 DOUBLE = Kind('d')
91 STRING = ReferenceKind('s')
92 HANDLE = ReferenceKind('h')
93 DCPIPE = ReferenceKind('h:d:c')
94 DPPIPE = ReferenceKind('h:d:p')
95 MSGPIPE = ReferenceKind('h:m')
96 SHAREDBUFFER = ReferenceKind('h:s')
97 NULLABLE_STRING = ReferenceKind('?s', True)
98 NULLABLE_HANDLE = ReferenceKind('?h', True)
99 NULLABLE_DCPIPE = ReferenceKind('?h:d:c', True)
100 NULLABLE_DPPIPE = ReferenceKind('?h:d:p', True)
101 NULLABLE_MSGPIPE = ReferenceKind('?h:m', True)
102 NULLABLE_SHAREDBUFFER = ReferenceKind('?h:s', True)
103
104
105 # Collection of all Primitive types
106 PRIMITIVES = (
107 BOOL,
108 INT8,
109 INT16,
110 INT32,
111 INT64,
112 UINT8,
113 UINT16,
114 UINT32,
115 UINT64,
116 FLOAT,
117 DOUBLE,
118 STRING,
119 HANDLE,
120 DCPIPE,
121 DPPIPE,
122 MSGPIPE,
123 SHAREDBUFFER,
124 NULLABLE_STRING,
125 NULLABLE_HANDLE,
126 NULLABLE_DCPIPE,
127 NULLABLE_DPPIPE,
128 NULLABLE_MSGPIPE,
129 NULLABLE_SHAREDBUFFER
130 )
131
132
133 class NamedValue(object):
134 def __init__(self, module=None, parent_kind=None, name=None):
135 self.module = module
136 if module:
137 self.namespace = module.namespace
138 self.parent_kind = parent_kind
139 self.name = name
140 self.imported_from = None
141
142 def GetSpec(self):
143 return (self.namespace + '.' +
144 (self.parent_kind and (self.parent_kind.name + '.') or "") +
145 self.name)
146
147
148 class BuiltinValue(object):
149 def __init__(self, value):
150 self.value = value
151
152
153 class ConstantValue(NamedValue):
154 def __init__(self, module=None, parent_kind=None, constant=None):
155 if constant:
156 NamedValue.__init__(self, module, parent_kind, constant.name)
157 else:
158 NamedValue.__init__(self, module, parent_kind)
159 self.constant = constant
160
161
162 class EnumValue(NamedValue):
163 def __init__(self, module=None, enum=None, field=None):
164 if enum and field:
165 NamedValue.__init__(self, module, enum.parent_kind, field.name)
166 else:
167 NamedValue.__init__(self, module)
168 self.enum = enum
169
170 def GetSpec(self):
171 return (self.namespace + '.' +
172 (self.parent_kind and (self.parent_kind.name + '.') or "") +
173 self.enum.name + '.' + self.name)
174
175
176 class Constant(object):
177 def __init__(self, name=None, kind=None, value=None, parent_kind=None):
178 self.name = name
179 self.kind = kind
180 self.value = value
181 self.parent_kind = parent_kind
182
183
184 class Field(object):
185 def __init__(self, name=None, kind=None, ordinal=None, default=None,
186 attributes=None):
187 if self.__class__.__name__ == 'Field':
188 raise Exception()
189 self.name = name
190 self.kind = kind
191 self.ordinal = ordinal
192 self.default = default
193 self.attributes = attributes
194
195
196 class StructField(Field): pass
197
198
199 class UnionField(Field): pass
200
201
202 class Struct(ReferenceKind):
203 ReferenceKind.AddSharedProperty('name')
204 ReferenceKind.AddSharedProperty('module')
205 ReferenceKind.AddSharedProperty('imported_from')
206 ReferenceKind.AddSharedProperty('fields')
207 ReferenceKind.AddSharedProperty('attributes')
208 ReferenceKind.AddSharedProperty('constants')
209 ReferenceKind.AddSharedProperty('enums')
210 ReferenceKind.AddSharedProperty('type_key')
211
212 def __init__(self, name=None, module=None, attributes=None):
213 if name is not None:
214 spec = 'x:' + name
215 else:
216 spec = None
217 ReferenceKind.__init__(self, spec)
218 self.name = name
219 self.module = module
220 self.imported_from = None
221 self.fields = []
222 self.constants = []
223 self.enums = []
224 self.attributes = attributes
225
226 def AddField(self, name, kind, ordinal=None, default=None, attributes=None):
227 field = StructField(name, kind, ordinal, default, attributes)
228 self.fields.append(field)
229 return field
230
231
232 class Union(ReferenceKind):
233 ReferenceKind.AddSharedProperty('name')
234 ReferenceKind.AddSharedProperty('module')
235 ReferenceKind.AddSharedProperty('imported_from')
236 ReferenceKind.AddSharedProperty('fields')
237 ReferenceKind.AddSharedProperty('attributes')
238 ReferenceKind.AddSharedProperty('type_key')
239
240 def __init__(self, name=None, module=None, attributes=None):
241 if name is not None:
242 spec = 'x:' + name
243 else:
244 spec = None
245 ReferenceKind.__init__(self, spec)
246 self.name = name
247 self.module = module
248 self.imported_from = None
249 self.fields = []
250 self.attributes = attributes
251
252 def AddField(self, name, kind, ordinal=None, attributes=None):
253 field = UnionField(name, kind, ordinal, None, attributes)
254 self.fields.append(field)
255 return field
256
257
258 class Array(ReferenceKind):
259 ReferenceKind.AddSharedProperty('kind')
260 ReferenceKind.AddSharedProperty('length')
261
262 def __init__(self, kind=None, length=None):
263 if kind is not None:
264 if length is not None:
265 spec = 'a%d:%s' % (length, kind.spec)
266 else:
267 spec = 'a:%s' % kind.spec
268
269 ReferenceKind.__init__(self, spec)
270 else:
271 ReferenceKind.__init__(self)
272 self.kind = kind
273 self.length = length
274
275
276 class Map(ReferenceKind):
277 ReferenceKind.AddSharedProperty('key_kind')
278 ReferenceKind.AddSharedProperty('value_kind')
279
280 def __init__(self, key_kind=None, value_kind=None):
281 if (key_kind is not None and value_kind is not None):
282 ReferenceKind.__init__(self,
283 'm[' + key_kind.spec + '][' + value_kind.spec +
284 ']')
285 if IsNullableKind(key_kind):
286 raise Exception("Nullable kinds cannot be keys in maps.")
287 if IsStructKind(key_kind):
288 # TODO(erg): It would sometimes be nice if we could key on struct
289 # values. However, what happens if the struct has a handle in it? Or
290 # non-copyable data like an array?
291 raise Exception("Structs cannot be keys in maps.")
292 if IsAnyHandleKind(key_kind):
293 raise Exception("Handles cannot be keys in maps.")
294 if IsInterfaceKind(key_kind):
295 raise Exception("Interfaces cannot be keys in maps.")
296 if IsArrayKind(key_kind):
297 raise Exception("Arrays cannot be keys in maps.")
298 else:
299 ReferenceKind.__init__(self)
300
301 self.key_kind = key_kind
302 self.value_kind = value_kind
303
304
305 class InterfaceRequest(ReferenceKind):
306 ReferenceKind.AddSharedProperty('kind')
307
308 def __init__(self, kind=None):
309 if kind is not None:
310 if not isinstance(kind, Interface):
311 raise Exception(
312 "Interface request requires %r to be an interface." % kind.spec)
313 ReferenceKind.__init__(self, 'r:' + kind.spec)
314 else:
315 ReferenceKind.__init__(self)
316 self.kind = kind
317
318
319 class Parameter(object):
320 def __init__(self, name=None, kind=None, ordinal=None, default=None,
321 attributes=None):
322 self.name = name
323 self.ordinal = ordinal
324 self.kind = kind
325 self.default = default
326 self.attributes = attributes
327
328
329 class Method(object):
330 def __init__(self, interface, name, ordinal=None, attributes=None):
331 self.interface = interface
332 self.name = name
333 self.ordinal = ordinal
334 self.parameters = []
335 self.response_parameters = None
336 self.attributes = attributes
337
338 def AddParameter(self, name, kind, ordinal=None, default=None,
339 attributes=None):
340 parameter = Parameter(name, kind, ordinal, default, attributes)
341 self.parameters.append(parameter)
342 return parameter
343
344 def AddResponseParameter(self, name, kind, ordinal=None, default=None,
345 attributes=None):
346 if self.response_parameters == None:
347 self.response_parameters = []
348 parameter = Parameter(name, kind, ordinal, default, attributes)
349 self.response_parameters.append(parameter)
350 return parameter
351
352
353 class Interface(ReferenceKind):
354 ReferenceKind.AddSharedProperty('module')
355 ReferenceKind.AddSharedProperty('name')
356 ReferenceKind.AddSharedProperty('imported_from')
357 ReferenceKind.AddSharedProperty('methods')
358 ReferenceKind.AddSharedProperty('attributes')
359 ReferenceKind.AddSharedProperty('constants')
360 ReferenceKind.AddSharedProperty('enums')
361 ReferenceKind.AddSharedProperty('type_key')
362
363 def __init__(self, name=None, module=None, attributes=None):
364 if name is not None:
365 spec = 'x:' + name
366 else:
367 spec = None
368 ReferenceKind.__init__(self, spec)
369 self.module = module
370 self.name = name
371 self.imported_from = None
372 self.methods = []
373 self.enums = []
374 self.constants = []
375 self.attributes = attributes
376
377 def AddMethod(self, name, ordinal=None, attributes=None):
378 method = Method(self, name, ordinal, attributes)
379 self.methods.append(method)
380 return method
381
382 # TODO(451323): Remove when the language backends no longer rely on this.
383 @property
384 def client(self):
385 return None
386
387
388 class EnumField(object):
389 def __init__(self, name=None, value=None, attributes=None,
390 numeric_value=None):
391 self.name = name
392 self.value = value
393 self.attributes = attributes
394 self.numeric_value = numeric_value
395
396
397 class Enum(Kind):
398 def __init__(self, name=None, module=None, attributes=None):
399 self.module = module
400 self.name = name
401 self.imported_from = None
402 if name is not None:
403 spec = 'x:' + name
404 else:
405 spec = None
406 Kind.__init__(self, spec)
407 self.fields = []
408 self.attributes = attributes
409
410
411 class Module(object):
412 def __init__(self, name=None, namespace=None, attributes=None):
413 self.name = name
414 self.path = name
415 self.namespace = namespace
416 self.structs = []
417 self.unions = []
418 self.interfaces = []
419 self.enums = []
420 self.constants = []
421 self.kinds = {}
422 self.attributes = attributes
423 self.imports = []
424 # Transitive imports should contain all of the module's imports plus
425 # all of their imports recursively.
426 self.transitive_imports = []
427
428 def AddInterface(self, name, attributes=None):
429 interface = Interface(name, self, attributes)
430 self.interfaces.append(interface)
431 return interface
432
433 def AddStruct(self, name, attributes=None):
434 struct = Struct(name, self, attributes)
435 self.structs.append(struct)
436 return struct
437
438 def AddUnion(self, name, attributes=None):
439 union = Union(name, self, attributes)
440 self.unions.append(union)
441 return union
442
443 def GetPackageName(kind):
444 """Get the package name from the given kind's module."""
445 return kind.module.name.split('.')[0]
446
447 def IsBoolKind(kind):
448 return kind.spec == BOOL.spec
449
450
451 def IsFloatKind(kind):
452 return kind.spec == FLOAT.spec
453
454
455 def IsDoubleKind(kind):
456 return kind.spec == DOUBLE.spec
457
458
459 def IsIntegralKind(kind):
460 return (kind.spec == BOOL.spec or
461 kind.spec == INT8.spec or
462 kind.spec == INT16.spec or
463 kind.spec == INT32.spec or
464 kind.spec == INT64.spec or
465 kind.spec == UINT8.spec or
466 kind.spec == UINT16.spec or
467 kind.spec == UINT32.spec or
468 kind.spec == UINT64.spec)
469
470 def IsNumericalKind(kind):
471 return (IsBoolKind(kind) or
472 IsFloatKind(kind) or
473 IsDoubleKind(kind) or
474 IsIntegralKind(kind))
475
476 def IsStringKind(kind):
477 return kind.spec == STRING.spec or kind.spec == NULLABLE_STRING.spec
478
479
480 def IsGenericHandleKind(kind):
481 return kind.spec == HANDLE.spec or kind.spec == NULLABLE_HANDLE.spec
482
483
484 def IsDataPipeConsumerKind(kind):
485 return kind.spec == DCPIPE.spec or kind.spec == NULLABLE_DCPIPE.spec
486
487
488 def IsDataPipeProducerKind(kind):
489 return kind.spec == DPPIPE.spec or kind.spec == NULLABLE_DPPIPE.spec
490
491
492 def IsMessagePipeKind(kind):
493 return kind.spec == MSGPIPE.spec or kind.spec == NULLABLE_MSGPIPE.spec
494
495
496 def IsSharedBufferKind(kind):
497 return (kind.spec == SHAREDBUFFER.spec or
498 kind.spec == NULLABLE_SHAREDBUFFER.spec)
499
500
501 def IsStructKind(kind):
502 return isinstance(kind, Struct)
503
504
505 def IsUnionKind(kind):
506 return isinstance(kind, Union)
507
508
509 def IsArrayKind(kind):
510 return isinstance(kind, Array)
511
512
513 def IsInterfaceKind(kind):
514 return isinstance(kind, Interface)
515
516
517 def IsInterfaceRequestKind(kind):
518 return isinstance(kind, InterfaceRequest)
519
520
521 def IsEnumKind(kind):
522 return isinstance(kind, Enum)
523
524
525 def IsReferenceKind(kind):
526 return isinstance(kind, ReferenceKind)
527
528
529 def IsNullableKind(kind):
530 return IsReferenceKind(kind) and kind.is_nullable
531
532
533 def IsMapKind(kind):
534 return isinstance(kind, Map)
535
536
537 def IsObjectKind(kind):
538 return IsPointerKind(kind) or IsUnionKind(kind)
539
540
541 def IsPointerKind(kind):
542 return (IsStructKind(kind) or IsArrayKind(kind) or IsStringKind(kind) or
543 IsMapKind(kind))
544
545
546 # Please note that interface is not considered as handle kind, since it is an
547 # aggregate type consisting of a handle and a version number.
548 def IsAnyHandleKind(kind):
549 return (IsGenericHandleKind(kind) or
550 IsDataPipeConsumerKind(kind) or
551 IsDataPipeProducerKind(kind) or
552 IsMessagePipeKind(kind) or
553 IsSharedBufferKind(kind) or
554 IsInterfaceRequestKind(kind))
555
556
557 def IsMoveOnlyKind(kind):
558 return (not IsStringKind(kind) and IsObjectKind(kind)) or \
559 IsAnyHandleKind(kind) or IsInterfaceKind(kind)
560
561
562 def ContainsHandles(kind, visited_kinds):
563 if kind in visited_kinds:
564 # No need to examine the kind again.
565 return False
566 visited_kinds.add(kind)
567 if IsAnyHandleKind(kind) or IsInterfaceKind(kind):
568 return True
569 if IsArrayKind(kind):
570 return ContainsHandles(kind.kind, visited_kinds)
571 if IsStructKind(kind) or IsUnionKind(kind):
572 for field in kind.fields:
573 if ContainsHandles(field.kind, visited_kinds):
574 return True
575 if IsMapKind(kind):
576 # No need to examine the key kind, only primitive kinds and non-nullable
577 # string are allowed to be key kinds.
578 return ContainsHandles(kind.value_kind, visited_kinds)
579 return False
580
581
582 def IsCloneableKind(kind):
583 return not ContainsHandles(kind, set())
584
585
586 def HasCallbacks(interface):
587 for method in interface.methods:
588 if method.response_parameters != None:
589 return True
590 return False
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698