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

Unified Diff: mojo/public/tools/bindings/generators/mojom_java_generator.py

Issue 814543006: Move //mojo/{public, edk} underneath //third_party (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Rebase Created 5 years, 11 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 side-by-side diff with in-line comments
Download patch
Index: mojo/public/tools/bindings/generators/mojom_java_generator.py
diff --git a/mojo/public/tools/bindings/generators/mojom_java_generator.py b/mojo/public/tools/bindings/generators/mojom_java_generator.py
deleted file mode 100644
index 276d5af0593b8ec9188a8549ba19432c668c7666..0000000000000000000000000000000000000000
--- a/mojo/public/tools/bindings/generators/mojom_java_generator.py
+++ /dev/null
@@ -1,531 +0,0 @@
-# Copyright 2014 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-"""Generates java source files from a mojom.Module."""
-
-import argparse
-import ast
-import contextlib
-import os
-import re
-import shutil
-import tempfile
-import zipfile
-
-from jinja2 import contextfilter
-
-import mojom.generate.generator as generator
-import mojom.generate.module as mojom
-from mojom.generate.template_expander import UseJinja
-
-
-GENERATOR_PREFIX = 'java'
-
-_HEADER_SIZE = 8
-
-_spec_to_java_type = {
- mojom.BOOL.spec: 'boolean',
- mojom.DCPIPE.spec: 'org.chromium.mojo.system.DataPipe.ConsumerHandle',
- mojom.DOUBLE.spec: 'double',
- mojom.DPPIPE.spec: 'org.chromium.mojo.system.DataPipe.ProducerHandle',
- mojom.FLOAT.spec: 'float',
- mojom.HANDLE.spec: 'org.chromium.mojo.system.UntypedHandle',
- mojom.INT16.spec: 'short',
- mojom.INT32.spec: 'int',
- mojom.INT64.spec: 'long',
- mojom.INT8.spec: 'byte',
- mojom.MSGPIPE.spec: 'org.chromium.mojo.system.MessagePipeHandle',
- mojom.NULLABLE_DCPIPE.spec:
- 'org.chromium.mojo.system.DataPipe.ConsumerHandle',
- mojom.NULLABLE_DPPIPE.spec:
- 'org.chromium.mojo.system.DataPipe.ProducerHandle',
- mojom.NULLABLE_HANDLE.spec: 'org.chromium.mojo.system.UntypedHandle',
- mojom.NULLABLE_MSGPIPE.spec: 'org.chromium.mojo.system.MessagePipeHandle',
- mojom.NULLABLE_SHAREDBUFFER.spec:
- 'org.chromium.mojo.system.SharedBufferHandle',
- mojom.NULLABLE_STRING.spec: 'String',
- mojom.SHAREDBUFFER.spec: 'org.chromium.mojo.system.SharedBufferHandle',
- mojom.STRING.spec: 'String',
- mojom.UINT16.spec: 'short',
- mojom.UINT32.spec: 'int',
- mojom.UINT64.spec: 'long',
- mojom.UINT8.spec: 'byte',
-}
-
-_spec_to_decode_method = {
- mojom.BOOL.spec: 'readBoolean',
- mojom.DCPIPE.spec: 'readConsumerHandle',
- mojom.DOUBLE.spec: 'readDouble',
- mojom.DPPIPE.spec: 'readProducerHandle',
- mojom.FLOAT.spec: 'readFloat',
- mojom.HANDLE.spec: 'readUntypedHandle',
- mojom.INT16.spec: 'readShort',
- mojom.INT32.spec: 'readInt',
- mojom.INT64.spec: 'readLong',
- mojom.INT8.spec: 'readByte',
- mojom.MSGPIPE.spec: 'readMessagePipeHandle',
- mojom.NULLABLE_DCPIPE.spec: 'readConsumerHandle',
- mojom.NULLABLE_DPPIPE.spec: 'readProducerHandle',
- mojom.NULLABLE_HANDLE.spec: 'readUntypedHandle',
- mojom.NULLABLE_MSGPIPE.spec: 'readMessagePipeHandle',
- mojom.NULLABLE_SHAREDBUFFER.spec: 'readSharedBufferHandle',
- mojom.NULLABLE_STRING.spec: 'readString',
- mojom.SHAREDBUFFER.spec: 'readSharedBufferHandle',
- mojom.STRING.spec: 'readString',
- mojom.UINT16.spec: 'readShort',
- mojom.UINT32.spec: 'readInt',
- mojom.UINT64.spec: 'readLong',
- mojom.UINT8.spec: 'readByte',
-}
-
-_java_primitive_to_boxed_type = {
- 'boolean': 'Boolean',
- 'byte': 'Byte',
- 'double': 'Double',
- 'float': 'Float',
- 'int': 'Integer',
- 'long': 'Long',
- 'short': 'Short',
-}
-
-
-def NameToComponent(name):
- # insert '_' between anything and a Title name (e.g, HTTPEntry2FooBar ->
- # HTTP_Entry2_FooBar)
- name = re.sub('([^_])([A-Z][^A-Z_]+)', r'\1_\2', name)
- # insert '_' between non upper and start of upper blocks (e.g.,
- # HTTP_Entry2_FooBar -> HTTP_Entry2_Foo_Bar)
- name = re.sub('([^A-Z_])([A-Z])', r'\1_\2', name)
- return [x.lower() for x in name.split('_')]
-
-def UpperCamelCase(name):
- return ''.join([x.capitalize() for x in NameToComponent(name)])
-
-def CamelCase(name):
- uccc = UpperCamelCase(name)
- return uccc[0].lower() + uccc[1:]
-
-def ConstantStyle(name):
- components = NameToComponent(name)
- if components[0] == 'k' and len(components) > 1:
- components = components[1:]
- # variable cannot starts with a digit.
- if components[0][0].isdigit():
- components[0] = '_' + components[0]
- return '_'.join([x.upper() for x in components])
-
-def GetNameForElement(element):
- if (mojom.IsEnumKind(element) or mojom.IsInterfaceKind(element) or
- mojom.IsStructKind(element)):
- return UpperCamelCase(element.name)
- if mojom.IsInterfaceRequestKind(element):
- return GetNameForElement(element.kind)
- if isinstance(element, (mojom.Method,
- mojom.Parameter,
- mojom.Field)):
- return CamelCase(element.name)
- if isinstance(element, mojom.EnumValue):
- return (GetNameForElement(element.enum) + '.' +
- ConstantStyle(element.name))
- if isinstance(element, (mojom.NamedValue,
- mojom.Constant,
- mojom.EnumField)):
- return ConstantStyle(element.name)
- raise Exception('Unexpected element: %s' % element)
-
-def GetInterfaceResponseName(method):
- return UpperCamelCase(method.name + 'Response')
-
-def ParseStringAttribute(attribute):
- assert isinstance(attribute, basestring)
- return attribute
-
-def GetJavaTrueFalse(value):
- return 'true' if value else 'false'
-
-def GetArrayNullabilityFlags(kind):
- """Returns nullability flags for an array type, see Decoder.java.
-
- As we have dedicated decoding functions for arrays, we have to pass
- nullability information about both the array itself, as well as the array
- element type there.
- """
- assert mojom.IsArrayKind(kind)
- ARRAY_NULLABLE = \
- 'org.chromium.mojo.bindings.BindingsHelper.ARRAY_NULLABLE'
- ELEMENT_NULLABLE = \
- 'org.chromium.mojo.bindings.BindingsHelper.ELEMENT_NULLABLE'
- NOTHING_NULLABLE = \
- 'org.chromium.mojo.bindings.BindingsHelper.NOTHING_NULLABLE'
-
- flags_to_set = []
- if mojom.IsNullableKind(kind):
- flags_to_set.append(ARRAY_NULLABLE)
- if mojom.IsNullableKind(kind.kind):
- flags_to_set.append(ELEMENT_NULLABLE)
-
- if not flags_to_set:
- flags_to_set = [NOTHING_NULLABLE]
- return ' | '.join(flags_to_set)
-
-
-def AppendEncodeDecodeParams(initial_params, context, kind, bit):
- """ Appends standard parameters shared between encode and decode calls. """
- params = list(initial_params)
- if (kind == mojom.BOOL):
- params.append(str(bit))
- if mojom.IsReferenceKind(kind):
- if mojom.IsArrayKind(kind):
- params.append(GetArrayNullabilityFlags(kind))
- else:
- params.append(GetJavaTrueFalse(mojom.IsNullableKind(kind)))
- if mojom.IsArrayKind(kind):
- params.append(GetArrayExpectedLength(kind))
- if mojom.IsInterfaceKind(kind):
- params.append('%s.MANAGER' % GetJavaType(context, kind))
- if mojom.IsArrayKind(kind) and mojom.IsInterfaceKind(kind.kind):
- params.append('%s.MANAGER' % GetJavaType(context, kind.kind))
- return params
-
-
-@contextfilter
-def DecodeMethod(context, kind, offset, bit):
- def _DecodeMethodName(kind):
- if mojom.IsArrayKind(kind):
- return _DecodeMethodName(kind.kind) + 's'
- if mojom.IsEnumKind(kind):
- return _DecodeMethodName(mojom.INT32)
- if mojom.IsInterfaceRequestKind(kind):
- return 'readInterfaceRequest'
- if mojom.IsInterfaceKind(kind):
- return 'readServiceInterface'
- return _spec_to_decode_method[kind.spec]
- methodName = _DecodeMethodName(kind)
- params = AppendEncodeDecodeParams([ str(offset) ], context, kind, bit)
- return '%s(%s)' % (methodName, ', '.join(params))
-
-@contextfilter
-def EncodeMethod(context, kind, variable, offset, bit):
- params = AppendEncodeDecodeParams(
- [ variable, str(offset) ], context, kind, bit)
- return 'encode(%s)' % ', '.join(params)
-
-def GetPackage(module):
- if 'JavaPackage' in module.attributes:
- return ParseStringAttribute(module.attributes['JavaPackage'])
- # Default package.
- if module.namespace:
- return 'org.chromium.mojom.' + module.namespace
- return 'org.chromium.mojom'
-
-def GetNameForKind(context, kind):
- def _GetNameHierachy(kind):
- hierachy = []
- if kind.parent_kind:
- hierachy = _GetNameHierachy(kind.parent_kind)
- hierachy.append(GetNameForElement(kind))
- return hierachy
-
- module = context.resolve('module')
- elements = []
- if GetPackage(module) != GetPackage(kind.module):
- elements += [GetPackage(kind.module)]
- elements += _GetNameHierachy(kind)
- return '.'.join(elements)
-
-def GetBoxedJavaType(context, kind, with_generics=True):
- unboxed_type = GetJavaType(context, kind, False, with_generics)
- if unboxed_type in _java_primitive_to_boxed_type:
- return _java_primitive_to_boxed_type[unboxed_type]
- return unboxed_type
-
-@contextfilter
-def GetJavaType(context, kind, boxed=False, with_generics=True):
- if boxed:
- return GetBoxedJavaType(context, kind)
- if mojom.IsStructKind(kind) or mojom.IsInterfaceKind(kind):
- return GetNameForKind(context, kind)
- if mojom.IsInterfaceRequestKind(kind):
- return ('org.chromium.mojo.bindings.InterfaceRequest<%s>' %
- GetNameForKind(context, kind.kind))
- if mojom.IsMapKind(kind):
- if with_generics:
- return 'java.util.Map<%s, %s>' % (
- GetBoxedJavaType(context, kind.key_kind),
- GetBoxedJavaType(context, kind.value_kind))
- else:
- return 'java.util.Map'
- if mojom.IsArrayKind(kind):
- return '%s[]' % GetJavaType(context, kind.kind, boxed, with_generics)
- if mojom.IsEnumKind(kind):
- return 'int'
- return _spec_to_java_type[kind.spec]
-
-@contextfilter
-def DefaultValue(context, field):
- assert field.default
- if isinstance(field.kind, mojom.Struct):
- assert field.default == 'default'
- return 'new %s()' % GetJavaType(context, field.kind)
- return '(%s) %s' % (
- GetJavaType(context, field.kind),
- ExpressionToText(context, field.default, kind_spec=field.kind.spec))
-
-@contextfilter
-def ConstantValue(context, constant):
- return '(%s) %s' % (
- GetJavaType(context, constant.kind),
- ExpressionToText(context, constant.value, kind_spec=constant.kind.spec))
-
-@contextfilter
-def NewArray(context, kind, size):
- if mojom.IsArrayKind(kind.kind):
- return NewArray(context, kind.kind, size) + '[]'
- return 'new %s[%s]' % (
- GetJavaType(context, kind.kind, boxed=False, with_generics=False), size)
-
-@contextfilter
-def ExpressionToText(context, token, kind_spec=''):
- def _TranslateNamedValue(named_value):
- entity_name = GetNameForElement(named_value)
- if named_value.parent_kind:
- return GetJavaType(context, named_value.parent_kind) + '.' + entity_name
- # Handle the case where named_value is a module level constant:
- if not isinstance(named_value, mojom.EnumValue):
- entity_name = (GetConstantsMainEntityName(named_value.module) + '.' +
- entity_name)
- if GetPackage(named_value.module) == GetPackage(context.resolve('module')):
- return entity_name
- return GetPackage(named_value.module) + '.' + entity_name
-
- if isinstance(token, mojom.NamedValue):
- return _TranslateNamedValue(token)
- if kind_spec.startswith('i') or kind_spec.startswith('u'):
- # Add Long suffix to all integer literals.
- number = ast.literal_eval(token.lstrip('+ '))
- if not isinstance(number, (int, long)):
- raise ValueError('got unexpected type %r for int literal %r' % (
- type(number), token))
- # If the literal is too large to fit a signed long, convert it to the
- # equivalent signed long.
- if number >= 2 ** 63:
- number -= 2 ** 64
- return '%dL' % number
- if isinstance(token, mojom.BuiltinValue):
- if token.value == 'double.INFINITY':
- return 'java.lang.Double.POSITIVE_INFINITY'
- if token.value == 'double.NEGATIVE_INFINITY':
- return 'java.lang.Double.NEGATIVE_INFINITY'
- if token.value == 'double.NAN':
- return 'java.lang.Double.NaN'
- if token.value == 'float.INFINITY':
- return 'java.lang.Float.POSITIVE_INFINITY'
- if token.value == 'float.NEGATIVE_INFINITY':
- return 'java.lang.Float.NEGATIVE_INFINITY'
- if token.value == 'float.NAN':
- return 'java.lang.Float.NaN'
- return token
-
-def GetArrayKind(kind, size = None):
- if size is None:
- return mojom.Array(kind)
- else:
- array = mojom.Array(kind, 0)
- array.java_map_size = size
- return array
-
-def GetArrayExpectedLength(kind):
- if mojom.IsArrayKind(kind) and kind.length is not None:
- return getattr(kind, 'java_map_size', str(kind.length))
- else:
- return 'org.chromium.mojo.bindings.BindingsHelper.UNSPECIFIED_ARRAY_LENGTH'
-
-def IsPointerArrayKind(kind):
- if not mojom.IsArrayKind(kind):
- return False
- sub_kind = kind.kind
- return mojom.IsObjectKind(sub_kind)
-
-def GetResponseStructFromMethod(method):
- return generator.GetDataHeader(
- False, generator.GetResponseStructFromMethod(method))
-
-def GetStructFromMethod(method):
- return generator.GetDataHeader(
- False, generator.GetStructFromMethod(method))
-
-def GetConstantsMainEntityName(module):
- if 'JavaConstantsClassName' in module.attributes:
- return ParseStringAttribute(module.attributes['JavaConstantsClassName'])
- # This constructs the name of the embedding classes for module level constants
- # by extracting the mojom's filename and prepending it to Constants.
- return (UpperCamelCase(module.path.split('/')[-1].rsplit('.', 1)[0]) +
- 'Constants')
-
-def GetMethodOrdinalName(method):
- return ConstantStyle(method.name) + '_ORDINAL'
-
-def HasMethodWithResponse(interface):
- for method in interface.methods:
- if method.response_parameters is not None:
- return True
- return False
-
-def HasMethodWithoutResponse(interface):
- for method in interface.methods:
- if method.response_parameters is None:
- return True
- return False
-
-@contextlib.contextmanager
-def TempDir():
- dirname = tempfile.mkdtemp()
- try:
- yield dirname
- finally:
- shutil.rmtree(dirname)
-
-def ZipContentInto(root, zip_filename):
- with zipfile.ZipFile(zip_filename, 'w') as zip_file:
- for dirname, _, files in os.walk(root):
- for filename in files:
- path = os.path.join(dirname, filename)
- path_in_archive = os.path.relpath(path, root)
- zip_file.write(path, path_in_archive)
-
-class Generator(generator.Generator):
-
- java_filters = {
- 'array_expected_length': GetArrayExpectedLength,
- 'array': GetArrayKind,
- 'constant_value': ConstantValue,
- 'decode_method': DecodeMethod,
- 'default_value': DefaultValue,
- 'encode_method': EncodeMethod,
- 'expression_to_text': ExpressionToText,
- 'has_method_without_response': HasMethodWithoutResponse,
- 'has_method_with_response': HasMethodWithResponse,
- 'interface_response_name': GetInterfaceResponseName,
- 'is_array_kind': mojom.IsArrayKind,
- 'is_handle': mojom.IsNonInterfaceHandleKind,
- 'is_map_kind': mojom.IsMapKind,
- 'is_nullable_kind': mojom.IsNullableKind,
- 'is_pointer_array_kind': IsPointerArrayKind,
- 'is_reference_kind': mojom.IsReferenceKind,
- 'is_struct_kind': mojom.IsStructKind,
- 'java_true_false': GetJavaTrueFalse,
- 'java_type': GetJavaType,
- 'method_ordinal_name': GetMethodOrdinalName,
- 'name': GetNameForElement,
- 'new_array': NewArray,
- 'response_struct_from_method': GetResponseStructFromMethod,
- 'struct_from_method': GetStructFromMethod,
- 'struct_size': lambda ps: ps.GetTotalSize() + _HEADER_SIZE,
- }
-
- def GetJinjaExports(self):
- return {
- 'package': GetPackage(self.module),
- }
-
- def GetJinjaExportsForInterface(self, interface):
- exports = self.GetJinjaExports()
- exports.update({'interface': interface})
- if interface.client:
- all_interfaces = [] + self.module.interfaces
- for each in self.module.imports:
- all_interfaces += each['module'].interfaces
- interfaces_by_name = dict((x.name, x) for x in all_interfaces)
- assert interface.client in interfaces_by_name, (
- 'Unable to find interface %s declared as client of %s.' %
- (interface.client, interface.name))
- exports.update({'client': interfaces_by_name[interface.client]})
- return exports
-
- @UseJinja('java_templates/enum.java.tmpl', filters=java_filters)
- def GenerateEnumSource(self, enum):
- exports = self.GetJinjaExports()
- exports.update({'enum': enum})
- return exports
-
- @UseJinja('java_templates/struct.java.tmpl', filters=java_filters)
- def GenerateStructSource(self, struct):
- exports = self.GetJinjaExports()
- exports.update({'struct': struct})
- return exports
-
- @UseJinja('java_templates/interface.java.tmpl', filters=java_filters)
- def GenerateInterfaceSource(self, interface):
- return self.GetJinjaExportsForInterface(interface)
-
- @UseJinja('java_templates/interface_internal.java.tmpl', filters=java_filters)
- def GenerateInterfaceInternalSource(self, interface):
- return self.GetJinjaExportsForInterface(interface)
-
- @UseJinja('java_templates/constants.java.tmpl', filters=java_filters)
- def GenerateConstantsSource(self, module):
- exports = self.GetJinjaExports()
- exports.update({'main_entity': GetConstantsMainEntityName(module),
- 'constants': module.constants})
- return exports
-
- def DoGenerateFiles(self):
- if not os.path.exists(self.output_dir):
- try:
- os.makedirs(self.output_dir)
- except:
- # Ignore errors on directory creation.
- pass
-
- # Keep this above the others as .GetStructs() changes the state of the
- # module, annotating structs with required information.
- for struct in self.GetStructs():
- self.Write(self.GenerateStructSource(struct),
- '%s.java' % GetNameForElement(struct))
-
- for enum in self.module.enums:
- self.Write(self.GenerateEnumSource(enum),
- '%s.java' % GetNameForElement(enum))
-
- for interface in self.module.interfaces:
- self.Write(self.GenerateInterfaceSource(interface),
- '%s.java' % GetNameForElement(interface))
- self.Write(self.GenerateInterfaceInternalSource(interface),
- '%s_Internal.java' % GetNameForElement(interface))
-
- if self.module.constants:
- self.Write(self.GenerateConstantsSource(self.module),
- '%s.java' % GetConstantsMainEntityName(self.module))
-
- def GenerateFiles(self, unparsed_args):
- parser = argparse.ArgumentParser()
- parser.add_argument('--java_output_directory', dest='java_output_directory')
- args = parser.parse_args(unparsed_args)
- package_path = GetPackage(self.module).replace('.', '/')
-
- # Generate the java files in a temporary directory and place a single
- # srcjar in the output directory.
- basename = self.MatchMojomFilePath("%s.srcjar" % self.module.name)
- zip_filename = os.path.join(self.output_dir, basename)
- with TempDir() as temp_java_root:
- self.output_dir = os.path.join(temp_java_root, package_path)
- self.DoGenerateFiles();
- ZipContentInto(temp_java_root, zip_filename)
-
- if args.java_output_directory:
- # If requested, generate the java files directly into indicated directory.
- self.output_dir = os.path.join(args.java_output_directory, package_path)
- self.DoGenerateFiles();
-
- def GetJinjaParameters(self):
- return {
- 'lstrip_blocks': True,
- 'trim_blocks': True,
- }
-
- def GetGlobals(self):
- return {
- 'namespace': self.module.namespace,
- 'module': self.module,
- }

Powered by Google App Engine
This is Rietveld 408576698