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) or | |
144 (IsArray(kind) and | |
145 isinstance(kind.kind, mojom.Interface))): | |
146 interfaceKind = kind | |
147 if IsArray(kind): | |
148 interfaceKind = kind.kind | |
149 additionalParams = ', %s.BUILDER' % GetJavaType(context, interfaceKind) | |
rmcilroy
2014/06/25 13:14:40
I think this would be clearer as:
if isinstance(
qsr
2014/06/25 14:43:06
Done.
| |
150 return '%s(%s%s)' % (methodName, offset, additionalParams) | |
151 | |
152 @contextfilter | |
153 def EncodeMethod(context, kind, variable, offset, bit): | |
154 additionalParams = '' | |
155 if (kind == mojom.BOOL): | |
156 additionalParams = ', %d' % bit | |
157 if (isinstance(kind, mojom.Interface) or | |
158 (IsArray(kind) and | |
159 isinstance(kind.kind, mojom.Interface))): | |
160 interfaceKind = kind | |
161 if IsArray(kind): | |
162 interfaceKind = kind.kind | |
163 additionalParams = ', %s.BUILDER' % GetJavaType(context, interfaceKind) | |
rmcilroy
2014/06/25 13:14:40
ditto
qsr
2014/06/25 14:43:06
Done.
| |
164 return 'encode(%s, %s%s)' % (variable, offset, additionalParams) | |
165 | |
102 def GetPackage(module): | 166 def GetPackage(module): |
103 if 'JavaPackage' in module.attributes: | 167 if 'JavaPackage' in module.attributes: |
104 return ParseStringAttribute(module.attributes['JavaPackage']) | 168 return ParseStringAttribute(module.attributes['JavaPackage']) |
105 # Default package. | 169 # Default package. |
106 return "org.chromium.mojom." + module.namespace | 170 return "org.chromium.mojom." + module.namespace |
107 | 171 |
108 def GetNameForKind(context, kind): | 172 def GetNameForKind(context, kind): |
109 def _GetNameHierachy(kind): | 173 def _GetNameHierachy(kind): |
110 hierachy = [] | 174 hierachy = [] |
111 if kind.parent_kind: | 175 if kind.parent_kind: |
(...skipping 16 matching lines...) Expand all Loading... | |
128 | 192 |
129 @contextfilter | 193 @contextfilter |
130 def GetJavaType(context, kind, boxed=False): | 194 def GetJavaType(context, kind, boxed=False): |
131 if boxed: | 195 if boxed: |
132 return GetBoxedJavaType(context, kind) | 196 return GetBoxedJavaType(context, kind) |
133 if isinstance(kind, (mojom.Struct, mojom.Interface)): | 197 if isinstance(kind, (mojom.Struct, mojom.Interface)): |
134 return GetNameForKind(context, kind) | 198 return GetNameForKind(context, kind) |
135 if isinstance(kind, mojom.InterfaceRequest): | 199 if isinstance(kind, mojom.InterfaceRequest): |
136 return ("org.chromium.mojo.bindings.InterfaceRequest<%s>" % | 200 return ("org.chromium.mojo.bindings.InterfaceRequest<%s>" % |
137 GetNameForKind(context, kind.kind)) | 201 GetNameForKind(context, kind.kind)) |
138 if isinstance(kind, (mojom.Array, mojom.FixedArray)): | 202 if IsArray(kind): |
139 return "%s[]" % GetJavaType(context, kind.kind) | 203 return "%s[]" % GetJavaType(context, kind.kind) |
140 if isinstance(kind, mojom.Enum): | 204 if isinstance(kind, mojom.Enum): |
141 return "int" | 205 return "int" |
142 return _spec_to_java_type[kind.spec] | 206 return _spec_to_java_type[kind.spec] |
143 | 207 |
144 def IsHandle(kind): | 208 def IsHandle(kind): |
145 return kind.spec[0] == 'h' | 209 return kind.spec[0] == 'h' |
146 | 210 |
147 @contextfilter | 211 @contextfilter |
148 def DefaultValue(context, field): | 212 def DefaultValue(context, field): |
149 assert field.default | 213 assert field.default |
150 if isinstance(field.kind, mojom.Struct): | 214 if isinstance(field.kind, mojom.Struct): |
151 assert field.default == "default" | 215 assert field.default == "default" |
152 return "new %s()" % GetJavaType(context, field.kind) | 216 return "new %s()" % GetJavaType(context, field.kind) |
153 return "(%s) %s" % (GetJavaType(context, field.kind), | 217 return "(%s) %s" % (GetJavaType(context, field.kind), |
154 ExpressionToText(context, field.default)) | 218 ExpressionToText(context, field.default)) |
155 | 219 |
156 @contextfilter | 220 @contextfilter |
221 def NewArray(context, kind, size): | |
222 if IsArray(kind.kind): | |
223 return NewArray(context, kind.kind, size) + '[]' | |
224 return 'new %s[%s]' % (GetJavaType(context, kind.kind), size) | |
225 | |
226 @contextfilter | |
157 def ExpressionToText(context, token): | 227 def ExpressionToText(context, token): |
158 def _TranslateNamedValue(named_value): | 228 def _TranslateNamedValue(named_value): |
159 entity_name = GetNameForElement(named_value) | 229 entity_name = GetNameForElement(named_value) |
160 if named_value.parent_kind: | 230 if named_value.parent_kind: |
161 return GetJavaType(context, named_value.parent_kind) + '.' + entity_name | 231 return GetJavaType(context, named_value.parent_kind) + '.' + entity_name |
162 # Handle the case where named_value is a module level constant: | 232 # Handle the case where named_value is a module level constant: |
163 if not isinstance(named_value, mojom.EnumValue): | 233 if not isinstance(named_value, mojom.EnumValue): |
164 entity_name = (GetConstantsMainEntityName(named_value.module) + '.' + | 234 entity_name = (GetConstantsMainEntityName(named_value.module) + '.' + |
165 entity_name) | 235 entity_name) |
166 if GetPackage(named_value.module) == GetPackage(context.resolve('module')): | 236 if GetPackage(named_value.module) == GetPackage(context.resolve('module')): |
167 return entity_name | 237 return entity_name |
168 return GetPackage(named_value.module) + '.' + entity_name | 238 return GetPackage(named_value.module) + '.' + entity_name |
169 | 239 |
170 if isinstance(token, mojom.NamedValue): | 240 if isinstance(token, mojom.NamedValue): |
171 return _TranslateNamedValue(token) | 241 return _TranslateNamedValue(token) |
172 # Add Long suffix to all number literals. | 242 # Add Long suffix to all number literals. |
173 if re.match('^[0-9]+$', token): | 243 if re.match('^[0-9]+$', token): |
174 return token + 'L' | 244 return token + 'L' |
175 return token | 245 return token |
176 | 246 |
247 def IsPointerArrayKind(kind): | |
248 if not IsArray(kind): | |
249 return False | |
250 sub_kind = kind.kind | |
251 return generator.IsObjectKind(sub_kind) | |
252 | |
177 def GetConstantsMainEntityName(module): | 253 def GetConstantsMainEntityName(module): |
178 if 'JavaConstantsClassName' in module.attributes: | 254 if 'JavaConstantsClassName' in module.attributes: |
179 return ParseStringAttribute(module.attributes['JavaConstantsClassName']) | 255 return ParseStringAttribute(module.attributes['JavaConstantsClassName']) |
180 # This constructs the name of the embedding classes for module level constants | 256 # This constructs the name of the embedding classes for module level constants |
181 # by extracting the mojom's filename and prepending it to Constants. | 257 # by extracting the mojom's filename and prepending it to Constants. |
182 return (UpperCamelCase(module.path.split('/')[-1].rsplit('.', 1)[0]) + | 258 return (UpperCamelCase(module.path.split('/')[-1].rsplit('.', 1)[0]) + |
183 'Constants') | 259 'Constants') |
184 | 260 |
185 class Generator(generator.Generator): | 261 class Generator(generator.Generator): |
186 | 262 |
187 java_filters = { | 263 java_filters = { |
188 "interface_response_name": GetInterfaceResponseName, | 264 "interface_response_name": GetInterfaceResponseName, |
189 "default_value": DefaultValue, | 265 "default_value": DefaultValue, |
266 "decode_method": DecodeMethod, | |
190 "expression_to_text": ExpressionToText, | 267 "expression_to_text": ExpressionToText, |
268 "encode_method": EncodeMethod, | |
191 "is_handle": IsHandle, | 269 "is_handle": IsHandle, |
270 "is_pointer_array_kind": IsPointerArrayKind, | |
271 "is_struct_kind": lambda kind: isinstance(kind, mojom.Struct), | |
192 "java_type": GetJavaType, | 272 "java_type": GetJavaType, |
193 "name": GetNameForElement, | 273 "name": GetNameForElement, |
274 "new_array": NewArray, | |
275 "struct_size": lambda ps: ps.GetTotalSize() + _HEADER_SIZE, | |
194 } | 276 } |
195 | 277 |
196 def GetJinjaExports(self): | 278 def GetJinjaExports(self): |
197 return { | 279 return { |
198 "module": self.module, | 280 "module": self.module, |
199 "package": GetPackage(self.module), | 281 "package": GetPackage(self.module), |
200 } | 282 } |
201 | 283 |
202 @UseJinja("java_templates/enum.java.tmpl", filters=java_filters) | 284 @UseJinja("java_templates/enum.java.tmpl", filters=java_filters) |
203 def GenerateEnumSource(self, enum): | 285 def GenerateEnumSource(self, enum): |
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
261 def GetJinjaParameters(self): | 343 def GetJinjaParameters(self): |
262 return { | 344 return { |
263 'lstrip_blocks': True, | 345 'lstrip_blocks': True, |
264 'trim_blocks': True, | 346 'trim_blocks': True, |
265 } | 347 } |
266 | 348 |
267 def GetGlobals(self): | 349 def GetGlobals(self): |
268 return { | 350 return { |
269 'module': self.module, | 351 'module': self.module, |
270 } | 352 } |
OLD | NEW |