| OLD | NEW |
| 1 # Copyright 2014 The Chromium Authors. All rights reserved. | 1 # Copyright 2014 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 java source files from a mojom.Module.""" | 5 """Generates java source files from a mojom.Module.""" |
| 6 | 6 |
| 7 import argparse | 7 import argparse |
| 8 import ast | 8 import ast |
| 9 import os | 9 import os |
| 10 import re | 10 import re |
| 11 | 11 |
| 12 from jinja2 import contextfilter | 12 from jinja2 import contextfilter |
| 13 | 13 |
| 14 import mojom.generate.generator as generator | 14 import mojom.generate.generator as generator |
| 15 import mojom.generate.module as mojom | 15 import mojom.generate.module as mojom |
| 16 from mojom.generate.template_expander import UseJinja | 16 from mojom.generate.template_expander import UseJinja |
| 17 | 17 |
| 18 | 18 |
| 19 GENERATOR_PREFIX = 'java' | 19 GENERATOR_PREFIX = 'java' |
| 20 | 20 |
| 21 _HEADER_SIZE = 8 | 21 _HEADER_SIZE = 8 |
| 22 | 22 |
| 23 _spec_to_java_type = { | 23 _spec_to_java_type = { |
| 24 'b': 'boolean', | 24 mojom.BOOL.spec: 'boolean', |
| 25 'd': 'double', | 25 mojom.DCPIPE.spec: 'org.chromium.mojo.system.DataPipe.ConsumerHandle', |
| 26 'f': 'float', | 26 mojom.DOUBLE.spec: 'double', |
| 27 'h:d:c': 'org.chromium.mojo.system.DataPipe.ConsumerHandle', | 27 mojom.DPPIPE.spec: 'org.chromium.mojo.system.DataPipe.ProducerHandle', |
| 28 'h:d:p': 'org.chromium.mojo.system.DataPipe.ProducerHandle', | 28 mojom.FLOAT.spec: 'float', |
| 29 'h:m': 'org.chromium.mojo.system.MessagePipeHandle', | 29 mojom.HANDLE.spec: 'org.chromium.mojo.system.UntypedHandle', |
| 30 'h': 'org.chromium.mojo.system.UntypedHandle', | 30 mojom.INT16.spec: 'short', |
| 31 'h:s': 'org.chromium.mojo.system.SharedBufferHandle', | 31 mojom.INT32.spec: 'int', |
| 32 'i16': 'short', | 32 mojom.INT64.spec: 'long', |
| 33 'i32': 'int', | 33 mojom.INT8.spec: 'byte', |
| 34 'i64': 'long', | 34 mojom.MSGPIPE.spec: 'org.chromium.mojo.system.MessagePipeHandle', |
| 35 'i8': 'byte', | 35 mojom.NULLABLE_DCPIPE.spec: |
| 36 's': 'String', | 36 'org.chromium.mojo.system.DataPipe.ConsumerHandle', |
| 37 'u16': 'short', | 37 mojom.NULLABLE_DPPIPE.spec: |
| 38 'u32': 'int', | 38 'org.chromium.mojo.system.DataPipe.ProducerHandle', |
| 39 'u64': 'long', | 39 mojom.NULLABLE_HANDLE.spec: 'org.chromium.mojo.system.UntypedHandle', |
| 40 'u8': 'byte', | 40 mojom.NULLABLE_MSGPIPE.spec: 'org.chromium.mojo.system.MessagePipeHandle', |
| 41 mojom.NULLABLE_SHAREDBUFFER.spec: |
| 42 'org.chromium.mojo.system.SharedBufferHandle', |
| 43 mojom.NULLABLE_STRING.spec: 'String', |
| 44 mojom.SHAREDBUFFER.spec: 'org.chromium.mojo.system.SharedBufferHandle', |
| 45 mojom.STRING.spec: 'String', |
| 46 mojom.UINT16.spec: 'short', |
| 47 mojom.UINT32.spec: 'int', |
| 48 mojom.UINT64.spec: 'long', |
| 49 mojom.UINT8.spec: 'byte', |
| 41 } | 50 } |
| 42 | 51 |
| 43 _spec_to_decode_method = { | 52 _spec_to_decode_method = { |
| 44 'b': 'readBoolean', | 53 mojom.BOOL.spec: 'readBoolean', |
| 45 'd': 'readDouble', | 54 mojom.DCPIPE.spec: 'readConsumerHandle', |
| 46 'f': 'readFloat', | 55 mojom.DOUBLE.spec: 'readDouble', |
| 47 'h:d:c': 'readConsumerHandle', | 56 mojom.DPPIPE.spec: 'readProducerHandle', |
| 48 'h:d:p': 'readProducerHandle', | 57 mojom.FLOAT.spec: 'readFloat', |
| 49 'h:m': 'readMessagePipeHandle', | 58 mojom.HANDLE.spec: 'readUntypedHandle', |
| 50 'h': 'readUntypedHandle', | 59 mojom.INT16.spec: 'readShort', |
| 51 'h:s': 'readSharedBufferHandle', | 60 mojom.INT32.spec: 'readInt', |
| 52 'i16': 'readShort', | 61 mojom.INT64.spec: 'readLong', |
| 53 'i32': 'readInt', | 62 mojom.INT8.spec: 'readByte', |
| 54 'i64': 'readLong', | 63 mojom.MSGPIPE.spec: 'readMessagePipeHandle', |
| 55 'i8': 'readByte', | 64 mojom.NULLABLE_DCPIPE.spec: 'readConsumerHandle', |
| 56 's': 'readString', | 65 mojom.NULLABLE_DPPIPE.spec: 'readProducerHandle', |
| 57 'u16': 'readShort', | 66 mojom.NULLABLE_HANDLE.spec: 'readUntypedHandle', |
| 58 'u32': 'readInt', | 67 mojom.NULLABLE_MSGPIPE.spec: 'readMessagePipeHandle', |
| 59 'u64': 'readLong', | 68 mojom.NULLABLE_SHAREDBUFFER.spec: 'readSharedBufferHandle', |
| 60 'u8': 'readByte', | 69 mojom.NULLABLE_STRING.spec: 'readString', |
| 70 mojom.SHAREDBUFFER.spec: 'readSharedBufferHandle', |
| 71 mojom.STRING.spec: 'readString', |
| 72 mojom.UINT16.spec: 'readShort', |
| 73 mojom.UINT32.spec: 'readInt', |
| 74 mojom.UINT64.spec: 'readLong', |
| 75 mojom.UINT8.spec: 'readByte', |
| 61 } | 76 } |
| 62 | 77 |
| 63 _java_primitive_to_boxed_type = { | 78 _java_primitive_to_boxed_type = { |
| 64 'boolean': 'Boolean', | 79 'boolean': 'Boolean', |
| 65 'byte': 'Byte', | 80 'byte': 'Byte', |
| 66 'double': 'Double', | 81 'double': 'Double', |
| 67 'float': 'Float', | 82 'float': 'Float', |
| 68 'int': 'Integer', | 83 'int': 'Integer', |
| 69 'long': 'Long', | 84 'long': 'Long', |
| 70 'short': 'Short', | 85 'short': 'Short', |
| (...skipping 19 matching lines...) Expand all Loading... |
| 90 uccc = UpperCamelCase(name) | 105 uccc = UpperCamelCase(name) |
| 91 return uccc[0].lower() + uccc[1:] | 106 return uccc[0].lower() + uccc[1:] |
| 92 | 107 |
| 93 def ConstantStyle(name): | 108 def ConstantStyle(name): |
| 94 components = NameToComponent(name) | 109 components = NameToComponent(name) |
| 95 if components[0] == 'k': | 110 if components[0] == 'k': |
| 96 components = components[1:] | 111 components = components[1:] |
| 97 return '_'.join([x.upper() for x in components]) | 112 return '_'.join([x.upper() for x in components]) |
| 98 | 113 |
| 99 def GetNameForElement(element): | 114 def GetNameForElement(element): |
| 100 if isinstance(element, (mojom.Enum, | 115 if (mojom.IsEnumKind(element) or mojom.IsInterfaceKind(element) or |
| 101 mojom.Interface, | 116 mojom.IsStructKind(element)): |
| 102 mojom.Struct)): | |
| 103 return UpperCamelCase(element.name) | 117 return UpperCamelCase(element.name) |
| 104 if isinstance(element, mojom.InterfaceRequest): | 118 if mojom.IsInterfaceRequestKind(element): |
| 105 return GetNameForElement(element.kind) | 119 return GetNameForElement(element.kind) |
| 106 if isinstance(element, (mojom.Method, | 120 if isinstance(element, (mojom.Method, |
| 107 mojom.Parameter, | 121 mojom.Parameter, |
| 108 mojom.Field)): | 122 mojom.Field)): |
| 109 return CamelCase(element.name) | 123 return CamelCase(element.name) |
| 110 if isinstance(element, mojom.EnumValue): | 124 if isinstance(element, mojom.EnumValue): |
| 111 return (UpperCamelCase(element.enum_name) + '.' + | 125 return (UpperCamelCase(element.enum_name) + '.' + |
| 112 ConstantStyle(element.name)) | 126 ConstantStyle(element.name)) |
| 113 if isinstance(element, (mojom.NamedValue, | 127 if isinstance(element, (mojom.NamedValue, |
| 114 mojom.Constant)): | 128 mojom.Constant)): |
| 115 return ConstantStyle(element.name) | 129 return ConstantStyle(element.name) |
| 116 raise Exception("Unexpected element: " % element) | 130 raise Exception("Unexpected element: " % element) |
| 117 | 131 |
| 118 def GetInterfaceResponseName(method): | 132 def GetInterfaceResponseName(method): |
| 119 return UpperCamelCase(method.name + 'Response') | 133 return UpperCamelCase(method.name + 'Response') |
| 120 | 134 |
| 121 def ParseStringAttribute(attribute): | 135 def ParseStringAttribute(attribute): |
| 122 assert isinstance(attribute, basestring) | 136 assert isinstance(attribute, basestring) |
| 123 return attribute | 137 return attribute |
| 124 | 138 |
| 125 def IsArray(kind): | |
| 126 return isinstance(kind, (mojom.Array, mojom.FixedArray)) | |
| 127 | |
| 128 @contextfilter | 139 @contextfilter |
| 129 def DecodeMethod(context, kind, offset, bit): | 140 def DecodeMethod(context, kind, offset, bit): |
| 130 def _DecodeMethodName(kind): | 141 def _DecodeMethodName(kind): |
| 131 if IsArray(kind): | 142 if mojom.IsAnyArrayKind(kind): |
| 132 return _DecodeMethodName(kind.kind) + 's' | 143 return _DecodeMethodName(kind.kind) + 's' |
| 133 if isinstance(kind, mojom.Enum): | 144 if mojom.IsEnumKind(kind): |
| 134 return _DecodeMethodName(mojom.INT32) | 145 return _DecodeMethodName(mojom.INT32) |
| 135 if isinstance(kind, mojom.InterfaceRequest): | 146 if mojom.IsInterfaceRequestKind(kind): |
| 136 return "readInterfaceRequest" | 147 return "readInterfaceRequest" |
| 137 if isinstance(kind, mojom.Interface): | 148 if mojom.IsInterfaceKind(kind): |
| 138 return "readServiceInterface" | 149 return "readServiceInterface" |
| 139 return _spec_to_decode_method[kind.spec] | 150 return _spec_to_decode_method[kind.spec] |
| 140 methodName = _DecodeMethodName(kind) | 151 methodName = _DecodeMethodName(kind) |
| 141 additionalParams = '' | 152 additionalParams = '' |
| 142 if (kind == mojom.BOOL): | 153 if (kind == mojom.BOOL): |
| 143 additionalParams = ', %d' % bit | 154 additionalParams = ', %d' % bit |
| 144 if isinstance(kind, mojom.Interface): | 155 if mojom.IsInterfaceKind(kind): |
| 145 additionalParams = ', %s.BUILDER' % GetJavaType(context, kind) | 156 additionalParams = ', %s.BUILDER' % GetJavaType(context, kind) |
| 146 if IsArray(kind) and isinstance(kind.kind, mojom.Interface): | 157 if mojom.IsAnyArrayKind(kind) and mojom.IsInterfaceKind(kind.kind): |
| 147 additionalParams = ', %s.BUILDER' % GetJavaType(context, kind.kind) | 158 additionalParams = ', %s.BUILDER' % GetJavaType(context, kind.kind) |
| 148 return '%s(%s%s)' % (methodName, offset, additionalParams) | 159 return '%s(%s%s)' % (methodName, offset, additionalParams) |
| 149 | 160 |
| 150 @contextfilter | 161 @contextfilter |
| 151 def EncodeMethod(context, kind, variable, offset, bit): | 162 def EncodeMethod(context, kind, variable, offset, bit): |
| 152 additionalParams = '' | 163 additionalParams = '' |
| 153 if (kind == mojom.BOOL): | 164 if (kind == mojom.BOOL): |
| 154 additionalParams = ', %d' % bit | 165 additionalParams = ', %d' % bit |
| 155 if isinstance(kind, mojom.Interface): | 166 if mojom.IsInterfaceKind(kind): |
| 156 additionalParams = ', %s.BUILDER' % GetJavaType(context, kind) | 167 additionalParams = ', %s.BUILDER' % GetJavaType(context, kind) |
| 157 if IsArray(kind) and isinstance(kind.kind, mojom.Interface): | 168 if mojom.IsAnyArrayKind(kind) and mojom.IsInterfaceKind(kind.kind): |
| 158 additionalParams = ', %s.BUILDER' % GetJavaType(context, kind.kind) | 169 additionalParams = ', %s.BUILDER' % GetJavaType(context, kind.kind) |
| 159 return 'encode(%s, %s%s)' % (variable, offset, additionalParams) | 170 return 'encode(%s, %s%s)' % (variable, offset, additionalParams) |
| 160 | 171 |
| 161 def GetPackage(module): | 172 def GetPackage(module): |
| 162 if 'JavaPackage' in module.attributes: | 173 if 'JavaPackage' in module.attributes: |
| 163 return ParseStringAttribute(module.attributes['JavaPackage']) | 174 return ParseStringAttribute(module.attributes['JavaPackage']) |
| 164 # Default package. | 175 # Default package. |
| 165 return "org.chromium.mojom." + module.namespace | 176 return "org.chromium.mojom." + module.namespace |
| 166 | 177 |
| 167 def GetNameForKind(context, kind): | 178 def GetNameForKind(context, kind): |
| (...skipping 14 matching lines...) Expand all Loading... |
| 182 def GetBoxedJavaType(context, kind): | 193 def GetBoxedJavaType(context, kind): |
| 183 unboxed_type = GetJavaType(context, kind, False) | 194 unboxed_type = GetJavaType(context, kind, False) |
| 184 if unboxed_type in _java_primitive_to_boxed_type: | 195 if unboxed_type in _java_primitive_to_boxed_type: |
| 185 return _java_primitive_to_boxed_type[unboxed_type] | 196 return _java_primitive_to_boxed_type[unboxed_type] |
| 186 return unboxed_type | 197 return unboxed_type |
| 187 | 198 |
| 188 @contextfilter | 199 @contextfilter |
| 189 def GetJavaType(context, kind, boxed=False): | 200 def GetJavaType(context, kind, boxed=False): |
| 190 if boxed: | 201 if boxed: |
| 191 return GetBoxedJavaType(context, kind) | 202 return GetBoxedJavaType(context, kind) |
| 192 if isinstance(kind, (mojom.Struct, mojom.Interface)): | 203 if mojom.IsStructKind(kind) or mojom.IsInterfaceKind(kind): |
| 193 return GetNameForKind(context, kind) | 204 return GetNameForKind(context, kind) |
| 194 if isinstance(kind, mojom.InterfaceRequest): | 205 if mojom.IsInterfaceRequestKind(kind): |
| 195 return ("org.chromium.mojo.bindings.InterfaceRequest<%s>" % | 206 return ("org.chromium.mojo.bindings.InterfaceRequest<%s>" % |
| 196 GetNameForKind(context, kind.kind)) | 207 GetNameForKind(context, kind.kind)) |
| 197 if IsArray(kind): | 208 if mojom.IsAnyArrayKind(kind): |
| 198 return "%s[]" % GetJavaType(context, kind.kind) | 209 return "%s[]" % GetJavaType(context, kind.kind) |
| 199 if isinstance(kind, mojom.Enum): | 210 if mojom.IsEnumKind(kind): |
| 200 return "int" | 211 return "int" |
| 201 return _spec_to_java_type[kind.spec] | 212 return _spec_to_java_type[kind.spec] |
| 202 | 213 |
| 203 def IsHandle(kind): | 214 def IsHandle(kind): |
| 204 return kind.spec[0] == 'h' | 215 return kind.spec[0] == 'h' |
| 205 | 216 |
| 206 @contextfilter | 217 @contextfilter |
| 207 def DefaultValue(context, field): | 218 def DefaultValue(context, field): |
| 208 assert field.default | 219 assert field.default |
| 209 if isinstance(field.kind, mojom.Struct): | 220 if isinstance(field.kind, mojom.Struct): |
| 210 assert field.default == "default" | 221 assert field.default == "default" |
| 211 return "new %s()" % GetJavaType(context, field.kind) | 222 return "new %s()" % GetJavaType(context, field.kind) |
| 212 return "(%s) %s" % ( | 223 return "(%s) %s" % ( |
| 213 GetJavaType(context, field.kind), | 224 GetJavaType(context, field.kind), |
| 214 ExpressionToText(context, field.default, kind_spec=field.kind.spec)) | 225 ExpressionToText(context, field.default, kind_spec=field.kind.spec)) |
| 215 | 226 |
| 216 @contextfilter | 227 @contextfilter |
| 217 def ConstantValue(context, constant): | 228 def ConstantValue(context, constant): |
| 218 return "(%s) %s" % ( | 229 return "(%s) %s" % ( |
| 219 GetJavaType(context, constant.kind), | 230 GetJavaType(context, constant.kind), |
| 220 ExpressionToText(context, constant.value, kind_spec=constant.kind.spec)) | 231 ExpressionToText(context, constant.value, kind_spec=constant.kind.spec)) |
| 221 | 232 |
| 222 @contextfilter | 233 @contextfilter |
| 223 def NewArray(context, kind, size): | 234 def NewArray(context, kind, size): |
| 224 if IsArray(kind.kind): | 235 if mojom.IsAnyArrayKind(kind.kind): |
| 225 return NewArray(context, kind.kind, size) + '[]' | 236 return NewArray(context, kind.kind, size) + '[]' |
| 226 return 'new %s[%s]' % (GetJavaType(context, kind.kind), size) | 237 return 'new %s[%s]' % (GetJavaType(context, kind.kind), size) |
| 227 | 238 |
| 228 @contextfilter | 239 @contextfilter |
| 229 def ExpressionToText(context, token, kind_spec=''): | 240 def ExpressionToText(context, token, kind_spec=''): |
| 230 def _TranslateNamedValue(named_value): | 241 def _TranslateNamedValue(named_value): |
| 231 entity_name = GetNameForElement(named_value) | 242 entity_name = GetNameForElement(named_value) |
| 232 if named_value.parent_kind: | 243 if named_value.parent_kind: |
| 233 return GetJavaType(context, named_value.parent_kind) + '.' + entity_name | 244 return GetJavaType(context, named_value.parent_kind) + '.' + entity_name |
| 234 # Handle the case where named_value is a module level constant: | 245 # Handle the case where named_value is a module level constant: |
| (...skipping 13 matching lines...) Expand all Loading... |
| 248 raise ValueError('got unexpected type %r for int literal %r' % ( | 259 raise ValueError('got unexpected type %r for int literal %r' % ( |
| 249 type(number), token)) | 260 type(number), token)) |
| 250 # If the literal is too large to fit a signed long, convert it to the | 261 # If the literal is too large to fit a signed long, convert it to the |
| 251 # equivalent signed long. | 262 # equivalent signed long. |
| 252 if number >= 2 ** 63: | 263 if number >= 2 ** 63: |
| 253 number -= 2 ** 64 | 264 number -= 2 ** 64 |
| 254 return '%dL' % number | 265 return '%dL' % number |
| 255 return token | 266 return token |
| 256 | 267 |
| 257 def IsPointerArrayKind(kind): | 268 def IsPointerArrayKind(kind): |
| 258 if not IsArray(kind): | 269 if not mojom.IsAnyArrayKind(kind): |
| 259 return False | 270 return False |
| 260 sub_kind = kind.kind | 271 sub_kind = kind.kind |
| 261 return generator.IsObjectKind(sub_kind) | 272 return mojom.IsObjectKind(sub_kind) |
| 262 | 273 |
| 263 def GetConstantsMainEntityName(module): | 274 def GetConstantsMainEntityName(module): |
| 264 if 'JavaConstantsClassName' in module.attributes: | 275 if 'JavaConstantsClassName' in module.attributes: |
| 265 return ParseStringAttribute(module.attributes['JavaConstantsClassName']) | 276 return ParseStringAttribute(module.attributes['JavaConstantsClassName']) |
| 266 # This constructs the name of the embedding classes for module level constants | 277 # This constructs the name of the embedding classes for module level constants |
| 267 # by extracting the mojom's filename and prepending it to Constants. | 278 # by extracting the mojom's filename and prepending it to Constants. |
| 268 return (UpperCamelCase(module.path.split('/')[-1].rsplit('.', 1)[0]) + | 279 return (UpperCamelCase(module.path.split('/')[-1].rsplit('.', 1)[0]) + |
| 269 'Constants') | 280 'Constants') |
| 270 | 281 |
| 271 class Generator(generator.Generator): | 282 class Generator(generator.Generator): |
| 272 | 283 |
| 273 java_filters = { | 284 java_filters = { |
| 274 "interface_response_name": GetInterfaceResponseName, | 285 "interface_response_name": GetInterfaceResponseName, |
| 275 "constant_value": ConstantValue, | 286 "constant_value": ConstantValue, |
| 276 "default_value": DefaultValue, | 287 "default_value": DefaultValue, |
| 277 "decode_method": DecodeMethod, | 288 "decode_method": DecodeMethod, |
| 278 "expression_to_text": ExpressionToText, | 289 "expression_to_text": ExpressionToText, |
| 279 "encode_method": EncodeMethod, | 290 "encode_method": EncodeMethod, |
| 280 "is_handle": IsHandle, | 291 "is_handle": mojom.IsAnyHandleKind, |
| 281 "is_pointer_array_kind": IsPointerArrayKind, | 292 "is_pointer_array_kind": IsPointerArrayKind, |
| 282 "is_struct_kind": lambda kind: isinstance(kind, mojom.Struct), | 293 "is_struct_kind": mojom.IsStructKind, |
| 283 "java_type": GetJavaType, | 294 "java_type": GetJavaType, |
| 284 "name": GetNameForElement, | 295 "name": GetNameForElement, |
| 285 "new_array": NewArray, | 296 "new_array": NewArray, |
| 286 "struct_size": lambda ps: ps.GetTotalSize() + _HEADER_SIZE, | 297 "struct_size": lambda ps: ps.GetTotalSize() + _HEADER_SIZE, |
| 287 } | 298 } |
| 288 | 299 |
| 289 def GetJinjaExports(self): | 300 def GetJinjaExports(self): |
| 290 return { | 301 return { |
| 291 "module": self.module, | 302 "module": self.module, |
| 292 "package": GetPackage(self.module), | 303 "package": GetPackage(self.module), |
| (...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 354 def GetJinjaParameters(self): | 365 def GetJinjaParameters(self): |
| 355 return { | 366 return { |
| 356 'lstrip_blocks': True, | 367 'lstrip_blocks': True, |
| 357 'trim_blocks': True, | 368 'trim_blocks': True, |
| 358 } | 369 } |
| 359 | 370 |
| 360 def GetGlobals(self): | 371 def GetGlobals(self): |
| 361 return { | 372 return { |
| 362 'module': self.module, | 373 'module': self.module, |
| 363 } | 374 } |
| OLD | NEW |