OLD | NEW |
1 # Copyright 2015 The Chromium Authors. All rights reserved. | 1 # Copyright 2015 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 Go source files from a mojom.Module.''' | 5 '''Generates Go source files from a mojom.Module.''' |
6 | 6 |
7 from itertools import chain | 7 from itertools import chain |
8 import os | 8 import os |
9 import re | 9 import re |
10 | 10 |
(...skipping 175 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
186 | 186 |
187 def EncodeSuffix(kind): | 187 def EncodeSuffix(kind): |
188 if mojom.IsEnumKind(kind): | 188 if mojom.IsEnumKind(kind): |
189 return EncodeSuffix(mojom.INT32) | 189 return EncodeSuffix(mojom.INT32) |
190 if mojom.IsInterfaceKind(kind): | 190 if mojom.IsInterfaceKind(kind): |
191 return 'Interface' | 191 return 'Interface' |
192 if mojom.IsInterfaceRequestKind(kind): | 192 if mojom.IsInterfaceRequestKind(kind): |
193 return EncodeSuffix(mojom.MSGPIPE) | 193 return EncodeSuffix(mojom.MSGPIPE) |
194 return _kind_infos[kind].encode_suffix | 194 return _kind_infos[kind].encode_suffix |
195 | 195 |
196 # This helper assists in the production of mojom_types.Type for simple kinds. | |
197 # See _kind_infos above. | |
198 def GetMojomTypeValue(kind, typepkg=''): | |
199 if not kind in _kind_infos: | |
200 return '' | |
201 | |
202 nullable = 'true' if mojom.IsNullableKind(kind) else 'false' | |
203 if kind == mojom.BOOL or kind == mojom.FLOAT or kind == mojom.DOUBLE or \ | |
204 mojom.IsIntegralKind(kind): | |
205 | |
206 kind_name = UpperCamelCase(_kind_infos[kind].decode_suffix.upper()) | |
207 if kind == mojom.FLOAT: | |
208 kind_name = "Float" | |
209 elif kind == mojom.DOUBLE: | |
210 kind_name = "Double" | |
211 return '%sTypeSimpleType{%sSimpleType_%s}' % (typepkg, typepkg, kind_name) | |
212 elif mojom.IsAnyHandleKind(kind): | |
213 kind_name = 'Unspecified' | |
214 if kind == mojom.DCPIPE: | |
215 kind_name = 'DataPipeConsumer' | |
216 elif kind == mojom.DPPIPE: | |
217 kind_name = 'DataPipeProducer' | |
218 elif kind == mojom.MSGPIPE: | |
219 kind_name = 'MessagePipe' | |
220 elif kind == mojom.SHAREDBUFFER: | |
221 kind_name = 'SharedBuffer' | |
222 return '%sTypeHandleType{%sHandleType{' \ | |
223 'Nullable: %s, Kind: %sHandleType_Kind_%s}}' % \ | |
224 (typepkg, typepkg, nullable, typepkg, kind_name) | |
225 elif mojom.IsStringKind(kind): | |
226 return '%sTypeStringType{%sStringType{%s}}' % (typepkg, typepkg, nullable) | |
227 else: | |
228 raise Exception('Missing case for kind: %s' % kind) | |
229 | |
230 def GetPackageName(module): | 196 def GetPackageName(module): |
231 return module.name.split('.')[0] | 197 return module.name.split('.')[0] |
232 | 198 |
233 def GetPackageNameForElement(element): | 199 def GetPackageNameForElement(element): |
234 if not hasattr(element, 'imported_from') or not element.imported_from: | 200 if not hasattr(element, 'imported_from') or not element.imported_from: |
235 return '' | 201 return '' |
236 return element.imported_from.get('go_name', '') | 202 return element.imported_from.get('go_name', '') |
237 | 203 |
| 204 def GetTypeKeyForElement(element): |
| 205 if not hasattr(element, 'type_key') or not element.type_key: |
| 206 return '' |
| 207 return element.type_key |
| 208 |
238 def GetQualifiedName(name, package=None, exported=True): | 209 def GetQualifiedName(name, package=None, exported=True): |
239 if not package: | 210 if not package: |
240 return FormatName(name, exported) | 211 return FormatName(name, exported) |
241 return '%s.%s' % (package, FormatName(name, exported)) | 212 return '%s.%s' % (package, FormatName(name, exported)) |
242 | 213 |
243 def GetPackagePath(module): | 214 def GetPackagePath(module): |
244 name = module.name.split('.')[0] | 215 name = module.name.split('.')[0] |
245 return '/'.join(module.path.split('/')[:-1] + [name]) | 216 return '/'.join(module.path.split('/')[:-1] + [name]) |
246 | 217 |
247 def GetAllConstants(module): | 218 def GetAllConstants(module): |
248 data = [module] + module.structs + module.interfaces | 219 data = [module] + module.structs + module.interfaces |
249 constants = [x.constants for x in data] | 220 constants = [x.constants for x in data] |
250 return [i for i in chain.from_iterable(constants)] | 221 return [i for i in chain.from_iterable(constants)] |
251 | 222 |
252 def GetAllEnums(module): | 223 def GetAllEnums(module): |
253 data = [module] + module.structs + module.interfaces | 224 data = [module] + module.structs + module.interfaces |
254 enums = [x.enums for x in data] | 225 enums = [x.enums for x in data] |
255 return [i for i in chain.from_iterable(enums)] | 226 return [i for i in chain.from_iterable(enums)] |
256 | 227 |
| 228 def GetSerializedRuntimeTypeInfoLiteral(module, enabled): |
| 229 """ Constructs a string that represents a literal definition in Go of |
| 230 an array of bytes corresponding to |module.serialized_runtime_type_info|. |
| 231 |
| 232 Args: |
| 233 module: {mojom.Module} the module being processed. |
| 234 enabled: {bool} Is this feature enabled. |
| 235 |
| 236 Returns: A string of the form '{b0, b1, b2,...}' where the 'bi' are |
| 237 the decimal representation of the bytes of |
| 238 |module.serialized_runtime_type_info| or the string '{}' if either |
| 239 |enabled| is false or |module.serialized_runtime_type_info| is None. |
| 240 Furthermore the returned string will have embedded newline characters inserted |
| 241 every 1000 characters to make the generated source code more tractable. |
| 242 """ |
| 243 if not enabled or not module.serialized_runtime_type_info: |
| 244 return '{}' |
| 245 return '{%s}' % ','.join('%s%d' % |
| 246 ('\n' if index > 0 and index%1000 == 0 else '', b) |
| 247 for index, b in enumerate(module.serialized_runtime_type_info)) |
| 248 |
257 def AddImport(imports, mojom_imports, module, element): | 249 def AddImport(imports, mojom_imports, module, element): |
258 """Adds an import required to use the provided element. | 250 """Adds an import required to use the provided element. |
259 | 251 |
260 The required import is stored in the imports parameter. | 252 The required import is stored in the imports parameter. |
261 The corresponding mojom import is stored in the mojom_imports parameter. | 253 The corresponding mojom import is stored in the mojom_imports parameter. |
262 Each import is also updated to include a 'go_name' entry. The 'go_name' entry | 254 Each import is also updated to include a 'go_name' entry. The 'go_name' entry |
263 is the name by which the imported module will be referred to in the generated | 255 is the name by which the imported module will be referred to in the generated |
264 code. Because the import dictionary is accessible from the element's | 256 code. Because the import dictionary is accessible from the element's |
265 imported_from field this allows us to generate the qualified name for the | 257 imported_from field this allows us to generate the qualified name for the |
266 element. | 258 element. |
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
317 'is_interface': mojom.IsInterfaceKind, | 309 'is_interface': mojom.IsInterfaceKind, |
318 'is_interface_request': mojom.IsInterfaceRequestKind, | 310 'is_interface_request': mojom.IsInterfaceRequestKind, |
319 'is_map': mojom.IsMapKind, | 311 'is_map': mojom.IsMapKind, |
320 'is_none_or_empty': lambda array: array is None or len(array) == 0, | 312 'is_none_or_empty': lambda array: array is None or len(array) == 0, |
321 'is_nullable': mojom.IsNullableKind, | 313 'is_nullable': mojom.IsNullableKind, |
322 'is_pointer': IsPointer, | 314 'is_pointer': IsPointer, |
323 'is_object': mojom.IsObjectKind, | 315 'is_object': mojom.IsObjectKind, |
324 'is_struct': mojom.IsStructKind, | 316 'is_struct': mojom.IsStructKind, |
325 'is_union': mojom.IsUnionKind, | 317 'is_union': mojom.IsUnionKind, |
326 'qualified': GetQualifiedName, | 318 'qualified': GetQualifiedName, |
327 'fullidentifier': mojom.GetMojomTypeFullIdentifier, | 319 'mojom_type_key' : GetTypeKeyForElement, |
328 'mojom_type': GetMojomTypeValue, | |
329 'mojom_type_identifier': mojom.GetMojomTypeIdentifier, | |
330 'name': GetNameForElement, | 320 'name': GetNameForElement, |
331 'unqualified_name': GetUnqualifiedNameForElement, | 321 'unqualified_name': GetUnqualifiedNameForElement, |
332 'package': GetPackageNameForElement, | 322 'package': GetPackageNameForElement, |
333 'tab_indent': lambda s, size = 1: ('\n' + '\t' * size).join(s.splitlines()) | 323 'tab_indent': lambda s, size = 1: ('\n' + '\t' * size).join(s.splitlines()) |
334 } | 324 } |
335 | 325 |
336 # If set to True, then mojom type information will be generated. | 326 # If set to True, then mojom type information will be generated. |
337 should_gen_mojom_types = False | 327 should_gen_mojom_types = False |
338 | 328 |
339 def GetParameters(self): | 329 def GetParameters(self): |
340 package = GetPackageName(self.module) | 330 package = GetPackageName(self.module) |
341 imports, mojom_imports = self.GetImports() | 331 imports, mojom_imports = self.GetImports() |
342 return { | 332 return { |
343 'enums': GetAllEnums(self.module), | 333 'enums': GetAllEnums(self.module), |
344 'imports': imports, | 334 'imports': imports, |
345 'interfaces': self.GetInterfaces(), | 335 'interfaces': self.GetInterfaces(), |
346 'mojom_imports': mojom_imports, | 336 'mojom_imports': mojom_imports, |
347 'package': package, | 337 'package': package, |
348 'structs': self.GetStructs(), | 338 'structs': self.GetStructs(), |
349 'descpkg': '%s.' % _service_describer_pkg_short \ | 339 'descpkg': '%s.' % _service_describer_pkg_short \ |
350 if package != _service_describer_pkg_short else '', | 340 if package != _service_describer_pkg_short else '', |
351 'typepkg': '%s.' % _mojom_types_pkg_short \ | 341 'typepkg': '%s.' % _mojom_types_pkg_short \ |
352 if package != _mojom_types_pkg_short else '', | 342 if package != _mojom_types_pkg_short else '', |
353 'unions': self.GetUnions() | 343 'unions': self.GetUnions(), |
| 344 'serialized_runtime_type_info_literal' : ( |
| 345 GetSerializedRuntimeTypeInfoLiteral(self.module, |
| 346 self.should_gen_mojom_types)) |
354 } | 347 } |
355 | 348 |
356 @UseJinja('go_templates/source.tmpl', filters=go_filters) | 349 @UseJinja('go_templates/source.tmpl', filters=go_filters) |
357 def GenerateSource(self): | 350 def GenerateSource(self): |
358 return self.GetParameters() | 351 return self.GetParameters() |
359 | 352 |
360 def GenerateFiles(self, args): | 353 def GenerateFiles(self, args): |
361 self.should_gen_mojom_types = "--generate_type_info" in args | 354 self.should_gen_mojom_types = "--generate_type_info" in args |
362 | 355 |
363 self.Write(self.GenerateSource(), os.path.join("go", "src", | 356 self.Write(self.GenerateSource(), os.path.join("go", "src", |
(...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
461 # Overrides the implementation from the base class in order to customize the | 454 # Overrides the implementation from the base class in order to customize the |
462 # struct and field names. | 455 # struct and field names. |
463 def _GetResponseStructFromMethod(self, method): | 456 def _GetResponseStructFromMethod(self, method): |
464 params_class = "%s_%s_ResponseParams" % ( | 457 params_class = "%s_%s_ResponseParams" % ( |
465 GetNameForElement(method.interface), GetNameForElement(method)) | 458 GetNameForElement(method.interface), GetNameForElement(method)) |
466 struct = mojom.Struct(params_class, module=method.interface.module) | 459 struct = mojom.Struct(params_class, module=method.interface.module) |
467 for param in method.response_parameters: | 460 for param in method.response_parameters: |
468 struct.AddField("out%s" % GetNameForElement(param), | 461 struct.AddField("out%s" % GetNameForElement(param), |
469 param.kind, param.ordinal, attributes=param.attributes) | 462 param.kind, param.ordinal, attributes=param.attributes) |
470 return self._AddStructComputedData(False, struct) | 463 return self._AddStructComputedData(False, struct) |
OLD | NEW |