Upstream version 7.36.149.0
[platform/framework/web/crosswalk.git] / src / mojo / public / tools / bindings / pylib / mojom / parse / translate.py
1 # Copyright 2014 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 """Translates parse tree to Mojom IR."""
6
7
8 import ast
9
10
11 def _MapTree(func, tree, name):
12   if not tree:
13     return []
14   return [func(subtree) for subtree in tree if subtree[0] == name]
15
16 def _MapKind(kind):
17   map_to_kind = { 'bool': 'b',
18                   'int8': 'i8',
19                   'int16': 'i16',
20                   'int32': 'i32',
21                   'int64': 'i64',
22                   'uint8': 'u8',
23                   'uint16': 'u16',
24                   'uint32': 'u32',
25                   'uint64': 'u64',
26                   'float': 'f',
27                   'double': 'd',
28                   'string': 's',
29                   'handle': 'h',
30                   'handle<data_pipe_consumer>': 'h:d:c',
31                   'handle<data_pipe_producer>': 'h:d:p',
32                   'handle<message_pipe>': 'h:m',
33                   'handle<shared_buffer>': 'h:s'}
34   if kind.endswith('[]'):
35     return 'a:' + _MapKind(kind[0:len(kind)-2])
36   if kind in map_to_kind:
37     return map_to_kind[kind]
38   return 'x:' + kind
39
40 def _MapAttributes(attributes):
41   if not attributes:
42     return {}
43   return dict([(attribute[1], attribute[2])
44                for attribute in attributes if attribute[0] == 'ATTRIBUTE'])
45
46 def _GetAttribute(attributes, name):
47   out = None
48   if attributes:
49     for attribute in attributes:
50       if attribute[0] == 'ATTRIBUTE' and attribute[1] == name:
51         out = attribute[2]
52   return out
53
54 def _MapField(tree):
55   assert type(tree[3]) is ast.Ordinal
56   return {'name': tree[2],
57           'kind': _MapKind(tree[1]),
58           'ordinal': tree[3].value,
59           'default': tree[4]}
60
61 def _MapParameter(tree):
62   assert type(tree[3]) is ast.Ordinal
63   return {'name': tree[2],
64           'kind': _MapKind(tree[1]),
65           'ordinal': tree[3].value}
66
67 def _MapMethod(tree):
68   assert type(tree[3]) is ast.Ordinal
69   method = {'name': tree[1],
70             'parameters': _MapTree(_MapParameter, tree[2], 'PARAM'),
71             'ordinal': tree[3].value}
72   if tree[4] != None:
73     method['response_parameters'] = _MapTree(_MapParameter, tree[4], 'PARAM')
74   return method
75
76 def _MapEnumField(tree):
77   return {'name': tree[1],
78           'value': tree[2]}
79
80 def _MapStruct(tree):
81   struct = {}
82   struct['name'] = tree[1]
83   struct['attributes'] = _MapAttributes(tree[2])
84   struct['fields'] = _MapTree(_MapField, tree[3], 'FIELD')
85   struct['enums'] = _MapTree(_MapEnum, tree[3], 'ENUM')
86   return struct
87
88 def _MapInterface(tree):
89   interface = {}
90   interface['name'] = tree[1]
91   interface['client'] = _GetAttribute(tree[2], 'Client')
92   interface['methods'] = _MapTree(_MapMethod, tree[3], 'METHOD')
93   interface['enums'] = _MapTree(_MapEnum, tree[3], 'ENUM')
94   return interface
95
96 def _MapEnum(tree):
97   enum = {}
98   enum['name'] = tree[1]
99   enum['fields'] = _MapTree(_MapEnumField, tree[2], 'ENUM_FIELD')
100   return enum
101
102 def _MapModule(tree, name):
103   mojom = {}
104   mojom['name'] = name
105   mojom['namespace'] = tree[1]
106   mojom['attributes'] = _MapAttributes(tree[2])
107   mojom['structs'] = _MapTree(_MapStruct, tree[3], 'STRUCT')
108   mojom['interfaces'] = _MapTree(_MapInterface, tree[3], 'INTERFACE')
109   mojom['enums'] = _MapTree(_MapEnum, tree[3], 'ENUM')
110   return mojom
111
112 def _MapImport(tree):
113   import_item = {}
114   import_item['filename'] = tree[1]
115   return import_item
116
117
118 class _MojomBuilder(object):
119   def __init__(self):
120     self.mojom = {}
121
122   def Build(self, tree, name):
123     modules = [_MapModule(item, name) for item in tree if item[0] == 'MODULE']
124     if len(modules) != 1:
125       raise Exception('A mojom file must contain exactly 1 module.')
126     self.mojom = modules[0]
127     self.mojom['imports'] = _MapTree(_MapImport, tree, 'IMPORT')
128     return self.mojom
129
130
131 def Translate(tree, name):
132   return _MojomBuilder().Build(tree, name)