| # Copyright 2013 The Chromium Authors. All rights reserved. |
| # Use of this source code is governed by a BSD-style license that can be |
| # found in the LICENSE file. |
| |
| import mojom |
| |
| # mojom_data provides a mechanism to turn mojom Modules to dictionaries and |
| # back again. This can be used to persist a mojom Module created progromatically |
| # or to read a dictionary from code or a file. |
| # Example: |
| # test_dict = { |
| # 'name': 'test', |
| # 'namespace': 'testspace', |
| # 'structs': [{ |
| # 'name': 'teststruct', |
| # 'fields': [ |
| # {'name': 'testfield1', 'kind': 'i32'}, |
| # {'name': 'testfield2', 'kind': 'a:i32', 'ordinal': 42}]}], |
| # 'interfaces': [{ |
| # 'name': 'Server', |
| # 'methods': [{ |
| # 'name': 'Foo', |
| # 'parameters': [{ |
| # 'name': 'foo', 'kind': 'i32'}, |
| # {'name': 'bar', 'kind': 'a:x:teststruct'}], |
| # 'ordinal': 42}]}] |
| # } |
| # test_module = mojom_data.ModuleFromData(test_dict) |
| |
| |
| # Used to create a subclass of str that supports sorting by index, to make |
| # pretty printing maintain the order. |
| def istr(index, string): |
| class IndexedString(str): |
| def __lt__(self, other): |
| return self.__index__ < other.__index__ |
| |
| istr = IndexedString(string) |
| istr.__index__ = index |
| return istr |
| |
| def KindToData(kind): |
| return kind.spec |
| |
| def KindFromData(kinds, data): |
| if kinds.has_key(data): |
| return kinds[data] |
| if data.startswith('a:'): |
| kind = mojom.Array() |
| kind.kind = KindFromData(kinds, data[2:]) |
| else: |
| kind = mojom.Kind() |
| kind.spec = data |
| kinds[data] = kind |
| return kind |
| |
| def StructToData(struct): |
| return { |
| istr(0, 'name'): struct.name, |
| istr(1, 'fields'): map(FieldToData, struct.fields) |
| } |
| |
| def StructFromData(kinds, data): |
| struct = mojom.Struct() |
| struct.name = data['name'] |
| struct.spec = 'x:' + struct.name |
| kinds[struct.spec] = struct |
| struct.fields = map(lambda field: FieldFromData(kinds, field), data['fields']) |
| return struct |
| |
| def FieldToData(field): |
| data = { |
| istr(0, 'name'): field.name, |
| istr(1, 'kind'): KindToData(field.kind) |
| } |
| if field.ordinal != None: |
| data[istr(2, 'ordinal')] = field.ordinal |
| if field.default != None: |
| data[istr(3, 'default')] = field.default |
| return data |
| |
| def FieldFromData(kinds, data): |
| field = mojom.Field() |
| field.name = data['name'] |
| field.kind = KindFromData(kinds, data['kind']) |
| field.ordinal = data.get('ordinal') |
| field.default = data.get('default') |
| return field |
| |
| def ParameterToData(parameter): |
| data = { |
| istr(0, 'name'): parameter.name, |
| istr(1, 'kind'): parameter.kind.spec |
| } |
| if parameter.ordinal != None: |
| data[istr(2, 'ordinal')] = parameter.ordinal |
| if parameter.default != None: |
| data[istr(3, 'default')] = parameter.default |
| return data |
| |
| def ParameterFromData(kinds, data): |
| parameter = mojom.Parameter() |
| parameter.name = data['name'] |
| parameter.kind = KindFromData(kinds, data['kind']) |
| parameter.ordinal = data.get('ordinal') |
| parameter.default = data.get('default') |
| return parameter |
| |
| def MethodToData(method): |
| data = { |
| istr(0, 'name'): method.name, |
| istr(1, 'parameters'): map(ParameterToData, method.parameters) |
| } |
| if method.ordinal != None: |
| data[istr(2, 'ordinal')] = method.ordinal |
| return data |
| |
| def MethodFromData(kinds, data): |
| method = mojom.Method() |
| method.name = data['name'] |
| method.ordinal = data.get('ordinal') |
| method.default = data.get('default') |
| method.parameters = map( |
| lambda parameter: ParameterFromData(kinds, parameter), data['parameters']) |
| return method |
| |
| def InterfaceToData(interface): |
| return { |
| istr(0, 'name'): interface.name, |
| istr(1, 'peer'): interface.peer, |
| istr(2, 'methods'): map(MethodToData, interface.methods) |
| } |
| |
| def InterfaceFromData(kinds, data): |
| interface = mojom.Interface() |
| interface.name = data['name'] |
| interface.peer = data['peer'] |
| interface.methods = map( |
| lambda method: MethodFromData(kinds, method), data['methods']) |
| return interface |
| |
| def EnumFieldFromData(kinds, data): |
| field = mojom.EnumField() |
| field.name = data['name'] |
| field.value = data['value'] |
| return field |
| |
| def EnumFromData(kinds, data): |
| enum = mojom.Enum() |
| enum.name = data['name'] |
| enum.fields = map( |
| lambda field: EnumFieldFromData(kinds, field), data['fields']) |
| return enum |
| |
| def ModuleToData(module): |
| return { |
| istr(0, 'name'): module.name, |
| istr(1, 'namespace'): module.namespace, |
| istr(2, 'structs'): map(StructToData, module.structs), |
| istr(3, 'interfaces'): map(InterfaceToData, module.interfaces) |
| } |
| |
| def ModuleFromData(data): |
| kinds = {} |
| for kind in mojom.PRIMITIVES: |
| kinds[kind.spec] = kind |
| |
| module = mojom.Module() |
| module.name = data['name'] |
| module.namespace = data['namespace'] |
| module.structs = map( |
| lambda struct: StructFromData(kinds, struct), data['structs']) |
| module.interfaces = map( |
| lambda interface: InterfaceFromData(kinds, interface), data['interfaces']) |
| module.enums = map( |
| lambda enum: EnumFromData(kinds, enum), data['enums']) |
| return module |
| |
| def OrderedModuleFromData(data): |
| module = ModuleFromData(data) |
| next_interface_ordinal = 0 |
| for interface in module.interfaces: |
| next_ordinal = 0 |
| for method in interface.methods: |
| if method.ordinal is None: |
| method.ordinal = next_ordinal |
| next_ordinal = method.ordinal + 1 |
| return module |