Home | History | Annotate | Download | only in generators
      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 import mojom
      6 
      7 # mojom_data provides a mechanism to turn mojom Modules to dictionaries and
      8 # back again. This can be used to persist a mojom Module created progromatically
      9 # or to read a dictionary from code or a file.
     10 # Example:
     11 # test_dict = {
     12 #   'name': 'test',
     13 #   'namespace': 'testspace',
     14 #   'structs': [{
     15 #     'name': 'teststruct',
     16 #     'fields': [
     17 #       {'name': 'testfield1', 'kind': 'i32'},
     18 #       {'name': 'testfield2', 'kind': 'a:i32', 'ordinal': 42}]}],
     19 #   'interfaces': [{
     20 #     'name': 'Server',
     21 #     'methods': [{
     22 #       'name': 'Foo',
     23 #       'parameters': [{
     24 #         'name': 'foo', 'kind': 'i32'},
     25 #         {'name': 'bar', 'kind': 'a:x:teststruct'}],
     26 #     'ordinal': 42}]}]
     27 # }
     28 # test_module = mojom_data.ModuleFromData(test_dict)
     29 
     30 
     31 # Used to create a subclass of str that supports sorting by index, to make
     32 # pretty printing maintain the order.
     33 def istr(index, string):
     34   class IndexedString(str):
     35     def __lt__(self, other):
     36       return self.__index__ < other.__index__
     37 
     38   istr = IndexedString(string)
     39   istr.__index__ = index
     40   return istr
     41 
     42 def KindToData(kind):
     43   return kind.spec
     44 
     45 def KindFromData(kinds, data):
     46   if kinds.has_key(data):
     47     return kinds[data]
     48   if data.startswith('a:'):
     49     kind = mojom.Array()
     50     kind.kind = KindFromData(kinds, data[2:])
     51   else:
     52     kind = mojom.Kind()
     53   kind.spec = data
     54   kinds[data] = kind
     55   return kind
     56 
     57 def StructToData(struct):
     58   return {
     59     istr(0, 'name'): struct.name,
     60     istr(1, 'fields'): map(FieldToData, struct.fields)
     61   }
     62 
     63 def StructFromData(kinds, data):
     64   struct = mojom.Struct()
     65   struct.name = data['name']
     66   struct.spec = 'x:' + struct.name
     67   kinds[struct.spec] = struct
     68   struct.fields = map(lambda field: FieldFromData(kinds, field), data['fields'])
     69   return struct
     70 
     71 def FieldToData(field):
     72   data = {
     73     istr(0, 'name'): field.name,
     74     istr(1, 'kind'): KindToData(field.kind)
     75   }
     76   if field.ordinal != None:
     77     data[istr(2, 'ordinal')] = field.ordinal
     78   if field.default != None:
     79     data[istr(3, 'default')] = field.default
     80   return data
     81 
     82 def FieldFromData(kinds, data):
     83   field = mojom.Field()
     84   field.name = data['name']
     85   field.kind = KindFromData(kinds, data['kind'])
     86   field.ordinal = data.get('ordinal')
     87   field.default = data.get('default')
     88   return field
     89 
     90 def ParameterToData(parameter):
     91   data = {
     92     istr(0, 'name'): parameter.name,
     93     istr(1, 'kind'): parameter.kind.spec
     94   }
     95   if parameter.ordinal != None:
     96     data[istr(2, 'ordinal')] = parameter.ordinal
     97   if parameter.default != None:
     98     data[istr(3, 'default')] = parameter.default
     99   return data
    100 
    101 def ParameterFromData(kinds, data):
    102   parameter = mojom.Parameter()
    103   parameter.name = data['name']
    104   parameter.kind = KindFromData(kinds, data['kind'])
    105   parameter.ordinal = data.get('ordinal')
    106   parameter.default = data.get('default')
    107   return parameter
    108 
    109 def MethodToData(method):
    110   data = {
    111     istr(0, 'name'):       method.name,
    112     istr(1, 'parameters'): map(ParameterToData, method.parameters)
    113   }
    114   if method.ordinal != None:
    115     data[istr(2, 'ordinal')] = method.ordinal
    116   return data
    117 
    118 def MethodFromData(kinds, data):
    119   method = mojom.Method()
    120   method.name = data['name']
    121   method.ordinal = data.get('ordinal')
    122   method.default = data.get('default')
    123   method.parameters = map(
    124     lambda parameter: ParameterFromData(kinds, parameter), data['parameters'])
    125   return method
    126 
    127 def InterfaceToData(interface):
    128   return {
    129     istr(0, 'name'):    interface.name,
    130     istr(1, 'peer'):    interface.peer,
    131     istr(2, 'methods'): map(MethodToData, interface.methods)
    132   }
    133 
    134 def InterfaceFromData(kinds, data):
    135   interface = mojom.Interface()
    136   interface.name = data['name']
    137   interface.peer = data['peer']
    138   interface.methods = map(
    139     lambda method: MethodFromData(kinds, method), data['methods'])
    140   return interface
    141 
    142 def EnumFieldFromData(kinds, data):
    143   field = mojom.EnumField()
    144   field.name = data['name']
    145   field.value = data['value']
    146   return field
    147 
    148 def EnumFromData(kinds, data):
    149   enum = mojom.Enum()
    150   enum.name = data['name']
    151   enum.fields = map(
    152     lambda field: EnumFieldFromData(kinds, field), data['fields'])
    153   return enum
    154 
    155 def ModuleToData(module):
    156   return {
    157     istr(0, 'name'):       module.name,
    158     istr(1, 'namespace'):  module.namespace,
    159     istr(2, 'structs'):    map(StructToData, module.structs),
    160     istr(3, 'interfaces'): map(InterfaceToData, module.interfaces)
    161   }
    162 
    163 def ModuleFromData(data):
    164   kinds = {}
    165   for kind in mojom.PRIMITIVES:
    166     kinds[kind.spec] = kind
    167 
    168   module = mojom.Module()
    169   module.name = data['name']
    170   module.namespace = data['namespace']
    171   module.structs = map(
    172     lambda struct: StructFromData(kinds, struct), data['structs'])
    173   module.interfaces = map(
    174     lambda interface: InterfaceFromData(kinds, interface), data['interfaces'])
    175   module.enums = map(
    176     lambda enum: EnumFromData(kinds, enum), data['enums'])
    177   return module
    178 
    179 def OrderedModuleFromData(data):
    180   module = ModuleFromData(data)
    181   next_interface_ordinal = 0
    182   for interface in module.interfaces:
    183     next_ordinal = 0
    184     for method in interface.methods:
    185       if method.ordinal is None:
    186         method.ordinal = next_ordinal
    187       next_ordinal = method.ordinal + 1
    188   return module
    189