| OLD | NEW | 
|---|
|  | (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, parent_kind, name): |  | 
| 135     self.module = module |  | 
| 136     self.namespace = module.namespace |  | 
| 137     self.parent_kind = parent_kind |  | 
| 138     self.name = name |  | 
| 139     self.imported_from = None |  | 
| 140 |  | 
| 141   def GetSpec(self): |  | 
| 142     return (self.namespace + '.' + |  | 
| 143         (self.parent_kind and (self.parent_kind.name + '.') or "") + |  | 
| 144         self.name) |  | 
| 145 |  | 
| 146 |  | 
| 147 class BuiltinValue(object): |  | 
| 148   def __init__(self, value): |  | 
| 149     self.value = value |  | 
| 150 |  | 
| 151 |  | 
| 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 |  | 
| 156 |  | 
| 157 |  | 
| 158 class EnumValue(NamedValue): |  | 
| 159   def __init__(self, module, enum, field): |  | 
| 160     NamedValue.__init__(self, module, enum.parent_kind, field.name) |  | 
| 161     self.enum = enum |  | 
| 162 |  | 
| 163   def GetSpec(self): |  | 
| 164     return (self.namespace + '.' + |  | 
| 165         (self.parent_kind and (self.parent_kind.name + '.') or "") + |  | 
| 166         self.enum.name + '.' + self.name) |  | 
| 167 |  | 
| 168 |  | 
| 169 class Constant(object): |  | 
| 170   def __init__(self, name=None, kind=None, value=None): |  | 
| 171     self.name = name |  | 
| 172     self.kind = kind |  | 
| 173     self.value = value |  | 
| 174 |  | 
| 175 |  | 
| 176 class Field(object): |  | 
| 177   def __init__(self, name=None, kind=None, ordinal=None, default=None): |  | 
| 178     self.name = name |  | 
| 179     self.kind = kind |  | 
| 180     self.ordinal = ordinal |  | 
| 181     self.default = default |  | 
| 182 |  | 
| 183 |  | 
| 184 class Struct(ReferenceKind): |  | 
| 185   ReferenceKind.AddSharedProperty('name') |  | 
| 186   ReferenceKind.AddSharedProperty('module') |  | 
| 187   ReferenceKind.AddSharedProperty('imported_from') |  | 
| 188   ReferenceKind.AddSharedProperty('fields') |  | 
| 189 |  | 
| 190   def __init__(self, name=None, module=None): |  | 
| 191     if name is not None: |  | 
| 192       spec = 'x:' + name |  | 
| 193     else: |  | 
| 194       spec = None |  | 
| 195     ReferenceKind.__init__(self, spec) |  | 
| 196     self.name = name |  | 
| 197     self.module = module |  | 
| 198     self.imported_from = None |  | 
| 199     self.fields = [] |  | 
| 200 |  | 
| 201   def AddField(self, name, kind, ordinal=None, default=None): |  | 
| 202     field = Field(name, kind, ordinal, default) |  | 
| 203     self.fields.append(field) |  | 
| 204     return field |  | 
| 205 |  | 
| 206 |  | 
| 207 class Union(ReferenceKind): |  | 
| 208   ReferenceKind.AddSharedProperty('name') |  | 
| 209   ReferenceKind.AddSharedProperty('module') |  | 
| 210   ReferenceKind.AddSharedProperty('imported_from') |  | 
| 211   ReferenceKind.AddSharedProperty('fields') |  | 
| 212 |  | 
| 213   def __init__(self, name=None, module=None): |  | 
| 214     if name is not None: |  | 
| 215       spec = 'x:' + name |  | 
| 216     else: |  | 
| 217       spec = None |  | 
| 218     ReferenceKind.__init__(self, spec) |  | 
| 219     self.name = name |  | 
| 220     self.module = module |  | 
| 221     self.imported_from = None |  | 
| 222     self.fields = [] |  | 
| 223 |  | 
| 224   def AddField(self, name, kind, ordinal=None): |  | 
| 225     field = Field(name, kind, ordinal, default=None) |  | 
| 226     self.fields.append(field) |  | 
| 227     return field |  | 
| 228 |  | 
| 229 |  | 
| 230 class Array(ReferenceKind): |  | 
| 231   ReferenceKind.AddSharedProperty('kind') |  | 
| 232   ReferenceKind.AddSharedProperty('length') |  | 
| 233 |  | 
| 234   def __init__(self, kind=None, length=None): |  | 
| 235     if kind is not None: |  | 
| 236       if length is not None: |  | 
| 237         spec = 'a%d:%s' % (length, kind.spec) |  | 
| 238       else: |  | 
| 239         spec = 'a:%s' % kind.spec |  | 
| 240 |  | 
| 241       ReferenceKind.__init__(self, spec) |  | 
| 242     else: |  | 
| 243       ReferenceKind.__init__(self) |  | 
| 244     self.kind = kind |  | 
| 245     self.length = length |  | 
| 246 |  | 
| 247 |  | 
| 248 class Map(ReferenceKind): |  | 
| 249   ReferenceKind.AddSharedProperty('key_kind') |  | 
| 250   ReferenceKind.AddSharedProperty('value_kind') |  | 
| 251 |  | 
| 252   def __init__(self, key_kind=None, value_kind=None): |  | 
| 253     if (key_kind is not None and value_kind is not None): |  | 
| 254       ReferenceKind.__init__(self, |  | 
| 255                              'm[' + key_kind.spec + '][' + value_kind.spec + |  | 
| 256                              ']') |  | 
| 257       if IsNullableKind(key_kind): |  | 
| 258         raise Exception("Nullable kinds can not be keys in maps.") |  | 
| 259       if IsStructKind(key_kind): |  | 
| 260         # TODO(erg): It would sometimes be nice if we could key on struct |  | 
| 261         # values. However, what happens if the struct has a handle in it? Or |  | 
| 262         # non-copyable data like an array? |  | 
| 263         raise Exception("Structs can not be keys in maps.") |  | 
| 264       if IsAnyHandleKind(key_kind): |  | 
| 265         raise Exception("Handles can not be keys in maps.") |  | 
| 266       if IsArrayKind(key_kind): |  | 
| 267         raise Exception("Arrays can not be keys in maps.") |  | 
| 268     else: |  | 
| 269       ReferenceKind.__init__(self) |  | 
| 270 |  | 
| 271     self.key_kind = key_kind |  | 
| 272     self.value_kind = value_kind |  | 
| 273 |  | 
| 274 |  | 
| 275 class InterfaceRequest(ReferenceKind): |  | 
| 276   ReferenceKind.AddSharedProperty('kind') |  | 
| 277 |  | 
| 278   def __init__(self, kind=None): |  | 
| 279     if kind is not None: |  | 
| 280       if not isinstance(kind, Interface): |  | 
| 281         raise Exception( |  | 
| 282             "Interface request requires %r to be an interface." % kind.spec) |  | 
| 283       ReferenceKind.__init__(self, 'r:' + kind.spec) |  | 
| 284     else: |  | 
| 285       ReferenceKind.__init__(self) |  | 
| 286     self.kind = kind |  | 
| 287 |  | 
| 288 |  | 
| 289 class Parameter(object): |  | 
| 290   def __init__(self, name=None, kind=None, ordinal=None, default=None): |  | 
| 291     self.name = name |  | 
| 292     self.ordinal = ordinal |  | 
| 293     self.kind = kind |  | 
| 294     self.default = default |  | 
| 295 |  | 
| 296 |  | 
| 297 class Method(object): |  | 
| 298   def __init__(self, interface, name, ordinal=None): |  | 
| 299     self.interface = interface |  | 
| 300     self.name = name |  | 
| 301     self.ordinal = ordinal |  | 
| 302     self.parameters = [] |  | 
| 303     self.response_parameters = None |  | 
| 304 |  | 
| 305   def AddParameter(self, name, kind, ordinal=None, default=None): |  | 
| 306     parameter = Parameter(name, kind, ordinal, default) |  | 
| 307     self.parameters.append(parameter) |  | 
| 308     return parameter |  | 
| 309 |  | 
| 310   def AddResponseParameter(self, name, kind, ordinal=None, default=None): |  | 
| 311     if self.response_parameters == None: |  | 
| 312       self.response_parameters = [] |  | 
| 313     parameter = Parameter(name, kind, ordinal, default) |  | 
| 314     self.response_parameters.append(parameter) |  | 
| 315     return parameter |  | 
| 316 |  | 
| 317 |  | 
| 318 class Interface(ReferenceKind): |  | 
| 319   ReferenceKind.AddSharedProperty('module') |  | 
| 320   ReferenceKind.AddSharedProperty('name') |  | 
| 321   ReferenceKind.AddSharedProperty('imported_from') |  | 
| 322   ReferenceKind.AddSharedProperty('client') |  | 
| 323   ReferenceKind.AddSharedProperty('methods') |  | 
| 324 |  | 
| 325   def __init__(self, name=None, client=None, module=None): |  | 
| 326     if name is not None: |  | 
| 327       spec = 'x:' + name |  | 
| 328     else: |  | 
| 329       spec = None |  | 
| 330     ReferenceKind.__init__(self, spec) |  | 
| 331     self.module = module |  | 
| 332     self.name = name |  | 
| 333     self.imported_from = None |  | 
| 334     self.client = client |  | 
| 335     self.methods = [] |  | 
| 336 |  | 
| 337   def AddMethod(self, name, ordinal=None): |  | 
| 338     method = Method(self, name, ordinal=ordinal) |  | 
| 339     self.methods.append(method) |  | 
| 340     return method |  | 
| 341 |  | 
| 342 |  | 
| 343 class EnumField(object): |  | 
| 344   def __init__(self, name=None, value=None): |  | 
| 345     self.name = name |  | 
| 346     self.value = value |  | 
| 347 |  | 
| 348 |  | 
| 349 class Enum(Kind): |  | 
| 350   def __init__(self, name=None, module=None): |  | 
| 351     self.module = module |  | 
| 352     self.name = name |  | 
| 353     self.imported_from = None |  | 
| 354     if name is not None: |  | 
| 355       spec = 'x:' + name |  | 
| 356     else: |  | 
| 357       spec = None |  | 
| 358     Kind.__init__(self, spec) |  | 
| 359     self.fields = [] |  | 
| 360 |  | 
| 361 |  | 
| 362 class Module(object): |  | 
| 363   def __init__(self, name=None, namespace=None): |  | 
| 364     self.name = name |  | 
| 365     self.path = name |  | 
| 366     self.namespace = namespace |  | 
| 367     self.structs = [] |  | 
| 368     self.unions = [] |  | 
| 369     self.interfaces = [] |  | 
| 370     self.kinds = {} |  | 
| 371 |  | 
| 372   def AddInterface(self, name): |  | 
| 373     interface = Interface(name, module=self) |  | 
| 374     self.interfaces.append(interface) |  | 
| 375     return interface |  | 
| 376 |  | 
| 377   def AddStruct(self, name): |  | 
| 378     struct = Struct(name, module=self) |  | 
| 379     self.structs.append(struct) |  | 
| 380     return struct |  | 
| 381 |  | 
| 382   def AddUnion(self, name): |  | 
| 383     union = Union(name, module=self) |  | 
| 384     self.unions.append(union) |  | 
| 385     return union |  | 
| 386 |  | 
| 387 |  | 
| 388 def IsBoolKind(kind): |  | 
| 389   return kind.spec == BOOL.spec |  | 
| 390 |  | 
| 391 |  | 
| 392 def IsFloatKind(kind): |  | 
| 393   return kind.spec == FLOAT.spec |  | 
| 394 |  | 
| 395 |  | 
| 396 def IsStringKind(kind): |  | 
| 397   return kind.spec == STRING.spec or kind.spec == NULLABLE_STRING.spec |  | 
| 398 |  | 
| 399 |  | 
| 400 def IsHandleKind(kind): |  | 
| 401   return kind.spec == HANDLE.spec or kind.spec == NULLABLE_HANDLE.spec |  | 
| 402 |  | 
| 403 |  | 
| 404 def IsDataPipeConsumerKind(kind): |  | 
| 405   return kind.spec == DCPIPE.spec or kind.spec == NULLABLE_DCPIPE.spec |  | 
| 406 |  | 
| 407 |  | 
| 408 def IsDataPipeProducerKind(kind): |  | 
| 409   return kind.spec == DPPIPE.spec or kind.spec == NULLABLE_DPPIPE.spec |  | 
| 410 |  | 
| 411 |  | 
| 412 def IsMessagePipeKind(kind): |  | 
| 413   return kind.spec == MSGPIPE.spec or kind.spec == NULLABLE_MSGPIPE.spec |  | 
| 414 |  | 
| 415 |  | 
| 416 def IsSharedBufferKind(kind): |  | 
| 417   return (kind.spec == SHAREDBUFFER.spec or |  | 
| 418           kind.spec == NULLABLE_SHAREDBUFFER.spec) |  | 
| 419 |  | 
| 420 |  | 
| 421 def IsStructKind(kind): |  | 
| 422   return isinstance(kind, Struct) |  | 
| 423 |  | 
| 424 |  | 
| 425 def IsArrayKind(kind): |  | 
| 426   return isinstance(kind, Array) |  | 
| 427 |  | 
| 428 |  | 
| 429 def IsInterfaceKind(kind): |  | 
| 430   return isinstance(kind, Interface) |  | 
| 431 |  | 
| 432 |  | 
| 433 def IsInterfaceRequestKind(kind): |  | 
| 434   return isinstance(kind, InterfaceRequest) |  | 
| 435 |  | 
| 436 |  | 
| 437 def IsEnumKind(kind): |  | 
| 438   return isinstance(kind, Enum) |  | 
| 439 |  | 
| 440 |  | 
| 441 def IsReferenceKind(kind): |  | 
| 442   return isinstance(kind, ReferenceKind) |  | 
| 443 |  | 
| 444 |  | 
| 445 def IsNullableKind(kind): |  | 
| 446   return IsReferenceKind(kind) and kind.is_nullable |  | 
| 447 |  | 
| 448 |  | 
| 449 def IsMapKind(kind): |  | 
| 450   return isinstance(kind, Map) |  | 
| 451 |  | 
| 452 |  | 
| 453 def IsObjectKind(kind): |  | 
| 454   return (IsStructKind(kind) or IsArrayKind(kind) or IsStringKind(kind) or |  | 
| 455           IsMapKind(kind)) |  | 
| 456 |  | 
| 457 |  | 
| 458 def IsNonInterfaceHandleKind(kind): |  | 
| 459   return (IsHandleKind(kind) or |  | 
| 460           IsDataPipeConsumerKind(kind) or |  | 
| 461           IsDataPipeProducerKind(kind) or |  | 
| 462           IsMessagePipeKind(kind) or |  | 
| 463           IsSharedBufferKind(kind)) |  | 
| 464 |  | 
| 465 |  | 
| 466 def IsAnyHandleKind(kind): |  | 
| 467   return (IsNonInterfaceHandleKind(kind) or |  | 
| 468           IsInterfaceKind(kind) or |  | 
| 469           IsInterfaceRequestKind(kind)) |  | 
| 470 |  | 
| 471 |  | 
| 472 def IsMoveOnlyKind(kind): |  | 
| 473   return IsObjectKind(kind) or IsAnyHandleKind(kind) |  | 
| 474 |  | 
| 475 |  | 
| 476 def IsCloneableKind(kind): |  | 
| 477   def ContainsHandles(kind, visited_kinds): |  | 
| 478     if kind in visited_kinds: |  | 
| 479       # No need to examine the kind again. |  | 
| 480       return False |  | 
| 481     visited_kinds.add(kind) |  | 
| 482     if IsAnyHandleKind(kind): |  | 
| 483       return True |  | 
| 484     if IsArrayKind(kind): |  | 
| 485       return ContainsHandles(kind.kind, visited_kinds) |  | 
| 486     if IsStructKind(kind): |  | 
| 487       for field in kind.fields: |  | 
| 488         if ContainsHandles(field.kind, visited_kinds): |  | 
| 489           return True |  | 
| 490     return False |  | 
| 491 |  | 
| 492   return not ContainsHandles(kind, set()) |  | 
| 493 |  | 
| 494 |  | 
| 495 def HasCallbacks(interface): |  | 
| 496   for method in interface.methods: |  | 
| 497     if method.response_parameters != None: |  | 
| 498       return True |  | 
| 499   return False |  | 
| 500 |  | 
| OLD | NEW | 
|---|