Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1557)

Side by Side Diff: mojo/public/bindings/pylib/generate/mojom_data.py

Issue 226263002: Mojo: Move mojo/public/bindings to mojo/public/tools/bindings. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: rebased Created 6 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
(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 import mojom
6 import copy
7
8 # mojom_data provides a mechanism to turn mojom Modules to dictionaries and
9 # back again. This can be used to persist a mojom Module created progromatically
10 # or to read a dictionary from code or a file.
11 # Example:
12 # test_dict = {
13 # 'name': 'test',
14 # 'namespace': 'testspace',
15 # 'structs': [{
16 # 'name': 'teststruct',
17 # 'fields': [
18 # {'name': 'testfield1', 'kind': 'i32'},
19 # {'name': 'testfield2', 'kind': 'a:i32', 'ordinal': 42}]}],
20 # 'interfaces': [{
21 # 'name': 'Server',
22 # 'methods': [{
23 # 'name': 'Foo',
24 # 'parameters': [{
25 # 'name': 'foo', 'kind': 'i32'},
26 # {'name': 'bar', 'kind': 'a:x:teststruct'}],
27 # 'ordinal': 42}]}]
28 # }
29 # test_module = mojom_data.ModuleFromData(test_dict)
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 LookupKind(kinds, spec, scope):
43 """Tries to find which Kind a spec refers to, given the scope in which its
44 referenced. Starts checking from the narrowest scope to most general. For
45 example, given a struct field like
46 Foo.Bar x;
47 Foo.Bar could refer to the type 'Bar' in the 'Foo' namespace, or an inner
48 type 'Bar' in the struct 'Foo' in the current namespace.
49
50 |scope| is a tuple that looks like (namespace, struct/interface), referring
51 to the location where the type is referenced."""
52 if spec.startswith('x:'):
53 name = spec[2:]
54 for i in xrange(len(scope), -1, -1):
55 test_spec = 'x:'
56 if i > 0:
57 test_spec += '.'.join(scope[:i]) + '.'
58 test_spec += name
59 kind = kinds.get(test_spec)
60 if kind:
61 return kind
62
63 return kinds.get(spec)
64
65 def LookupConstant(constants, name, scope):
66 """Like LookupKind, but for constants."""
67 for i in xrange(len(scope), -1, -1):
68 if i > 0:
69 test_spec = '.'.join(scope[:i]) + '.'
70 test_spec += name
71 constant = constants.get(test_spec)
72 if constant:
73 return constant
74
75 return constants.get(name)
76
77 def KindToData(kind):
78 return kind.spec
79
80 def KindFromData(kinds, data, scope):
81 kind = LookupKind(kinds, data, scope)
82 if kind:
83 return kind
84 if data.startswith('a:'):
85 kind = mojom.Array()
86 kind.kind = KindFromData(kinds, data[2:], scope)
87 else:
88 kind = mojom.Kind()
89 kind.spec = data
90 kinds[data] = kind
91 return kind
92
93 def KindFromImport(original_kind, imported_from):
94 """Used with 'import module' - clones the kind imported from the
95 given module's namespace. Only used with Structs and Enums."""
96 kind = copy.deepcopy(original_kind)
97 kind.imported_from = imported_from
98 return kind
99
100 def ImportFromData(module, data):
101 import_module = data['module']
102
103 import_item = {}
104 import_item['module_name'] = import_module.name
105 import_item['namespace'] = import_module.namespace
106 import_item['module'] = import_module
107
108 # Copy the struct kinds from our imports into the current module.
109 for kind in import_module.kinds.itervalues():
110 if (isinstance(kind, (mojom.Struct, mojom.Enum)) and
111 kind.imported_from is None):
112 kind = KindFromImport(kind, import_item)
113 module.kinds[kind.spec] = kind
114 # Ditto for constants.
115 for constant in import_module.constants.itervalues():
116 if constant.imported_from is None:
117 constant = copy.deepcopy(constant)
118 constant.imported_from = import_item
119 module.constants[constant.GetSpec()] = constant
120
121 return import_item
122
123 def StructToData(struct):
124 return {
125 istr(0, 'name'): struct.name,
126 istr(1, 'fields'): map(FieldToData, struct.fields)
127 }
128
129 def StructFromData(module, data):
130 struct = mojom.Struct()
131 struct.name = data['name']
132 struct.spec = 'x:' + module.namespace + '.' + struct.name
133 module.kinds[struct.spec] = struct
134 struct.enums = map(lambda enum:
135 EnumFromData(module, enum, struct), data['enums'])
136 struct.fields = map(lambda field:
137 FieldFromData(module, field, struct), data['fields'])
138 return struct
139
140 def FieldToData(field):
141 data = {
142 istr(0, 'name'): field.name,
143 istr(1, 'kind'): KindToData(field.kind)
144 }
145 if field.ordinal != None:
146 data[istr(2, 'ordinal')] = field.ordinal
147 if field.default != None:
148 data[istr(3, 'default')] = field.default
149 return data
150
151 def FixupExpression(module, value, scope):
152 if isinstance(value, (tuple, list)):
153 for i in xrange(len(value)):
154 if isinstance(value, tuple):
155 FixupExpression(module, value[i], scope)
156 else:
157 value[i] = FixupExpression(module, value[i], scope)
158 elif value:
159 constant = LookupConstant(module.constants, value, scope)
160 if constant:
161 return constant
162 return value
163
164 def FieldFromData(module, data, struct):
165 field = mojom.Field()
166 field.name = data['name']
167 field.kind = KindFromData(
168 module.kinds, data['kind'], (module.namespace, struct.name))
169 field.ordinal = data.get('ordinal')
170 field.default = FixupExpression(
171 module, data.get('default'), (module.namespace, struct.name))
172 return field
173
174 def ParameterToData(parameter):
175 data = {
176 istr(0, 'name'): parameter.name,
177 istr(1, 'kind'): parameter.kind.spec
178 }
179 if parameter.ordinal != None:
180 data[istr(2, 'ordinal')] = parameter.ordinal
181 if parameter.default != None:
182 data[istr(3, 'default')] = parameter.default
183 return data
184
185 def ParameterFromData(module, data, interface):
186 parameter = mojom.Parameter()
187 parameter.name = data['name']
188 parameter.kind = KindFromData(
189 module.kinds, data['kind'], (module.namespace, interface.name))
190 parameter.ordinal = data.get('ordinal')
191 parameter.default = data.get('default')
192 return parameter
193
194 def MethodToData(method):
195 data = {
196 istr(0, 'name'): method.name,
197 istr(1, 'parameters'): map(ParameterToData, method.parameters)
198 }
199 if method.ordinal != None:
200 data[istr(2, 'ordinal')] = method.ordinal
201 if method.response_parameters != None:
202 data[istr(3, 'response_parameters')] = map(
203 ParameterToData, method.response_parameters)
204 return data
205
206 def MethodFromData(module, data, interface):
207 method = mojom.Method()
208 method.name = data['name']
209 method.ordinal = data.get('ordinal')
210 method.default = data.get('default')
211 method.parameters = map(lambda parameter:
212 ParameterFromData(module, parameter, interface), data['parameters'])
213 if data.has_key('response_parameters'):
214 method.response_parameters = map(
215 lambda parameter: ParameterFromData(module, parameter, interface),
216 data['response_parameters'])
217 return method
218
219 def InterfaceToData(interface):
220 return {
221 istr(0, 'name'): interface.name,
222 istr(1, 'peer'): interface.peer,
223 istr(2, 'methods'): map(MethodToData, interface.methods)
224 }
225
226 def InterfaceFromData(module, data):
227 interface = mojom.Interface()
228 interface.name = data['name']
229 interface.spec = 'x:' + module.namespace + '.' + interface.name
230 interface.peer = data['peer'] if data.has_key('peer') else None
231 module.kinds[interface.spec] = interface
232 interface.enums = map(lambda enum:
233 EnumFromData(module, enum, interface), data['enums'])
234 interface.methods = map(lambda method:
235 MethodFromData(module, method, interface), data['methods'])
236 return interface
237
238 def EnumFieldFromData(module, enum, data, parent_kind):
239 field = mojom.EnumField()
240 field.name = data['name']
241 if parent_kind:
242 field.value = FixupExpression(
243 module, data['value'], (module.namespace, parent_kind.name))
244 else:
245 field.value = FixupExpression(
246 module, data['value'], (module.namespace, ))
247 constant = mojom.Constant(module, enum, field)
248 module.constants[constant.GetSpec()] = constant
249 return field
250
251 def EnumFromData(module, data, parent_kind):
252 enum = mojom.Enum()
253 enum.name = data['name']
254 name = enum.name
255 if parent_kind:
256 name = parent_kind.name + '.' + name
257 enum.spec = 'x:%s.%s' % (module.namespace, name)
258 enum.parent_kind = parent_kind
259
260 enum.fields = map(
261 lambda field: EnumFieldFromData(module, enum, field, parent_kind),
262 data['fields'])
263 module.kinds[enum.spec] = enum
264 return enum
265
266 def ModuleToData(module):
267 return {
268 istr(0, 'name'): module.name,
269 istr(1, 'namespace'): module.namespace,
270 istr(2, 'structs'): map(StructToData, module.structs),
271 istr(3, 'interfaces'): map(InterfaceToData, module.interfaces)
272 }
273
274 def ModuleFromData(data):
275 module = mojom.Module()
276 module.kinds = {}
277 for kind in mojom.PRIMITIVES:
278 module.kinds[kind.spec] = kind
279
280 module.constants = {}
281
282 module.name = data['name']
283 module.namespace = data['namespace']
284 # Imports must come first, because they add to module.kinds which is used
285 # by by the others.
286 module.imports = map(
287 lambda import_data: ImportFromData(module, import_data),
288 data['imports'])
289 module.enums = map(
290 lambda enum: EnumFromData(module, enum, None), data['enums'])
291 module.structs = map(
292 lambda struct: StructFromData(module, struct), data['structs'])
293 module.interfaces = map(
294 lambda interface: InterfaceFromData(module, interface),
295 data['interfaces'])
296
297 return module
298
299 def OrderedModuleFromData(data):
300 module = ModuleFromData(data)
301 next_interface_ordinal = 0
302 for interface in module.interfaces:
303 next_ordinal = 0
304 for method in interface.methods:
305 if method.ordinal is None:
306 method.ordinal = next_ordinal
307 next_ordinal = method.ordinal + 1
308 return module
OLDNEW
« no previous file with comments | « mojo/public/bindings/pylib/generate/mojom.py ('k') | mojo/public/bindings/pylib/generate/mojom_data_tests.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698