OLD | NEW |
1 # Copyright (c) 2013 The Chromium Authors. All rights reserved. | 1 # Copyright (c) 2013 The Chromium Authors. All rights reserved. |
2 # Use of this source code is governed by a BSD-style license that can be | 2 # Use of this source code is governed by a BSD-style license that can be |
3 # found in the LICENSE file. | 3 # found in the LICENSE file. |
4 | 4 |
5 """Generates C++ source files from a mojom.Module.""" | 5 """Generates C++ source files from a mojom.Module.""" |
6 | 6 |
7 import datetime | 7 import datetime |
8 import mojom | 8 import mojom |
9 import mojom_pack | 9 import mojom_pack |
10 import os | 10 import os |
11 import re | 11 import re |
12 import sys | 12 import sys |
13 | 13 |
14 from string import Template | 14 from string import Template |
15 | 15 |
16 # mojom_cpp_generator provides a way to generate c++ code from a mojom.Module. | 16 # mojom_cpp_generator provides a way to generate c++ code from a mojom.Module. |
17 # cpp = mojom_cpp_generator.CPPGenerator(module) | 17 # cpp = mojom_cpp_generator.CPPGenerator(module) |
18 # cpp.GenerateFiles("/tmp/g") | 18 # cpp.GenerateFiles("/tmp/g") |
19 | 19 |
20 class DependentKinds(set): | |
21 """Set subclass to find the unique set of non POD types.""" | |
22 def AddKind(self, kind): | |
23 if isinstance(kind, mojom.Struct): | |
24 self.add(kind) | |
25 if isinstance(kind, mojom.Array): | |
26 self.AddKind(kind.kind) | |
27 | |
28 | |
29 class Forwards(object): | |
30 """Helper class to maintain unique set of forward declarations.""" | |
31 def __init__(self): | |
32 self.kinds = DependentKinds() | |
33 | |
34 def Add(self, kind): | |
35 self.kinds.AddKind(kind) | |
36 | |
37 def __repr__(self): | |
38 return '\n'.join( | |
39 sorted(map(lambda kind: "class %s;" % kind.name, self.kinds))) | |
40 | |
41 | |
42 class Lines(object): | 20 class Lines(object): |
43 """Helper class to maintain list of template expanded lines.""" | 21 """Helper class to maintain list of template expanded lines.""" |
44 def __init__(self, template): | 22 def __init__(self, template, indent = None): |
45 self.template = template | 23 self.template = template |
| 24 self.indent = indent |
46 self.lines = [] | 25 self.lines = [] |
47 | 26 |
48 def Add(self, map = {}, **substitutions): | 27 def Add(self, map = {}, **substitutions): |
49 if len(substitutions) > 0: | 28 if len(substitutions) > 0: |
50 map = map.copy() | 29 map = map.copy() |
51 map.update(substitutions) | 30 map.update(substitutions) |
52 | 31 |
53 self.lines.append(self.template.substitute(map)) | 32 self.lines.append(self.template.substitute(map)) |
54 | 33 |
55 def __repr__(self): | 34 def __repr__(self): |
| 35 if self.indent is not None: |
| 36 prefix = "".ljust(self.indent, ' ') |
| 37 repr = '\n'.join(self.lines) |
| 38 self.lines = map(lambda l: prefix + l, repr.splitlines()) |
56 return '\n'.join(self.lines) | 39 return '\n'.join(self.lines) |
57 | 40 |
58 | 41 |
59 def GetStructFromMethod(interface, method): | 42 def GetStructFromMethod(interface, method): |
60 """Converts a method's parameters into the fields of a struct.""" | 43 """Converts a method's parameters into the fields of a struct.""" |
61 params_class = "%s_%s_Params" % (interface.name, method.name) | 44 params_class = "%s_%s_Params" % (interface.name, method.name) |
62 struct = mojom.Struct(params_class) | 45 struct = mojom.Struct(params_class) |
63 for param in method.parameters: | 46 for param in method.parameters: |
64 struct.AddField(param.name, param.kind, param.ordinal) | 47 struct.AddField(param.name, param.kind, param.ordinal) |
65 return struct | 48 return struct |
(...skipping 30 matching lines...) Expand all Loading... |
96 bool_field_template = Template(" uint8_t ${FIELD}_ : 1;") | 79 bool_field_template = Template(" uint8_t ${FIELD}_ : 1;") |
97 setter_template = \ | 80 setter_template = \ |
98 Template(" void set_$FIELD($TYPE $FIELD) { ${FIELD}_ = $FIELD; }") | 81 Template(" void set_$FIELD($TYPE $FIELD) { ${FIELD}_ = $FIELD; }") |
99 ptr_setter_template = \ | 82 ptr_setter_template = \ |
100 Template(" void set_$FIELD($TYPE $FIELD) { ${FIELD}_.ptr = $FIELD; }") | 83 Template(" void set_$FIELD($TYPE $FIELD) { ${FIELD}_.ptr = $FIELD; }") |
101 getter_template = \ | 84 getter_template = \ |
102 Template(" $TYPE $FIELD() const { return ${FIELD}_; }") | 85 Template(" $TYPE $FIELD() const { return ${FIELD}_; }") |
103 ptr_getter_template = \ | 86 ptr_getter_template = \ |
104 Template(" $TYPE $FIELD() const { return ${FIELD}_.ptr; }") | 87 Template(" $TYPE $FIELD() const { return ${FIELD}_.ptr; }") |
105 pad_template = Template(" uint8_t _pad${COUNT}_[$PAD];") | 88 pad_template = Template(" uint8_t _pad${COUNT}_[$PAD];") |
106 name_template = \ | |
107 Template("const uint32_t k${INTERFACE}_${METHOD}_Name = $NAME;") | |
108 templates = {} | 89 templates = {} |
109 HEADER_SIZE = 8 | 90 HEADER_SIZE = 8 |
110 | 91 |
111 kind_to_type = { | 92 kind_to_type = { |
112 mojom.BOOL: "bool", | 93 mojom.BOOL: "bool", |
113 mojom.INT8: "int8_t", | 94 mojom.INT8: "int8_t", |
114 mojom.UINT8: "uint8_t", | 95 mojom.UINT8: "uint8_t", |
115 mojom.INT16: "int16_t", | 96 mojom.INT16: "int16_t", |
116 mojom.UINT16: "uint16_t", | 97 mojom.UINT16: "uint16_t", |
117 mojom.INT32: "int32_t", | 98 mojom.INT32: "int32_t", |
(...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
213 fields.append(pf.field) | 194 fields.append(pf.field) |
214 return fields | 195 return fields |
215 | 196 |
216 def GetHeaderGuard(self, name): | 197 def GetHeaderGuard(self, name): |
217 return "MOJO_GENERATED_BINDINGS_%s_%s_H_" % \ | 198 return "MOJO_GENERATED_BINDINGS_%s_%s_H_" % \ |
218 (self.module.name.upper(), name.upper()) | 199 (self.module.name.upper(), name.upper()) |
219 | 200 |
220 def GetHeaderFile(self, *components): | 201 def GetHeaderFile(self, *components): |
221 components = map(lambda c: CamelToUnderscores(c), components) | 202 components = map(lambda c: CamelToUnderscores(c), components) |
222 component_string = '_'.join(components) | 203 component_string = '_'.join(components) |
223 return os.path.join( | 204 return os.path.join(self.header_dir, "%s.h" % component_string) |
224 self.header_dir, | |
225 "%s_%s.h" % (CamelToUnderscores(self.module.name), component_string)) | |
226 | 205 |
227 # Pass |output_dir| to emit files to disk. Omit |output_dir| to echo all files | 206 # Pass |output_dir| to emit files to disk. Omit |output_dir| to echo all files |
228 # to stdout. | 207 # to stdout. |
229 def __init__(self, module, header_dir, output_dir=None): | 208 def __init__(self, module, header_dir, output_dir=None): |
230 self.module = module | 209 self.module = module |
231 self.header_dir = header_dir | 210 self.header_dir = header_dir |
232 self.output_dir = output_dir | 211 self.output_dir = output_dir |
233 | 212 |
234 def WriteTemplateToFile(self, template_name, name, **substitutions): | 213 def WriteTemplateToFile(self, template_name, **substitutions): |
235 template_name = CamelToUnderscores(template_name) | |
236 name = CamelToUnderscores(name) | |
237 template = self.GetTemplate(template_name) | 214 template = self.GetTemplate(template_name) |
238 filename = "%s_%s" % (CamelToUnderscores(self.module.name), template_name) | 215 filename = \ |
239 filename = filename.replace("interface", name) | 216 template_name.replace("module", CamelToUnderscores(self.module.name)) |
240 filename = filename.replace("struct", name) | |
241 substitutions['YEAR'] = datetime.date.today().year | 217 substitutions['YEAR'] = datetime.date.today().year |
242 substitutions['NAMESPACE'] = self.module.namespace | 218 substitutions['NAMESPACE'] = self.module.namespace |
243 if self.output_dir is None: | 219 if self.output_dir is None: |
244 file = sys.stdout | 220 file = sys.stdout |
245 else: | 221 else: |
246 file = open(os.path.join(self.output_dir, filename), "w+") | 222 file = open(os.path.join(self.output_dir, filename), "w+") |
247 try: | 223 try: |
248 file.write(template.substitute(substitutions)) | 224 file.write(template.substitute(substitutions)) |
249 finally: | 225 finally: |
250 if self.output_dir is not None: | 226 if self.output_dir is not None: |
251 file.close() | 227 file.close() |
252 | 228 |
253 def GetStructDeclaration(self, name, ps): | 229 def GetStructDeclaration(self, name, ps, template, subs = {}): |
254 params_template = self.GetTemplate("struct_declaration") | |
255 fields = [] | 230 fields = [] |
256 setters = [] | 231 setters = [] |
257 getters = [] | 232 getters = [] |
258 pad_count = 0 | 233 pad_count = 0 |
259 num_fields = len(ps.packed_fields) | 234 num_fields = len(ps.packed_fields) |
260 for i in xrange(num_fields): | 235 for i in xrange(num_fields): |
261 pf = ps.packed_fields[i] | 236 pf = ps.packed_fields[i] |
262 field = pf.field | 237 field = pf.field |
263 fields.append(self.GetFieldLine(field)) | 238 fields.append(self.GetFieldLine(field)) |
264 if i < (num_fields - 1): | 239 if i < (num_fields - 1): |
265 next_pf = ps.packed_fields[i+1] | 240 next_pf = ps.packed_fields[i+1] |
266 pad = next_pf.offset - (pf.offset + pf.size) | 241 pad = next_pf.offset - (pf.offset + pf.size) |
267 if pad > 0: | 242 if pad > 0: |
268 fields.append(self.pad_template.substitute(COUNT=pad_count, PAD=pad)) | 243 fields.append(self.pad_template.substitute(COUNT=pad_count, PAD=pad)) |
269 pad_count += 1 | 244 pad_count += 1 |
270 setters.append(self.GetSetterLine(field)) | 245 setters.append(self.GetSetterLine(field)) |
271 getters.append(self.GetGetterLine(field)) | 246 getters.append(self.GetGetterLine(field)) |
272 | 247 |
273 if num_fields > 0: | 248 if num_fields > 0: |
274 last_field = ps.packed_fields[num_fields - 1] | 249 last_field = ps.packed_fields[num_fields - 1] |
275 offset = last_field.offset + last_field.size | 250 offset = last_field.offset + last_field.size |
276 pad = mojom_pack.GetPad(offset, 8) | 251 pad = mojom_pack.GetPad(offset, 8) |
277 if pad > 0: | 252 if pad > 0: |
278 fields.append(self.pad_template.substitute(COUNT=pad_count, PAD=pad)) | 253 fields.append(self.pad_template.substitute(COUNT=pad_count, PAD=pad)) |
279 pad_count += 1 | 254 pad_count += 1 |
280 size = offset + pad | 255 size = offset + pad |
281 else: | 256 else: |
282 size = 0 | 257 size = 0 |
283 return params_template.substitute( | 258 subs.update( |
284 CLASS = name, | 259 CLASS = name, |
285 SETTERS = '\n'.join(setters), | 260 SETTERS = '\n'.join(setters), |
286 GETTERS = '\n'.join(getters), | 261 GETTERS = '\n'.join(getters), |
287 FIELDS = '\n'.join(fields), | 262 FIELDS = '\n'.join(fields), |
288 SIZE = size + self.HEADER_SIZE) | 263 SIZE = size + self.HEADER_SIZE) |
| 264 return template.substitute(subs) |
289 | 265 |
290 def GetStructImplementation(self, name, ps): | 266 def GetStructSerialization( |
291 return self.GetTemplate("struct_implementation").substitute( | 267 self, class_name, param_name, ps, template, indent = None): |
292 CLASS = name, | |
293 NUM_FIELDS = len(ps.packed_fields)) | |
294 | |
295 def GetStructSerialization(self, class_name, param_name, ps): | |
296 struct = ps.struct | 268 struct = ps.struct |
297 encodes = Lines(self.struct_serialization_encode_template) | 269 encodes = Lines(self.struct_serialization_encode_template, indent) |
298 encode_handles = Lines(self.struct_serialization_encode_handle_template) | 270 encode_handles = \ |
299 decodes = Lines(self.struct_serialization_decode_template) | 271 Lines(self.struct_serialization_encode_handle_template, indent) |
300 decode_handles = Lines(self.struct_serialization_decode_handle_template) | 272 decodes = Lines(self.struct_serialization_decode_template, indent) |
| 273 decode_handles = \ |
| 274 Lines(self.struct_serialization_decode_handle_template, indent) |
301 fields = self.GetSerializedFields(ps) | 275 fields = self.GetSerializedFields(ps) |
302 handle_fields = self.GetHandleFields(ps) | 276 handle_fields = self.GetHandleFields(ps) |
303 for field in fields: | 277 for field in fields: |
304 substitutions = {'NAME': param_name, 'FIELD': field.name} | 278 substitutions = {'NAME': param_name, 'FIELD': field.name} |
305 encodes.Add(substitutions) | 279 encodes.Add(substitutions) |
306 decodes.Add(substitutions) | 280 decodes.Add(substitutions) |
307 for field in handle_fields: | 281 for field in handle_fields: |
308 substitutions = {'NAME': param_name, 'FIELD': field.name} | 282 substitutions = {'NAME': param_name, 'FIELD': field.name} |
309 encode_handles.Add(substitutions) | 283 encode_handles.Add(substitutions) |
310 decode_handles.Add(substitutions) | 284 decode_handles.Add(substitutions) |
311 return self.GetTemplate("struct_serialization").substitute( | 285 return template.substitute( |
312 CLASS = "%s::%s" % (self.module.namespace, class_name), | 286 CLASS = "%s::%s" % (self.module.namespace, class_name), |
313 NAME = param_name, | 287 NAME = param_name, |
314 ENCODES = encodes, | 288 ENCODES = encodes, |
315 DECODES = decodes, | 289 DECODES = decodes, |
316 ENCODE_HANDLES = encode_handles, | 290 ENCODE_HANDLES = encode_handles, |
317 DECODE_HANDLES = decode_handles) | 291 DECODE_HANDLES = decode_handles) |
318 | 292 |
319 def GenerateStructHeader(self, ps): | 293 def GetStructClassDeclarations(self): |
320 struct = ps.struct | 294 struct_decls = map( |
321 forwards = Forwards() | 295 lambda s: self.GetStructDeclaration( |
322 for field in struct.fields: | 296 s.name, |
323 forwards.Add(field.kind) | 297 mojom_pack.PackedStruct(s), |
| 298 self.GetTemplate("struct_declaration"), |
| 299 {}), |
| 300 self.module.structs) |
| 301 return '\n'.join(struct_decls) |
324 | 302 |
325 self.WriteTemplateToFile("struct.h", struct.name, | 303 def GetInterfaceClassDeclaration(self, interface, template, method_postfix): |
326 HEADER_GUARD = self.GetHeaderGuard(struct.name), | |
327 CLASS = struct.name, | |
328 FORWARDS = forwards, | |
329 DECLARATION = self.GetStructDeclaration(struct.name, ps)) | |
330 | |
331 def GenerateStructSource(self, ps): | |
332 struct = ps.struct | |
333 header = self.GetHeaderFile(struct.name) | |
334 implementation = self.GetStructImplementation(struct.name, ps) | |
335 self.WriteTemplateToFile("struct.cc", struct.name, | |
336 CLASS = struct.name, | |
337 NUM_FIELDS = len(struct.fields), | |
338 HEADER = header, | |
339 IMPLEMENTATION = implementation) | |
340 | |
341 def GenerateStructSerializationHeader(self, ps): | |
342 struct = ps.struct | |
343 self.WriteTemplateToFile("struct_serialization.h", struct.name, | |
344 HEADER_GUARD = self.GetHeaderGuard(struct.name + "_SERIALIZATION"), | |
345 CLASS = struct.name, | |
346 NAME = CamelToUnderscores(struct.name), | |
347 FULL_CLASS = "%s::%s" % \ | |
348 (self.module.namespace, struct.name)) | |
349 | |
350 def GenerateStructSerializationSource(self, ps): | |
351 struct = ps.struct | |
352 serialization_header = self.GetHeaderFile(struct.name, "serialization") | |
353 param_name = CamelToUnderscores(struct.name) | |
354 | |
355 kinds = DependentKinds() | |
356 for field in struct.fields: | |
357 kinds.AddKind(field.kind) | |
358 headers = \ | |
359 map(lambda kind: self.GetHeaderFile(kind.name, "serialization"), kinds) | |
360 headers.append(self.GetHeaderFile(struct.name)) | |
361 includes = map(lambda header: "#include \"%s\"" % header, sorted(headers)) | |
362 | |
363 class_header = self.GetHeaderFile(struct.name) | |
364 clones = Lines(self.struct_serialization_clone_template) | |
365 sizes = " return sizeof(*%s)" % param_name | |
366 fields = self.GetSerializedFields(ps) | |
367 for field in fields: | |
368 substitutions = {'NAME': param_name, 'FIELD': field.name} | |
369 sizes += \ | |
370 self.struct_serialization_compute_template.substitute(substitutions) | |
371 clones.Add(substitutions) | |
372 sizes += ";" | |
373 serialization = self.GetStructSerialization(struct.name, param_name, ps) | |
374 self.WriteTemplateToFile("struct_serialization.cc", struct.name, | |
375 NAME = param_name, | |
376 CLASS = "%s::%s" % (self.module.namespace, struct.name), | |
377 SERIALIZATION_HEADER = serialization_header, | |
378 INCLUDES = '\n'.join(includes), | |
379 SIZES = sizes, | |
380 CLONES = clones, | |
381 SERIALIZATION = serialization) | |
382 | |
383 def GenerateInterfaceHeader(self, interface): | |
384 methods = [] | 304 methods = [] |
385 forwards = Forwards() | |
386 for method in interface.methods: | 305 for method in interface.methods: |
387 params = [] | 306 params = [] |
388 for param in method.parameters: | 307 for param in method.parameters: |
389 forwards.Add(param.kind) | |
390 params.append("%s %s" % (self.GetConstType(param.kind), param.name)) | 308 params.append("%s %s" % (self.GetConstType(param.kind), param.name)) |
391 methods.append( | 309 methods.append( |
392 " virtual void %s(%s) = 0;" % (method.name, ", ".join(params))) | 310 " virtual void %s(%s) %s;" % |
| 311 (method.name, ", ".join(params), method_postfix)) |
| 312 return template.substitute( |
| 313 CLASS=interface.name, |
| 314 METHODS='.\n'.join(methods)) |
393 | 315 |
394 self.WriteTemplateToFile("interface.h", interface.name, | 316 def GetInterfaceClassDeclarations(self): |
395 HEADER_GUARD = self.GetHeaderGuard(interface.name), | 317 template = self.GetTemplate("interface_declaration") |
396 CLASS = interface.name, | 318 interface_decls = \ |
397 FORWARDS = forwards, | 319 map(lambda i: |
398 METHODS = '\n'.join(methods)) | 320 self.GetInterfaceClassDeclaration(i, template, " = 0"), |
| 321 self.module.interfaces) |
| 322 return '\n'.join(interface_decls) |
399 | 323 |
400 def GenerateInterfaceStubHeader(self, interface): | 324 def GetInterfaceProxyDeclarations(self): |
401 header = self.GetHeaderFile(interface.name) | 325 template = self.GetTemplate("interface_proxy_declaration") |
402 self.WriteTemplateToFile("interface_stub.h", interface.name, | 326 interface_decls = \ |
403 HEADER_GUARD = self.GetHeaderGuard(interface.name + "_STUB"), | 327 map(lambda i: |
404 CLASS = interface.name, | 328 self.GetInterfaceClassDeclaration(i, template, "MOJO_OVERRIDE"), |
405 HEADER = header) | 329 self.module.interfaces) |
| 330 return '\n'.join(interface_decls) |
406 | 331 |
407 def GenerateInterfaceStubSource(self, interface): | 332 def GetInterfaceStubDeclarations(self): |
408 stub_header = self.GetHeaderFile(interface.name, "stub") | 333 template = self.GetTemplate("interface_stub_declaration") |
409 serialization_header = self.GetHeaderFile(interface.name, "serialization") | 334 interface_decls = \ |
| 335 map(lambda i: template.substitute(CLASS=i.name), self.module.interfaces) |
| 336 return '\n'.join(interface_decls) |
| 337 |
| 338 def GenerateModuleHeader(self): |
| 339 self.WriteTemplateToFile("module.h", |
| 340 HEADER_GUARD = self.GetHeaderGuard(self.module.name), |
| 341 STRUCT_CLASS_DECLARARTIONS = self.GetStructClassDeclarations(), |
| 342 INTERFACE_CLASS_DECLARATIONS = self.GetInterfaceClassDeclarations(), |
| 343 INTERFACE_PROXY_DECLARATIONS = self.GetInterfaceProxyDeclarations(), |
| 344 INTERFACE_STUB_DECLARATIONS = self.GetInterfaceStubDeclarations()) |
| 345 |
| 346 def GetParamsDefinition(self, interface, method, next_id): |
| 347 struct = GetStructFromMethod(interface, method) |
| 348 method_name = "k%s_%s_Name" % (interface.name, method.name) |
| 349 if method.ordinal is not None: |
| 350 next_id = method.ordinal |
| 351 params_def = self.GetStructDeclaration( |
| 352 struct.name, |
| 353 mojom_pack.PackedStruct(struct), |
| 354 self.GetTemplate("params_definition"), |
| 355 {'METHOD_NAME': method_name, 'METHOD_ID': next_id}) |
| 356 return params_def, next_id + 1 |
| 357 |
| 358 def GetStructDefinitions(self): |
| 359 template = self.GetTemplate("struct_definition") |
| 360 return '\n'.join(map( |
| 361 lambda s: template.substitute( |
| 362 CLASS = s.name, NUM_FIELDS = len(s.fields)), |
| 363 self.module.structs)); |
| 364 |
| 365 def GetInterfaceDefinition(self, interface): |
410 cases = [] | 366 cases = [] |
| 367 implementations = Lines(self.GetTemplate("proxy_implementation")) |
| 368 |
411 for method in interface.methods: | 369 for method in interface.methods: |
412 cases.append(self.GetCaseLine(interface, method)) | 370 cases.append(self.GetCaseLine(interface, method)) |
413 self.WriteTemplateToFile("interface_stub.cc", interface.name, | |
414 CLASS = interface.name, | |
415 CASES = '\n'.join(cases), | |
416 STUB_HEADER = stub_header, | |
417 SERIALIZATION_HEADER = serialization_header) | |
418 | |
419 def GenerateInterfaceSerializationHeader(self, interface): | |
420 kinds = DependentKinds() | |
421 for method in interface.methods: | |
422 for param in method.parameters: | |
423 kinds.AddKind(param.kind) | |
424 headers = \ | |
425 map(lambda kind: self.GetHeaderFile(kind.name, "serialization"), kinds) | |
426 headers.append(self.GetHeaderFile(interface.name)) | |
427 headers.append("mojo/public/bindings/lib/bindings_serialization.h") | |
428 includes = map(lambda header: "#include \"%s\"" % header, sorted(headers)) | |
429 | |
430 names = [] | |
431 name = 1 | |
432 param_classes = [] | |
433 param_templates = [] | |
434 template_declaration = self.GetTemplate("template_declaration") | |
435 for method in interface.methods: | |
436 names.append(self.name_template.substitute( | |
437 INTERFACE = interface.name, | |
438 METHOD = method.name, | |
439 NAME = name)) | |
440 name += 1 | |
441 | |
442 struct = GetStructFromMethod(interface, method) | |
443 ps = mojom_pack.PackedStruct(struct) | |
444 param_classes.append(self.GetStructDeclaration(struct.name, ps)) | |
445 param_templates.append(template_declaration.substitute(CLASS=struct.name)) | |
446 | |
447 self.WriteTemplateToFile("interface_serialization.h", interface.name, | |
448 HEADER_GUARD = self.GetHeaderGuard(interface.name + "_SERIALIZATION"), | |
449 INCLUDES = '\n'.join(includes), | |
450 NAMES = '\n'.join(names), | |
451 PARAM_CLASSES = '\n'.join(param_classes), | |
452 PARAM_TEMPLATES = '\n'.join(param_templates)) | |
453 | |
454 def GenerateInterfaceSerializationSource(self, interface): | |
455 implementations = [] | |
456 serializations = [] | |
457 for method in interface.methods: | |
458 struct = GetStructFromMethod(interface, method) | |
459 ps = mojom_pack.PackedStruct(struct) | |
460 implementations.append(self.GetStructImplementation(struct.name, ps)) | |
461 serializations.append( | |
462 self.GetStructSerialization("internal::" + struct.name, "params", ps)) | |
463 self.WriteTemplateToFile("interface_serialization.cc", interface.name, | |
464 HEADER = self.GetHeaderFile(interface.name, "serialization"), | |
465 IMPLEMENTATIONS = '\n'.join(implementations), | |
466 SERIALIZATIONS = '\n'.join(serializations)) | |
467 | |
468 def GenerateInterfaceProxyHeader(self, interface): | |
469 methods = [] | |
470 for method in interface.methods: | |
471 params = map( | |
472 lambda param: "%s %s" % (self.GetConstType(param.kind), param.name), | |
473 method.parameters) | |
474 methods.append( | |
475 " virtual void %s(%s) MOJO_OVERRIDE;" \ | |
476 % (method.name, ", ".join(params))) | |
477 | |
478 self.WriteTemplateToFile("interface_proxy.h", interface.name, | |
479 HEADER_GUARD = self.GetHeaderGuard(interface.name + "_PROXY"), | |
480 HEADER = self.GetHeaderFile(interface.name), | |
481 CLASS = interface.name, | |
482 METHODS = '\n'.join(methods)) | |
483 | |
484 def GenerateInterfaceProxySource(self, interface): | |
485 implementations = Lines(self.GetTemplate("proxy_implementation")) | |
486 for method in interface.methods: | |
487 sets = [] | 371 sets = [] |
488 computes = Lines(self.param_struct_compute_template) | 372 computes = Lines(self.param_struct_compute_template) |
489 for param in method.parameters: | 373 for param in method.parameters: |
490 if IsPointerKind(param.kind): | 374 if IsPointerKind(param.kind): |
491 sets.append( | 375 sets.append( |
492 self.param_struct_set_template.substitute(NAME=param.name)) | 376 self.param_struct_set_template.substitute(NAME=param.name)) |
493 computes.Add(NAME=param.name) | 377 computes.Add(NAME=param.name) |
494 else: | 378 else: |
495 sets.append(self.param_set_template.substitute(NAME=param.name)) | 379 sets.append(self.param_set_template.substitute(NAME=param.name)) |
496 params_list = map( | 380 params_list = map( |
497 lambda param: "%s %s" % (self.GetConstType(param.kind), param.name), | 381 lambda param: "%s %s" % (self.GetConstType(param.kind), param.name), |
498 method.parameters) | 382 method.parameters) |
499 name = "internal::k%s_%s_Name" % (interface.name, method.name) | 383 name = "k%s_%s_Name" % (interface.name, method.name) |
500 params_name = "internal::%s_%s_Params" % (interface.name, method.name) | 384 params_name = "%s_%s_Params" % (interface.name, method.name) |
501 | 385 |
502 implementations.Add( | 386 implementations.Add( |
503 CLASS = interface.name, | 387 CLASS = interface.name, |
504 METHOD = method.name, | 388 METHOD = method.name, |
505 NAME = name, | 389 NAME = name, |
506 PARAMS = params_name, | 390 PARAMS = params_name, |
507 PARAMS_LIST = ', '.join(params_list), | 391 PARAMS_LIST = ', '.join(params_list), |
508 COMPUTES = computes, | 392 COMPUTES = computes, |
509 SETS = '\n'.join(sets)) | 393 SETS = '\n'.join(sets)) |
510 self.WriteTemplateToFile("interface_proxy.cc", interface.name, | 394 stub_definition = self.GetTemplate("interface_stub_definition").substitute( |
511 HEADER = self.GetHeaderFile(interface.name, "proxy"), | |
512 SERIALIZATION_HEADER = \ | |
513 self.GetHeaderFile(interface.name, "serialization"), | |
514 CLASS = interface.name, | 395 CLASS = interface.name, |
515 IMPLEMENTATIONS = implementations) | 396 CASES = '\n'.join(cases)) |
| 397 return self.GetTemplate("interface_definition").substitute( |
| 398 CLASS = interface.name + "Proxy", |
| 399 PROXY_DEFINITIONS = implementations, |
| 400 STUB_DEFINITION = stub_definition) |
| 401 |
| 402 def GetInterfaceDefinitions(self): |
| 403 return '\n'.join( |
| 404 map(lambda i: self.GetInterfaceDefinition(i), self.module.interfaces)) |
| 405 |
| 406 def GetStructSerializationDefinition(self, struct): |
| 407 ps = mojom_pack.PackedStruct(struct) |
| 408 param_name = CamelToUnderscores(struct.name) |
| 409 |
| 410 clones = Lines(self.struct_serialization_clone_template) |
| 411 sizes = " return sizeof(*%s)" % param_name |
| 412 fields = self.GetSerializedFields(ps) |
| 413 for field in fields: |
| 414 substitutions = {'NAME': param_name, 'FIELD': field.name} |
| 415 sizes += \ |
| 416 self.struct_serialization_compute_template.substitute(substitutions) |
| 417 clones.Add(substitutions) |
| 418 sizes += ";" |
| 419 serialization = self.GetStructSerialization( |
| 420 struct.name, param_name, ps, self.GetTemplate("struct_serialization")) |
| 421 return self.GetTemplate("struct_serialization_definition").substitute( |
| 422 NAME = param_name, |
| 423 CLASS = "%s::%s" % (self.module.namespace, struct.name), |
| 424 SIZES = sizes, |
| 425 CLONES = clones, |
| 426 SERIALIZATION = serialization) |
| 427 |
| 428 def GetStructSerializationDefinitions(self): |
| 429 return '\n'.join( |
| 430 map(lambda i: self.GetStructSerializationDefinition(i), |
| 431 self.module.structs)) |
| 432 |
| 433 def GetInterfaceSerializationDefinitions(self): |
| 434 serializations = [] |
| 435 for interface in self.module.interfaces: |
| 436 for method in interface.methods: |
| 437 struct = GetStructFromMethod(interface, method) |
| 438 ps = mojom_pack.PackedStruct(struct) |
| 439 serializations.append(self.GetStructSerialization( |
| 440 struct.name, |
| 441 "params", |
| 442 ps, |
| 443 self.GetTemplate("params_serialization"), |
| 444 2)) |
| 445 return '\n'.join(serializations) |
| 446 |
| 447 def GetParamsDefinitions(self): |
| 448 params_defs = [] |
| 449 for interface in self.module.interfaces: |
| 450 next_id = 0 |
| 451 for method in interface.methods: |
| 452 (params_def, next_id) = \ |
| 453 self.GetParamsDefinition(interface, method, next_id) |
| 454 params_defs.append(params_def) |
| 455 return '\n'.join(params_defs) |
| 456 |
| 457 def GenerateModuleSource(self): |
| 458 self.WriteTemplateToFile("module.cc", |
| 459 HEADER = self.GetHeaderFile(self.module.name), |
| 460 INTERNAL_HEADER = self.GetHeaderFile(self.module.name, "internal"), |
| 461 PARAM_DEFINITIONS = self.GetParamsDefinitions(), |
| 462 STRUCT_DEFINITIONS = self.GetStructDefinitions(), |
| 463 INTERFACE_DEFINITIONS = self.GetInterfaceDefinitions(), |
| 464 STRUCT_SERIALIZATION_DEFINITIONS = |
| 465 self.GetStructSerializationDefinitions(), |
| 466 INTERFACE_SERIALIZATION_DEFINITIONS = |
| 467 self.GetInterfaceSerializationDefinitions()) |
| 468 |
| 469 def GenerateModuleInternalHeader(self): |
| 470 traits = map( |
| 471 lambda s: self.GetTemplate("struct_serialization_traits").substitute( |
| 472 NAME = CamelToUnderscores(s.name), |
| 473 FULL_CLASS = "%s::%s" % (self.module.namespace, s.name)), |
| 474 self.module.structs); |
| 475 self.WriteTemplateToFile("module_internal.h", |
| 476 HEADER_GUARD = self.GetHeaderGuard(self.module.name + "_INTERNAL"), |
| 477 HEADER = self.GetHeaderFile(self.module.name), |
| 478 TRAITS = '\n'.join(traits)) |
516 | 479 |
517 def GenerateFiles(self): | 480 def GenerateFiles(self): |
518 for struct in self.module.structs: | 481 self.GenerateModuleHeader() |
519 ps = mojom_pack.PackedStruct(struct) | 482 self.GenerateModuleInternalHeader() |
520 self.GenerateStructHeader(ps) | 483 self.GenerateModuleSource() |
521 self.GenerateStructSource(ps) | |
522 self.GenerateStructSerializationHeader(ps) | |
523 self.GenerateStructSerializationSource(ps) | |
524 for interface in self.module.interfaces: | |
525 self.GenerateInterfaceHeader(interface) | |
526 self.GenerateInterfaceStubHeader(interface) | |
527 self.GenerateInterfaceStubSource(interface) | |
528 self.GenerateInterfaceSerializationHeader(interface) | |
529 self.GenerateInterfaceSerializationSource(interface) | |
530 self.GenerateInterfaceProxyHeader(interface) | |
531 self.GenerateInterfaceProxySource(interface) | |
OLD | NEW |