blob: aeb0ca6a5a51b8ce9e8f71cb6c68ca85711e4589 [file] [log] [blame]
# 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