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.
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
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)
17 def __init__(self, spec=None):
19 self.parent_kind = None
22 class ReferenceKind(Kind):
23 """ReferenceKind represents pointer types and handle types.
24 A type is nullable means that NULL (for pointer types) or invalid handle
25 (for handle types) is a legal value for the type.
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 = {}
34 def MakeNullableKind(self):
35 assert not self.is_nullable
38 return NULLABLE_STRING
40 return NULLABLE_HANDLE
42 return NULLABLE_DCPIPE
44 return NULLABLE_DPPIPE
46 return NULLABLE_MSGPIPE
47 if self == SHAREDBUFFER:
48 return NULLABLE_SHAREDBUFFER
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
59 def AddSharedProperty(cls, name):
60 """Adds a property |name| to |cls|, which accesses the corresponding item in
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'.
71 return self.shared_definition[name]
74 self.shared_definition[name] = value
76 setattr(cls, name, property(Get, Set))
79 # Initialize the set of primitive types. These can be accessed by clients.
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)
105 # Collection of all Primitive types
129 NULLABLE_SHAREDBUFFER
133 class NamedValue(object):
134 def __init__(self, module, parent_kind, name):
136 self.namespace = module.namespace
137 self.parent_kind = parent_kind
139 self.imported_from = None
142 return (self.namespace + '.' +
143 (self.parent_kind and (self.parent_kind.name + '.') or "") +
147 class BuiltinValue(object):
148 def __init__(self, value):
152 class ConstantValue(NamedValue):
153 def __init__(self, module, parent_kind, constant):
154 NamedValue.__init__(self, module, parent_kind, constant.name)
155 self.constant = constant
158 class EnumValue(NamedValue):
159 def __init__(self, module, enum, field):
160 NamedValue.__init__(self, module, enum.parent_kind, field.name)
164 return (self.namespace + '.' +
165 (self.parent_kind and (self.parent_kind.name + '.') or "") +
166 self.enum.name + '.' + self.name)
169 class Constant(object):
170 def __init__(self, name=None, kind=None, value=None):
177 def __init__(self, name=None, kind=None, ordinal=None, default=None):
180 self.ordinal = ordinal
181 self.default = default
184 class Struct(ReferenceKind):
185 ReferenceKind.AddSharedProperty('name')
186 ReferenceKind.AddSharedProperty('module')
187 ReferenceKind.AddSharedProperty('imported_from')
188 ReferenceKind.AddSharedProperty('fields')
190 def __init__(self, name=None, module=None):
195 ReferenceKind.__init__(self, spec)
198 self.imported_from = None
201 def AddField(self, name, kind, ordinal=None, default=None):
202 field = Field(name, kind, ordinal, default)
203 self.fields.append(field)
207 class Array(ReferenceKind):
208 ReferenceKind.AddSharedProperty('kind')
210 def __init__(self, kind=None):
212 ReferenceKind.__init__(self, 'a:' + kind.spec)
214 ReferenceKind.__init__(self)
218 class FixedArray(ReferenceKind):
219 ReferenceKind.AddSharedProperty('kind')
220 ReferenceKind.AddSharedProperty('length')
222 def __init__(self, length=-1, kind=None):
224 ReferenceKind.__init__(self, 'a%d:%s' % (length, kind.spec))
226 ReferenceKind.__init__(self)
231 class InterfaceRequest(ReferenceKind):
232 ReferenceKind.AddSharedProperty('kind')
234 def __init__(self, kind=None):
236 ReferenceKind.__init__(self, 'r:' + kind.spec)
238 ReferenceKind.__init__(self)
242 class Parameter(object):
243 def __init__(self, name=None, kind=None, ordinal=None, default=None):
245 self.ordinal = ordinal
247 self.default = default
250 class Method(object):
251 def __init__(self, interface, name, ordinal=None):
252 self.interface = interface
254 self.ordinal = ordinal
256 self.response_parameters = None
258 def AddParameter(self, name, kind, ordinal=None, default=None):
259 parameter = Parameter(name, kind, ordinal, default)
260 self.parameters.append(parameter)
263 def AddResponseParameter(self, name, kind, ordinal=None, default=None):
264 if self.response_parameters == None:
265 self.response_parameters = []
266 parameter = Parameter(name, kind, ordinal, default)
267 self.response_parameters.append(parameter)
271 class Interface(ReferenceKind):
272 ReferenceKind.AddSharedProperty('module')
273 ReferenceKind.AddSharedProperty('name')
274 ReferenceKind.AddSharedProperty('imported_from')
275 ReferenceKind.AddSharedProperty('client')
276 ReferenceKind.AddSharedProperty('methods')
278 def __init__(self, name=None, client=None, module=None):
283 ReferenceKind.__init__(self, spec)
286 self.imported_from = None
290 def AddMethod(self, name, ordinal=None):
291 method = Method(self, name, ordinal=ordinal)
292 self.methods.append(method)
296 class EnumField(object):
297 def __init__(self, name=None, value=None):
303 def __init__(self, name=None, module=None):
306 self.imported_from = None
311 Kind.__init__(self, spec)
315 class Module(object):
316 def __init__(self, name=None, namespace=None):
319 self.namespace = namespace
323 def AddInterface(self, name):
324 self.interfaces.append(Interface(name, module=self))
327 def AddStruct(self, name):
328 struct=Struct(name, module=self)
329 self.structs.append(struct)
333 def IsBoolKind(kind):
334 return kind.spec == BOOL.spec
337 def IsFloatKind(kind):
338 return kind.spec == FLOAT.spec
341 def IsStringKind(kind):
342 return kind.spec == STRING.spec or kind.spec == NULLABLE_STRING.spec
345 def IsHandleKind(kind):
346 return kind.spec == HANDLE.spec or kind.spec == NULLABLE_HANDLE.spec
349 def IsDataPipeConsumerKind(kind):
350 return kind.spec == DCPIPE.spec or kind.spec == NULLABLE_DCPIPE.spec
353 def IsDataPipeProducerKind(kind):
354 return kind.spec == DPPIPE.spec or kind.spec == NULLABLE_DPPIPE.spec
357 def IsMessagePipeKind(kind):
358 return kind.spec == MSGPIPE.spec or kind.spec == NULLABLE_MSGPIPE.spec
361 def IsSharedBufferKind(kind):
362 return (kind.spec == SHAREDBUFFER.spec or
363 kind.spec == NULLABLE_SHAREDBUFFER.spec)
366 def IsStructKind(kind):
367 return isinstance(kind, Struct)
370 def IsArrayKind(kind):
371 return isinstance(kind, Array)
374 def IsFixedArrayKind(kind):
375 return isinstance(kind, FixedArray)
378 def IsInterfaceKind(kind):
379 return isinstance(kind, Interface)
382 def IsInterfaceRequestKind(kind):
383 return isinstance(kind, InterfaceRequest)
386 def IsEnumKind(kind):
387 return isinstance(kind, Enum)
390 def IsReferenceKind(kind):
391 return isinstance(kind, ReferenceKind)
394 def IsNullableKind(kind):
395 return IsReferenceKind(kind) and kind.is_nullable
398 def IsAnyArrayKind(kind):
399 return IsArrayKind(kind) or IsFixedArrayKind(kind)
402 def IsObjectKind(kind):
403 return IsStructKind(kind) or IsAnyArrayKind(kind) or IsStringKind(kind)
406 def IsNonInterfaceHandleKind(kind):
407 return (IsHandleKind(kind) or
408 IsDataPipeConsumerKind(kind) or
409 IsDataPipeProducerKind(kind) or
410 IsMessagePipeKind(kind) or
411 IsSharedBufferKind(kind))
414 def IsAnyHandleKind(kind):
415 return (IsNonInterfaceHandleKind(kind) or
416 IsInterfaceKind(kind) or
417 IsInterfaceRequestKind(kind))
420 def IsMoveOnlyKind(kind):
421 return IsObjectKind(kind) or IsAnyHandleKind(kind)
424 def HasCallbacks(interface):
425 for method in interface.methods:
426 if method.response_parameters != None: