Chromium Code Reviews| Index: mojo/public/tools/bindings/generators/mojom_go_generator.py |
| diff --git a/mojo/public/tools/bindings/generators/mojom_go_generator.py b/mojo/public/tools/bindings/generators/mojom_go_generator.py |
| index 62babffad83c138045e94330b17023c58d5fba16..d02b75774f4c8c5ff434d331c12e8ca659993e76 100644 |
| --- a/mojo/public/tools/bindings/generators/mojom_go_generator.py |
| +++ b/mojo/public/tools/bindings/generators/mojom_go_generator.py |
| @@ -5,6 +5,7 @@ |
| '''Generates Go source files from a mojom.Module.''' |
| from itertools import chain |
| +import base64 |
| import os |
| import re |
| @@ -15,49 +16,56 @@ import mojom.generate.module as mojom |
| import mojom.generate.pack as pack |
| class KindInfo(object): |
| - def __init__(self, go_type, encode_suffix, decode_suffix, bit_size): |
| + def __init__(self, go_type, encode_suffix, decode_suffix, bit_size, type_template): |
| self.go_type = go_type |
| self.encode_suffix = encode_suffix |
| self.decode_suffix = decode_suffix |
| self.bit_size = bit_size |
| + self.type_template = type_template |
| _kind_infos = { |
| - mojom.BOOL: KindInfo('bool', 'Bool', 'Bool', 1), |
| - mojom.INT8: KindInfo('int8', 'Int8', 'Int8', 8), |
| - mojom.UINT8: KindInfo('uint8', 'Uint8', 'Uint8', 8), |
| - mojom.INT16: KindInfo('int16', 'Int16', 'Int16', 16), |
| - mojom.UINT16: KindInfo('uint16', 'Uint16', 'Uint16', 16), |
| - mojom.INT32: KindInfo('int32', 'Int32', 'Int32', 32), |
| - mojom.UINT32: KindInfo('uint32', 'Uint32', 'Uint32', 32), |
| - mojom.FLOAT: KindInfo('float32', 'Float32', 'Float32', 32), |
| + mojom.BOOL: KindInfo('bool', 'Bool', 'Bool', 1, '%sTypeSimpleType{%sSimpleType_Bool}'), |
| + mojom.INT8: KindInfo('int8', 'Int8', 'Int8', 8, '%sTypeSimpleType{%sSimpleType_InT8}'), |
| + mojom.UINT8: KindInfo('uint8', 'Uint8', 'Uint8', 8, '%sTypeSimpleType{%sSimpleType_UinT8}'), |
| + mojom.INT16: KindInfo('int16', 'Int16', 'Int16', 16, '%sTypeSimpleType{%sSimpleType_InT16}'), |
| + mojom.UINT16: KindInfo('uint16', 'Uint16', 'Uint16', 16, '%sTypeSimpleType{%sSimpleType_UinT16}'), |
| + mojom.INT32: KindInfo('int32', 'Int32', 'Int32', 32, '%sTypeSimpleType{%sSimpleType_InT32}'), |
| + mojom.UINT32: KindInfo('uint32', 'Uint32', 'Uint32', 32, '%sTypeSimpleType{%sSimpleType_UinT32}'), |
| + mojom.FLOAT: KindInfo('float32', 'Float32', 'Float32', 32, '%sTypeSimpleType{%sSimpleType_Float}'), |
| mojom.HANDLE: KindInfo( |
| - 'system.Handle', 'Handle', 'Handle', 32), |
| + 'system.Handle', 'Handle', 'Handle', 32, '%sTypeHandleType{%sHandleType{Nullable: false, Kind: %sHandleType_Kind_Unspecified}}'), |
| mojom.DCPIPE: KindInfo( |
| - 'system.ConsumerHandle', 'Handle', 'ConsumerHandle', 32), |
| + 'system.ConsumerHandle', 'Handle', 'ConsumerHandle', 32, '%sTypeHandleType{%sHandleType{Nullable: false, Kind: %sHandleType_Kind_DataPipeConsumer}}'), |
| mojom.DPPIPE: KindInfo( |
| - 'system.ProducerHandle', 'Handle', 'ProducerHandle', 32), |
| + 'system.ProducerHandle', 'Handle', 'ProducerHandle', 32, '%sTypeHandleType{%sHandleType{Nullable: false, Kind: %sHandleType_Kind_DataPipeProducer}}'), |
| mojom.MSGPIPE: KindInfo( |
| - 'system.MessagePipeHandle', 'Handle', 'MessagePipeHandle', 32), |
| + 'system.MessagePipeHandle', 'Handle', 'MessagePipeHandle', 32, '%sTypeHandleType{%sHandleType{Nullable: false, Kind: %sHandleType_Kind_MessagePipe}}'), |
| mojom.SHAREDBUFFER: KindInfo( |
| - 'system.SharedBufferHandle', 'Handle', 'SharedBufferHandle', 32), |
| + 'system.SharedBufferHandle', 'Handle', 'SharedBufferHandle', 32, '%sTypeHandleType{%sHandleType{Nullable: false, Kind: %sHandleType_Kind_SharedBuffer}}'), |
| mojom.NULLABLE_HANDLE: KindInfo( |
| - 'system.Handle', 'Handle', 'Handle', 32), |
| + 'system.Handle', 'Handle', 'Handle', 32, '%sTypeHandleType{%sHandleType{Nullable: true, Kind: %sHandleType_Kind_Unspecified}}'), |
| mojom.NULLABLE_DCPIPE: KindInfo( |
| - 'system.ConsumerHandle', 'Handle', 'ConsumerHandle', 32), |
| + 'system.ConsumerHandle', 'Handle', 'ConsumerHandle', 32, '%sTypeHandleType{%sHandleType{Nullable: true, Kind: %sHandleType_Kind_DataPipeConsumer}}'), |
| mojom.NULLABLE_DPPIPE: KindInfo( |
| - 'system.ProducerHandle', 'Handle', 'ProducerHandle', 32), |
| + 'system.ProducerHandle', 'Handle', 'ProducerHandle', 32, '%sTypeHandleType{%sHandleType{Nullable: true, Kind: %sHandleType_Kind_DataPipeProducer}}'), |
| mojom.NULLABLE_MSGPIPE: KindInfo( |
| - 'system.MessagePipeHandle', 'Handle', 'MessagePipeHandle', 32), |
| + 'system.MessagePipeHandle', 'Handle', 'MessagePipeHandle', 32, '%sTypeHandleType{%sHandleType{Nullable: true, Kind: %sHandleType_Kind_MessagePipe}}'), |
| mojom.NULLABLE_SHAREDBUFFER: KindInfo( |
| - 'system.SharedBufferHandle', 'Handle', 'SharedBufferHandle', 32), |
| - mojom.INT64: KindInfo('int64', 'Int64', 'Int64', 64), |
| - mojom.UINT64: KindInfo('uint64', 'Uint64', 'Uint64', 64), |
| - mojom.DOUBLE: KindInfo('float64', 'Float64', 'Float64', 64), |
| - mojom.STRING: KindInfo('string', 'String', 'String', 64), |
| - mojom.NULLABLE_STRING: KindInfo('string', 'String', 'String', 64), |
| + 'system.SharedBufferHandle', 'Handle', 'SharedBufferHandle', 32, '%sTypeHandleType{%sHandleType{Nullable: true, Kind: %sHandleType_Kind_SharedBuffer}}'), |
| + mojom.INT64: KindInfo('int64', 'Int64', 'Int64', 64, '%sTypeSimpleType{%sSimpleType_InT64}'), |
| + mojom.UINT64: KindInfo('uint64', 'Uint64', 'Uint64', 64, '%sTypeSimpleType{%sSimpleType_UinT64}'), |
| + mojom.DOUBLE: KindInfo('float64', 'Float64', 'Float64', 64, '%sTypeSimpleType{%sSimpleType_Double}'), |
| + mojom.STRING: KindInfo('string', 'String', 'String', 64, '%sTypeStringType{%sStringType{false}}'), |
| + mojom.NULLABLE_STRING: KindInfo('string', 'String', 'String', 64, '%sTypeStringType{%sStringType{true}}'), |
| } |
| _imports = {} |
| +_mojom_imports = {} |
|
mattr
2015/09/17 00:37:35
Can you explain the difference between imports and
alexfandrianto
2015/10/09 17:43:55
Added comments.
_imports contains the raw text fo
|
| + |
| +_mojom_descriptors_pkg = "mojo/public/interfaces/bindings/mojom_descriptors" |
| +_mojom_descriptors_pkg_short = "mojom_descriptors" |
| +_mojom_types_pkg = "mojo/public/interfaces/bindings/mojom_types" |
| +_mojom_types_pkg_short = "mojom_types" |
| def GetBitSize(kind): |
| if isinstance(kind, (mojom.Union)): |
| @@ -183,18 +191,42 @@ def EncodeSuffix(kind): |
| return EncodeSuffix(mojom.MSGPIPE) |
| return _kind_infos[kind].encode_suffix |
| +def GetIdentifier(kind, default): |
| + package = GetPackageNameForElement(kind, default) |
| + #print(package) |
| + #print(kind.name if hasattr(kind, 'name') else kind.spec) |
| + #return base64.b32encode(package + ':' + (kind.name if hasattr(kind, 'name') else kind.spec)).replace('=', '') |
| + # Replace all suspicious characters with _. |
| + # Remove ? since this info is captured in TypeReference. |
| + package_unique = (kind.name if hasattr(kind, 'name') else kind.spec).replace(':', '_').replace('?', '') |
| + return '%s_%s' % (package, package_unique) |
| + |
| +#def GetImportShortName(imp): |
| +# i = imp.replace('"', '') |
| +# print(i) |
| +# print(i.split('/')[-1]) |
| +# print(_imports[i] if i in _imports else '') |
| +# return _imports[i] if i in _imports else i.split('/')[-1] |
| + |
| +def GetMojomTypeValue(kind, typepkg=''): |
| + if not kind in _kind_infos: |
| + return '' |
| + if mojom.IsAnyHandleKind(kind): |
| + return _kind_infos[kind].type_template % (typepkg, typepkg, typepkg) |
| + return _kind_infos[kind].type_template % (typepkg, typepkg) |
| + |
| def GetPackageName(module): |
| return module.name.split('.')[0] |
| -def GetPackageNameForElement(element): |
| +def GetPackageNameForElement(element, default=''): |
| if not hasattr(element, 'imported_from') or not element.imported_from: |
| - return '' |
| + return default |
| path = '' |
| if element.imported_from['module'].path: |
| path += GetPackagePath(element.imported_from['module']) |
| if path in _imports: |
| return _imports[path] |
| - return '' |
| + return default |
| def GetQualifiedName(name, package=None, exported=True): |
| if not package: |
| @@ -217,6 +249,7 @@ def GetAllEnums(module): |
| # Adds an import required to use the provided |element|. |
| # The required import is stored at '_imports'. |
| +# The mojom imports are also stored separately in '_mojom_imports'. |
| def AddImport(module, element): |
| if not isinstance(element, mojom.Kind): |
| return |
| @@ -241,10 +274,27 @@ def AddImport(module, element): |
| if path in _imports: |
| return |
| name = GetPackageName(imported['module']) |
| - while name in _imports.values(): |
| + while name in _imports.values(): # This avoids repeated names. |
| name += '_' |
| _imports[path] = name |
| + _mojom_imports[path] = name |
| + |
| +def NeedsMojomDescriptor(module): |
| + return GetPackageName(module) != _mojom_descriptors_pkg_short and \ |
|
mattr
2015/09/17 00:37:36
I think you can use parens to break this line.
alexfandrianto
2015/10/09 17:43:55
I never knew about that in Python.
Ended up delet
|
| + GetPackageName(module) != _mojom_types_pkg_short |
| + |
| +identifier_cache = {} |
| +def StoreIdentifier(identifier, cache_name): |
| + if not cache_name in identifier_cache: |
| + identifier_cache[cache_name] = {} |
| + identifier_cache[cache_name][identifier] = True |
| + return '' |
| + |
| +def CheckIdentifier(identifier, cache_name): |
| + if not cache_name in identifier_cache: |
| + identifier_cache[cache_name] = {} |
| + return identifier in identifier_cache[cache_name] |
| class Generator(generator.Generator): |
| go_filters = { |
| @@ -254,6 +304,9 @@ class Generator(generator.Generator): |
| 'encode_suffix': EncodeSuffix, |
| 'go_type': GetGoType, |
| 'expression_to_text': ExpressionToText, |
| + 'identifier': GetIdentifier, |
| + 'identifier_check': CheckIdentifier, |
| + 'identifier_store': StoreIdentifier, |
| 'is_array': mojom.IsArrayKind, |
| 'is_enum': mojom.IsEnumKind, |
| 'is_handle': mojom.IsAnyHandleKind, |
| @@ -267,19 +320,25 @@ class Generator(generator.Generator): |
| 'is_struct': mojom.IsStructKind, |
| 'is_union': mojom.IsUnionKind, |
| 'qualified': GetQualifiedName, |
| + 'mojom_type': GetMojomTypeValue, |
| 'name': GetNameForElement, |
| 'package': GetPackageNameForElement, |
| 'tab_indent': lambda s, size = 1: ('\n' + '\t' * size).join(s.splitlines()) |
| } |
| def GetParameters(self): |
| + package = GetPackageName(self.module) |
| return { |
| 'enums': GetAllEnums(self.module), |
| 'imports': self.GetImports(), |
| 'interfaces': self.GetInterfaces(), |
| - 'package': GetPackageName(self.module), |
| + 'mojom_imports': self.GetMojomImports(), |
| + 'package': package, |
| 'structs': self.GetStructs(), |
| - 'unions': self.GetUnions(), |
| + 'need_mojom_desc': NeedsMojomDescriptor(self.module), |
|
mattr
2015/09/17 00:37:35
It seems odd we need this and the variable descpkg
alexfandrianto
2015/10/09 17:43:55
OLD:
Unfortunately, we needed both. The MojomDescr
|
| + 'descpkg': '%s.' % _mojom_descriptors_pkg_short if package != _mojom_descriptors_pkg_short else '', |
| + 'typepkg': '%s.' % _mojom_types_pkg_short if package != _mojom_types_pkg_short else '', |
| + 'unions': self.GetUnions() |
| } |
| @UseJinja('go_templates/source.tmpl', filters=go_filters) |
| @@ -338,6 +397,16 @@ class Generator(generator.Generator): |
| if field.value: |
| AddImport(self.module, field.value) |
| + |
| + num_user_defined_types = len(self.module.interfaces) + \ |
|
mattr
2015/09/17 00:37:35
Interfaces define types too right? The request/re
alexfandrianto
2015/10/09 17:43:55
That's right, interfaces define types as well. Sin
|
| + len(self.module.unions) + len(all_structs) + len(GetAllEnums(self.module)) |
| + if num_user_defined_types > 0 \ |
| + and GetPackageName(self.module) != _mojom_types_pkg_short: |
| + _imports[_mojom_types_pkg] = _mojom_types_pkg_short |
| + |
| + if NeedsMojomDescriptor(self.module): |
| + _imports[_mojom_descriptors_pkg] = _mojom_descriptors_pkg_short |
| + |
| # TODO(rogulenko): add these after generating constants and struct defaults. |
| # for constant in GetAllConstants(self.module): |
| # AddImport(self.module, constant.value) |
| @@ -350,6 +419,10 @@ class Generator(generator.Generator): |
| imports_list.append('%s "%s"' % (_imports[i], i)) |
| return sorted(imports_list) |
| + def GetMojomImports(self): |
| + self.GetImports() # Can call GetImports multiple times since it only sets the internal _imports map. |
| + return _mojom_imports |
| + |
| # Overrides the implementation from the base class in order to customize the |
| # struct and field names. |
| def _GetStructFromMethod(self, method): |