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 os | 8 import os |
9 import re | 9 import re |
10 | 10 |
11 from jinja2 import contextfilter | 11 from jinja2 import contextfilter |
12 | 12 |
13 import mojom.generate.generator as generator | 13 import mojom.generate.generator as generator |
14 import mojom.generate.module as mojom | 14 import mojom.generate.module as mojom |
15 from mojom.generate.template_expander import UseJinja | 15 from mojom.generate.template_expander import UseJinja |
16 | 16 |
17 | 17 |
18 GENERATOR_PREFIX = 'java' | 18 GENERATOR_PREFIX = 'java' |
19 | 19 |
| 20 _HEADER_SIZE = 8 |
| 21 |
20 _spec_to_java_type = { | 22 _spec_to_java_type = { |
21 'b': 'boolean', | 23 'b': 'boolean', |
22 'd': 'double', | 24 'd': 'double', |
23 'f': 'float', | 25 'f': 'float', |
24 'h:d:c': 'org.chromium.mojo.system.DataPipe.ConsumerHandle', | 26 'h:d:c': 'org.chromium.mojo.system.DataPipe.ConsumerHandle', |
25 'h:d:p': 'org.chromium.mojo.system.DataPipe.ProducerHandle', | 27 'h:d:p': 'org.chromium.mojo.system.DataPipe.ProducerHandle', |
26 'h:m': 'org.chromium.mojo.system.MessagePipeHandle', | 28 'h:m': 'org.chromium.mojo.system.MessagePipeHandle', |
27 'h': 'org.chromium.mojo.system.UntypedHandle', | 29 'h': 'org.chromium.mojo.system.UntypedHandle', |
28 'h:s': 'org.chromium.mojo.system.SharedBufferHandle', | 30 'h:s': 'org.chromium.mojo.system.SharedBufferHandle', |
29 'i16': 'short', | 31 'i16': 'short', |
30 'i32': 'int', | 32 'i32': 'int', |
31 'i64': 'long', | 33 'i64': 'long', |
32 'i8': 'byte', | 34 'i8': 'byte', |
33 's': 'String', | 35 's': 'String', |
34 'u16': 'short', | 36 'u16': 'short', |
35 'u32': 'int', | 37 'u32': 'int', |
36 'u64': 'long', | 38 'u64': 'long', |
37 'u8': 'byte', | 39 'u8': 'byte', |
38 } | 40 } |
39 | 41 |
| 42 _spec_to_decode_method = { |
| 43 'b': 'readBoolean', |
| 44 'd': 'readDouble', |
| 45 'f': 'readFloat', |
| 46 'h:d:c': 'readConsumerHandle', |
| 47 'h:d:p': 'readProducerHandle', |
| 48 'h:m': 'readMessagePipeHandle', |
| 49 'h': 'readUntypedHandle', |
| 50 'h:s': 'readSharedBufferHandle', |
| 51 'i16': 'readShort', |
| 52 'i32': 'readInt', |
| 53 'i64': 'readLong', |
| 54 'i8': 'readByte', |
| 55 's': 'readString', |
| 56 'u16': 'readShort', |
| 57 'u32': 'readInt', |
| 58 'u64': 'readLong', |
| 59 'u8': 'readByte', |
| 60 } |
| 61 |
40 _java_primitive_to_boxed_type = { | 62 _java_primitive_to_boxed_type = { |
41 'boolean': 'Boolean', | 63 'boolean': 'Boolean', |
42 'byte': 'Byte', | 64 'byte': 'Byte', |
43 'double': 'Double', | 65 'double': 'Double', |
44 'float': 'Float', | 66 'float': 'Float', |
45 'int': 'Integer', | 67 'int': 'Integer', |
46 'long': 'Long', | 68 'long': 'Long', |
47 'short': 'Short', | 69 'short': 'Short', |
48 } | 70 } |
49 | 71 |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
92 return ConstantStyle(element.name) | 114 return ConstantStyle(element.name) |
93 raise Exception("Unexpected element: " % element) | 115 raise Exception("Unexpected element: " % element) |
94 | 116 |
95 def GetInterfaceResponseName(method): | 117 def GetInterfaceResponseName(method): |
96 return UpperCamelCase(method.name + 'Response') | 118 return UpperCamelCase(method.name + 'Response') |
97 | 119 |
98 def ParseStringAttribute(attribute): | 120 def ParseStringAttribute(attribute): |
99 assert isinstance(attribute, basestring) | 121 assert isinstance(attribute, basestring) |
100 return attribute | 122 return attribute |
101 | 123 |
| 124 def IsArray(kind): |
| 125 return isinstance(kind, (mojom.Array, mojom.FixedArray)) |
| 126 |
| 127 @contextfilter |
| 128 def DecodeMethod(context, kind, offset, bit): |
| 129 def _DecodeMethodName(kind): |
| 130 if IsArray(kind): |
| 131 return _DecodeMethodName(kind.kind) + 's' |
| 132 if isinstance(kind, mojom.Enum): |
| 133 return _DecodeMethodName(mojom.INT32) |
| 134 if isinstance(kind, mojom.InterfaceRequest): |
| 135 return "readInterfaceRequest" |
| 136 if isinstance(kind, mojom.Interface): |
| 137 return "readServiceInterface" |
| 138 return _spec_to_decode_method[kind.spec] |
| 139 methodName = _DecodeMethodName(kind) |
| 140 additionalParams = '' |
| 141 if (kind == mojom.BOOL): |
| 142 additionalParams = ', %d' % bit |
| 143 if isinstance(kind, mojom.Interface): |
| 144 additionalParams = ', %s.BUILDER' % GetJavaType(context, kind) |
| 145 if IsArray(kind) and isinstance(kind.kind, mojom.Interface): |
| 146 additionalParams = ', %s.BUILDER' % GetJavaType(context, kind.kind) |
| 147 return '%s(%s%s)' % (methodName, offset, additionalParams) |
| 148 |
| 149 @contextfilter |
| 150 def EncodeMethod(context, kind, variable, offset, bit): |
| 151 additionalParams = '' |
| 152 if (kind == mojom.BOOL): |
| 153 additionalParams = ', %d' % bit |
| 154 if isinstance(kind, mojom.Interface): |
| 155 additionalParams = ', %s.BUILDER' % GetJavaType(context, kind) |
| 156 if IsArray(kind) and isinstance(kind.kind, mojom.Interface): |
| 157 additionalParams = ', %s.BUILDER' % GetJavaType(context, kind.kind) |
| 158 return 'encode(%s, %s%s)' % (variable, offset, additionalParams) |
| 159 |
102 def GetPackage(module): | 160 def GetPackage(module): |
103 if 'JavaPackage' in module.attributes: | 161 if 'JavaPackage' in module.attributes: |
104 return ParseStringAttribute(module.attributes['JavaPackage']) | 162 return ParseStringAttribute(module.attributes['JavaPackage']) |
105 # Default package. | 163 # Default package. |
106 return "org.chromium.mojom." + module.namespace | 164 return "org.chromium.mojom." + module.namespace |
107 | 165 |
108 def GetNameForKind(context, kind): | 166 def GetNameForKind(context, kind): |
109 def _GetNameHierachy(kind): | 167 def _GetNameHierachy(kind): |
110 hierachy = [] | 168 hierachy = [] |
111 if kind.parent_kind: | 169 if kind.parent_kind: |
(...skipping 16 matching lines...) Expand all Loading... |
128 | 186 |
129 @contextfilter | 187 @contextfilter |
130 def GetJavaType(context, kind, boxed=False): | 188 def GetJavaType(context, kind, boxed=False): |
131 if boxed: | 189 if boxed: |
132 return GetBoxedJavaType(context, kind) | 190 return GetBoxedJavaType(context, kind) |
133 if isinstance(kind, (mojom.Struct, mojom.Interface)): | 191 if isinstance(kind, (mojom.Struct, mojom.Interface)): |
134 return GetNameForKind(context, kind) | 192 return GetNameForKind(context, kind) |
135 if isinstance(kind, mojom.InterfaceRequest): | 193 if isinstance(kind, mojom.InterfaceRequest): |
136 return ("org.chromium.mojo.bindings.InterfaceRequest<%s>" % | 194 return ("org.chromium.mojo.bindings.InterfaceRequest<%s>" % |
137 GetNameForKind(context, kind.kind)) | 195 GetNameForKind(context, kind.kind)) |
138 if isinstance(kind, (mojom.Array, mojom.FixedArray)): | 196 if IsArray(kind): |
139 return "%s[]" % GetJavaType(context, kind.kind) | 197 return "%s[]" % GetJavaType(context, kind.kind) |
140 if isinstance(kind, mojom.Enum): | 198 if isinstance(kind, mojom.Enum): |
141 return "int" | 199 return "int" |
142 return _spec_to_java_type[kind.spec] | 200 return _spec_to_java_type[kind.spec] |
143 | 201 |
144 def IsHandle(kind): | 202 def IsHandle(kind): |
145 return kind.spec[0] == 'h' | 203 return kind.spec[0] == 'h' |
146 | 204 |
147 @contextfilter | 205 @contextfilter |
148 def DefaultValue(context, field): | 206 def DefaultValue(context, field): |
149 assert field.default | 207 assert field.default |
150 if isinstance(field.kind, mojom.Struct): | 208 if isinstance(field.kind, mojom.Struct): |
151 assert field.default == "default" | 209 assert field.default == "default" |
152 return "new %s()" % GetJavaType(context, field.kind) | 210 return "new %s()" % GetJavaType(context, field.kind) |
153 return "(%s) %s" % (GetJavaType(context, field.kind), | 211 return "(%s) %s" % (GetJavaType(context, field.kind), |
154 ExpressionToText(context, field.default)) | 212 ExpressionToText(context, field.default)) |
155 | 213 |
156 @contextfilter | 214 @contextfilter |
| 215 def NewArray(context, kind, size): |
| 216 if IsArray(kind.kind): |
| 217 return NewArray(context, kind.kind, size) + '[]' |
| 218 return 'new %s[%s]' % (GetJavaType(context, kind.kind), size) |
| 219 |
| 220 @contextfilter |
157 def ExpressionToText(context, token): | 221 def ExpressionToText(context, token): |
158 def _TranslateNamedValue(named_value): | 222 def _TranslateNamedValue(named_value): |
159 entity_name = GetNameForElement(named_value) | 223 entity_name = GetNameForElement(named_value) |
160 if named_value.parent_kind: | 224 if named_value.parent_kind: |
161 return GetJavaType(context, named_value.parent_kind) + '.' + entity_name | 225 return GetJavaType(context, named_value.parent_kind) + '.' + entity_name |
162 # Handle the case where named_value is a module level constant: | 226 # Handle the case where named_value is a module level constant: |
163 if not isinstance(named_value, mojom.EnumValue): | 227 if not isinstance(named_value, mojom.EnumValue): |
164 entity_name = (GetConstantsMainEntityName(named_value.module) + '.' + | 228 entity_name = (GetConstantsMainEntityName(named_value.module) + '.' + |
165 entity_name) | 229 entity_name) |
166 if GetPackage(named_value.module) == GetPackage(context.resolve('module')): | 230 if GetPackage(named_value.module) == GetPackage(context.resolve('module')): |
167 return entity_name | 231 return entity_name |
168 return GetPackage(named_value.module) + '.' + entity_name | 232 return GetPackage(named_value.module) + '.' + entity_name |
169 | 233 |
170 if isinstance(token, mojom.NamedValue): | 234 if isinstance(token, mojom.NamedValue): |
171 return _TranslateNamedValue(token) | 235 return _TranslateNamedValue(token) |
172 # Add Long suffix to all number literals. | 236 # Add Long suffix to all number literals. |
173 if re.match('^[0-9]+$', token): | 237 if re.match('^[0-9]+$', token): |
174 return token + 'L' | 238 return token + 'L' |
175 return token | 239 return token |
176 | 240 |
| 241 def IsPointerArrayKind(kind): |
| 242 if not IsArray(kind): |
| 243 return False |
| 244 sub_kind = kind.kind |
| 245 return generator.IsObjectKind(sub_kind) |
| 246 |
177 def GetConstantsMainEntityName(module): | 247 def GetConstantsMainEntityName(module): |
178 if 'JavaConstantsClassName' in module.attributes: | 248 if 'JavaConstantsClassName' in module.attributes: |
179 return ParseStringAttribute(module.attributes['JavaConstantsClassName']) | 249 return ParseStringAttribute(module.attributes['JavaConstantsClassName']) |
180 # This constructs the name of the embedding classes for module level constants | 250 # This constructs the name of the embedding classes for module level constants |
181 # by extracting the mojom's filename and prepending it to Constants. | 251 # by extracting the mojom's filename and prepending it to Constants. |
182 return (UpperCamelCase(module.path.split('/')[-1].rsplit('.', 1)[0]) + | 252 return (UpperCamelCase(module.path.split('/')[-1].rsplit('.', 1)[0]) + |
183 'Constants') | 253 'Constants') |
184 | 254 |
185 class Generator(generator.Generator): | 255 class Generator(generator.Generator): |
186 | 256 |
187 java_filters = { | 257 java_filters = { |
188 "interface_response_name": GetInterfaceResponseName, | 258 "interface_response_name": GetInterfaceResponseName, |
189 "default_value": DefaultValue, | 259 "default_value": DefaultValue, |
| 260 "decode_method": DecodeMethod, |
190 "expression_to_text": ExpressionToText, | 261 "expression_to_text": ExpressionToText, |
| 262 "encode_method": EncodeMethod, |
191 "is_handle": IsHandle, | 263 "is_handle": IsHandle, |
| 264 "is_pointer_array_kind": IsPointerArrayKind, |
| 265 "is_struct_kind": lambda kind: isinstance(kind, mojom.Struct), |
192 "java_type": GetJavaType, | 266 "java_type": GetJavaType, |
193 "name": GetNameForElement, | 267 "name": GetNameForElement, |
| 268 "new_array": NewArray, |
| 269 "struct_size": lambda ps: ps.GetTotalSize() + _HEADER_SIZE, |
194 } | 270 } |
195 | 271 |
196 def GetJinjaExports(self): | 272 def GetJinjaExports(self): |
197 return { | 273 return { |
198 "module": self.module, | 274 "module": self.module, |
199 "package": GetPackage(self.module), | 275 "package": GetPackage(self.module), |
200 } | 276 } |
201 | 277 |
202 @UseJinja("java_templates/enum.java.tmpl", filters=java_filters) | 278 @UseJinja("java_templates/enum.java.tmpl", filters=java_filters) |
203 def GenerateEnumSource(self, enum): | 279 def GenerateEnumSource(self, enum): |
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
261 def GetJinjaParameters(self): | 337 def GetJinjaParameters(self): |
262 return { | 338 return { |
263 'lstrip_blocks': True, | 339 'lstrip_blocks': True, |
264 'trim_blocks': True, | 340 'trim_blocks': True, |
265 } | 341 } |
266 | 342 |
267 def GetGlobals(self): | 343 def GetGlobals(self): |
268 return { | 344 return { |
269 'module': self.module, | 345 'module': self.module, |
270 } | 346 } |
OLD | NEW |