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

Side by Side Diff: mojo/public/tools/bindings/generators/mojom_js_generator.py

Issue 2250183003: Make the fuchsia mojo/public repo the source of truth. (Closed) Base URL: https://github.com/domokit/mojo.git@master
Patch Set: Created 4 years, 4 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 unified diff | Download patch
OLDNEW
(Empty)
1 # Copyright 2013 The Chromium Authors. All rights reserved.
2 # Use of this source code is governed by a BSD-style license that can be
3 # found in the LICENSE file.
4
5 """Generates JavaScript source files from a mojom.Module."""
6
7 import mojom.generate.generator as generator
8 import mojom.generate.module as mojom
9 import mojom.generate.pack as pack
10 from mojom.generate.template_expander import UseJinja
11
12 _kind_to_javascript_default_value = {
13 mojom.BOOL: "false",
14 mojom.INT8: "0",
15 mojom.UINT8: "0",
16 mojom.INT16: "0",
17 mojom.UINT16: "0",
18 mojom.INT32: "0",
19 mojom.UINT32: "0",
20 mojom.FLOAT: "0",
21 mojom.HANDLE: "null",
22 mojom.DCPIPE: "null",
23 mojom.DPPIPE: "null",
24 mojom.MSGPIPE: "null",
25 mojom.SHAREDBUFFER: "null",
26 mojom.NULLABLE_HANDLE: "null",
27 mojom.NULLABLE_DCPIPE: "null",
28 mojom.NULLABLE_DPPIPE: "null",
29 mojom.NULLABLE_MSGPIPE: "null",
30 mojom.NULLABLE_SHAREDBUFFER: "null",
31 mojom.INT64: "0",
32 mojom.UINT64: "0",
33 mojom.DOUBLE: "0",
34 mojom.STRING: "null",
35 mojom.NULLABLE_STRING: "null"
36 }
37
38
39 def JavaScriptType(kind):
40 if kind.imported_from:
41 return kind.imported_from["unique_name"] + "." + kind.name
42 return kind.name
43
44
45 def JavaScriptDefaultValue(field):
46 if field.default:
47 if mojom.IsStructKind(field.kind):
48 assert field.default == "default"
49 return "new %s()" % JavaScriptType(field.kind)
50 return ExpressionToText(field.default)
51 if field.kind in mojom.PRIMITIVES:
52 return _kind_to_javascript_default_value[field.kind]
53 if mojom.IsStructKind(field.kind):
54 return "null"
55 if mojom.IsUnionKind(field.kind):
56 return "null"
57 if mojom.IsArrayKind(field.kind):
58 return "null"
59 if mojom.IsMapKind(field.kind):
60 return "null"
61 if mojom.IsInterfaceKind(field.kind) or \
62 mojom.IsInterfaceRequestKind(field.kind):
63 return _kind_to_javascript_default_value[mojom.MSGPIPE]
64 if mojom.IsEnumKind(field.kind):
65 return "0"
66 raise Exception("No valid default: %s" % field)
67
68
69 def JavaScriptPayloadSize(packed):
70 packed_fields = packed.packed_fields
71 if not packed_fields:
72 return 0
73 last_field = packed_fields[-1]
74 offset = last_field.offset + last_field.size
75 pad = pack.GetPad(offset, 8)
76 return offset + pad
77
78
79 _kind_to_codec_type = {
80 mojom.BOOL: "codec.Uint8",
81 mojom.INT8: "codec.Int8",
82 mojom.UINT8: "codec.Uint8",
83 mojom.INT16: "codec.Int16",
84 mojom.UINT16: "codec.Uint16",
85 mojom.INT32: "codec.Int32",
86 mojom.UINT32: "codec.Uint32",
87 mojom.FLOAT: "codec.Float",
88 mojom.HANDLE: "codec.Handle",
89 mojom.DCPIPE: "codec.Handle",
90 mojom.DPPIPE: "codec.Handle",
91 mojom.MSGPIPE: "codec.Handle",
92 mojom.SHAREDBUFFER: "codec.Handle",
93 mojom.NULLABLE_HANDLE: "codec.NullableHandle",
94 mojom.NULLABLE_DCPIPE: "codec.NullableHandle",
95 mojom.NULLABLE_DPPIPE: "codec.NullableHandle",
96 mojom.NULLABLE_MSGPIPE: "codec.NullableHandle",
97 mojom.NULLABLE_SHAREDBUFFER: "codec.NullableHandle",
98 mojom.INT64: "codec.Int64",
99 mojom.UINT64: "codec.Uint64",
100 mojom.DOUBLE: "codec.Double",
101 mojom.STRING: "codec.String",
102 mojom.NULLABLE_STRING: "codec.NullableString",
103 }
104
105
106 def CodecType(kind):
107 if kind in mojom.PRIMITIVES:
108 return _kind_to_codec_type[kind]
109 if mojom.IsStructKind(kind):
110 pointer_type = "NullablePointerTo" if mojom.IsNullableKind(kind) \
111 else "PointerTo"
112 return "new codec.%s(%s)" % (pointer_type, JavaScriptType(kind))
113 if mojom.IsUnionKind(kind):
114 return JavaScriptType(kind)
115 if mojom.IsArrayKind(kind):
116 array_type = "NullableArrayOf" if mojom.IsNullableKind(kind) else "ArrayOf"
117 array_length = "" if kind.length is None else ", %d" % kind.length
118 element_type = ElementCodecType(kind.kind)
119 return "new codec.%s(%s%s)" % (array_type, element_type, array_length)
120 if mojom.IsInterfaceKind(kind):
121 return "codec.%s" % ("NullableInterface" if mojom.IsNullableKind(kind)
122 else "Interface")
123 if mojom.IsInterfaceRequestKind(kind):
124 return CodecType(mojom.MSGPIPE)
125 if mojom.IsEnumKind(kind):
126 return _kind_to_codec_type[mojom.INT32]
127 if mojom.IsMapKind(kind):
128 map_type = "NullableMapOf" if mojom.IsNullableKind(kind) else "MapOf"
129 key_type = ElementCodecType(kind.key_kind)
130 value_type = ElementCodecType(kind.value_kind)
131 return "new codec.%s(%s, %s)" % (map_type, key_type, value_type)
132 raise Exception("No codec type for %s" % kind)
133
134
135 def ElementCodecType(kind):
136 if mojom.IsUnionKind(kind):
137 wrapper_type = "NullableUnionWrapper" if mojom.IsNullableKind(kind) \
138 else "UnionWrapper"
139 return "new codec.%s(%s)" % (wrapper_type, JavaScriptType(kind))
140 return "codec.PackedBool" if mojom.IsBoolKind(kind) else CodecType(kind)
141
142 def JavaScriptDecodeSnippet(kind):
143 if kind in mojom.PRIMITIVES or mojom.IsUnionKind(kind):
144 return "decodeStruct(%s)" % CodecType(kind)
145 if mojom.IsStructKind(kind):
146 return "decodeStructPointer(%s)" % JavaScriptType(kind)
147 if mojom.IsMapKind(kind):
148 return "decodeMapPointer(%s, %s)" % \
149 (ElementCodecType(kind.key_kind), ElementCodecType(kind.value_kind))
150 if mojom.IsArrayKind(kind) and mojom.IsBoolKind(kind.kind):
151 return "decodeArrayPointer(codec.PackedBool)"
152 if mojom.IsArrayKind(kind):
153 return "decodeArrayPointer(%s)" % CodecType(kind.kind)
154 if mojom.IsInterfaceKind(kind):
155 return "decodeStruct(%s)" % CodecType(kind)
156 if mojom.IsUnionKind(kind):
157 return "decodeUnion(%s)" % CodecType(kind)
158 if mojom.IsInterfaceRequestKind(kind):
159 return JavaScriptDecodeSnippet(mojom.MSGPIPE)
160 if mojom.IsEnumKind(kind):
161 return JavaScriptDecodeSnippet(mojom.INT32)
162 raise Exception("No decode snippet for %s" % kind)
163
164
165 def JavaScriptEncodeSnippet(kind):
166 if kind in mojom.PRIMITIVES or mojom.IsUnionKind(kind):
167 return "encodeStruct(%s, " % CodecType(kind)
168 if mojom.IsUnionKind(kind):
169 return "encodeStruct(%s, " % JavaScriptType(kind)
170 if mojom.IsStructKind(kind):
171 return "encodeStructPointer(%s, " % JavaScriptType(kind)
172 if mojom.IsMapKind(kind):
173 return "encodeMapPointer(%s, %s, " % \
174 (ElementCodecType(kind.key_kind), ElementCodecType(kind.value_kind))
175 if mojom.IsArrayKind(kind) and mojom.IsBoolKind(kind.kind):
176 return "encodeArrayPointer(codec.PackedBool, ";
177 if mojom.IsArrayKind(kind):
178 return "encodeArrayPointer(%s, " % CodecType(kind.kind)
179 if mojom.IsInterfaceKind(kind):
180 return "encodeStruct(%s, " % CodecType(kind)
181 if mojom.IsInterfaceRequestKind(kind):
182 return JavaScriptEncodeSnippet(mojom.MSGPIPE)
183 if mojom.IsEnumKind(kind):
184 return JavaScriptEncodeSnippet(mojom.INT32)
185 raise Exception("No encode snippet for %s" % kind)
186
187
188 def JavaScriptUnionDecodeSnippet(kind):
189 if mojom.IsUnionKind(kind):
190 return "decodeStructPointer(%s)" % JavaScriptType(kind)
191 return JavaScriptDecodeSnippet(kind)
192
193
194 def JavaScriptUnionEncodeSnippet(kind):
195 if mojom.IsUnionKind(kind):
196 return "encodeStructPointer(%s, " % JavaScriptType(kind)
197 return JavaScriptEncodeSnippet(kind)
198
199
200 def JavaScriptFieldOffset(packed_field):
201 return "offset + codec.kStructHeaderSize + %s" % packed_field.offset
202
203
204 def JavaScriptNullableParam(field):
205 return "true" if mojom.IsNullableKind(field.kind) else "false"
206
207
208 def GetArrayExpectedDimensionSizes(kind):
209 expected_dimension_sizes = []
210 while mojom.IsArrayKind(kind):
211 expected_dimension_sizes.append(generator.ExpectedArraySize(kind) or 0)
212 kind = kind.kind
213 # Strings are serialized as variable-length arrays.
214 if (mojom.IsStringKind(kind)):
215 expected_dimension_sizes.append(0)
216 return expected_dimension_sizes
217
218
219 def JavaScriptValidateArrayParams(field):
220 nullable = JavaScriptNullableParam(field)
221 element_kind = field.kind.kind
222 element_size = pack.PackedField.GetSizeForKind(element_kind)
223 expected_dimension_sizes = GetArrayExpectedDimensionSizes(
224 field.kind)
225 element_type = ElementCodecType(element_kind)
226 return "%s, %s, %s, %s, 0" % \
227 (element_size, element_type, nullable,
228 expected_dimension_sizes)
229
230
231 def JavaScriptValidateStructParams(field):
232 nullable = JavaScriptNullableParam(field)
233 struct_type = JavaScriptType(field.kind)
234 return "%s, %s" % (struct_type, nullable)
235
236 def JavaScriptValidateUnionParams(field):
237 nullable = JavaScriptNullableParam(field)
238 union_type = JavaScriptType(field.kind)
239 return "%s, %s" % (union_type, nullable)
240
241 def JavaScriptValidateMapParams(field):
242 nullable = JavaScriptNullableParam(field)
243 keys_type = ElementCodecType(field.kind.key_kind)
244 values_kind = field.kind.value_kind;
245 values_type = ElementCodecType(values_kind)
246 values_nullable = "true" if mojom.IsNullableKind(values_kind) else "false"
247 return "%s, %s, %s, %s" % \
248 (nullable, keys_type, values_type, values_nullable)
249
250
251 def JavaScriptValidateStringParams(field):
252 nullable = JavaScriptNullableParam(field)
253 return "%s" % (nullable)
254
255
256 def JavaScriptValidateHandleParams(field):
257 nullable = JavaScriptNullableParam(field)
258 return "%s" % (nullable)
259
260 def JavaScriptValidateInterfaceParams(field):
261 return JavaScriptValidateHandleParams(field)
262
263 def JavaScriptProxyMethodParameterValue(parameter):
264 name = parameter.name;
265 if (mojom.IsInterfaceKind(parameter.kind)):
266 type = JavaScriptType(parameter.kind)
267 return "core.isHandle(%s) ? %s : connection.bindImpl" \
268 "(%s, %s)" % (name, name, name, type)
269 if (mojom.IsInterfaceRequestKind(parameter.kind)):
270 type = JavaScriptType(parameter.kind.kind)
271 return "core.isHandle(%s) ? %s : connection.bindProxy" \
272 "(%s, %s)" % (name, name, name, type)
273 return name;
274
275
276 def JavaScriptStubMethodParameterValue(parameter):
277 name = parameter.name;
278 if (mojom.IsInterfaceKind(parameter.kind)):
279 type = JavaScriptType(parameter.kind)
280 return "connection.bindHandleToProxy(%s, %s)" % (name, type)
281 if (mojom.IsInterfaceRequestKind(parameter.kind)):
282 type = JavaScriptType(parameter.kind.kind)
283 return "connection.bindHandleToStub(%s, %s)" % (name, type)
284 return name;
285
286
287 def TranslateConstants(token):
288 if isinstance(token, (mojom.EnumValue, mojom.NamedValue)):
289 # Both variable and enum constants are constructed like:
290 # NamespaceUid.Struct[.Enum].CONSTANT_NAME
291 name = []
292 if token.imported_from:
293 name.append(token.imported_from["unique_name"])
294 if token.parent_kind:
295 name.append(token.parent_kind.name)
296 if isinstance(token, mojom.EnumValue):
297 name.append(token.enum.name)
298 name.append(token.name)
299 return ".".join(name)
300
301 if isinstance(token, mojom.BuiltinValue):
302 if token.value == "double.INFINITY" or token.value == "float.INFINITY":
303 return "Infinity";
304 if token.value == "double.NEGATIVE_INFINITY" or \
305 token.value == "float.NEGATIVE_INFINITY":
306 return "-Infinity";
307 if token.value == "double.NAN" or token.value == "float.NAN":
308 return "NaN";
309
310 return token
311
312
313 def ExpressionToText(value):
314 return TranslateConstants(value)
315
316 def IsArrayPointerField(field):
317 return mojom.IsArrayKind(field.kind)
318
319 def IsStringPointerField(field):
320 return mojom.IsStringKind(field.kind)
321
322 def IsStructPointerField(field):
323 return mojom.IsStructKind(field.kind)
324
325 def IsMapPointerField(field):
326 return mojom.IsMapKind(field.kind)
327
328 def IsHandleField(field):
329 return mojom.IsAnyHandleKind(field.kind)
330
331 def IsInterfaceField(field):
332 return mojom.IsInterfaceKind(field.kind)
333
334 def IsUnionField(field):
335 return mojom.IsUnionKind(field.kind)
336
337
338 class Generator(generator.Generator):
339
340 js_filters = {
341 "default_value": JavaScriptDefaultValue,
342 "payload_size": JavaScriptPayloadSize,
343 "decode_snippet": JavaScriptDecodeSnippet,
344 "encode_snippet": JavaScriptEncodeSnippet,
345 "union_decode_snippet": JavaScriptUnionDecodeSnippet,
346 "union_encode_snippet": JavaScriptUnionEncodeSnippet,
347 "expression_to_text": ExpressionToText,
348 "field_offset": JavaScriptFieldOffset,
349 "has_callbacks": mojom.HasCallbacks,
350 "is_array_pointer_field": IsArrayPointerField,
351 "is_map_pointer_field": IsMapPointerField,
352 "is_struct_pointer_field": IsStructPointerField,
353 "is_string_pointer_field": IsStringPointerField,
354 "is_union_field": IsUnionField,
355 "is_handle_field": IsHandleField,
356 "is_interface_field": IsInterfaceField,
357 "js_type": JavaScriptType,
358 "js_proxy_method_parameter_value": JavaScriptProxyMethodParameterValue,
359 "js_stub_method_parameter_value": JavaScriptStubMethodParameterValue,
360 "stylize_method": generator.StudlyCapsToCamel,
361 "validate_array_params": JavaScriptValidateArrayParams,
362 "validate_handle_params": JavaScriptValidateHandleParams,
363 "validate_interface_params": JavaScriptValidateInterfaceParams,
364 "validate_map_params": JavaScriptValidateMapParams,
365 "validate_string_params": JavaScriptValidateStringParams,
366 "validate_struct_params": JavaScriptValidateStructParams,
367 "validate_union_params": JavaScriptValidateUnionParams,
368 }
369
370 def GetParameters(self):
371 return {
372 "namespace": self.module.namespace,
373 "imports": self.GetImports(),
374 "kinds": self.module.kinds,
375 "enums": self.module.enums,
376 "module": self.module,
377 "structs": self.GetStructs() + self.GetStructsFromMethods(),
378 "unions": self.GetUnions(),
379 "interfaces": self.GetInterfaces(),
380 "imported_interfaces": self.GetImportedInterfaces(),
381 }
382
383 @UseJinja("js_templates/module.amd.tmpl", filters=js_filters)
384 def GenerateAMDModule(self):
385 return self.GetParameters()
386
387 def GenerateFiles(self, args):
388 self.Write(self.GenerateAMDModule(),
389 self.MatchMojomFilePath("%s.js" % self.module.name))
390
391 def GetImports(self):
392 used_names = set()
393 for each_import in self.module.transitive_imports:
394 simple_name = each_import["module_name"].split(".")[0]
395
396 # Since each import is assigned a variable in JS, they need to have unique
397 # names.
398 unique_name = simple_name
399 counter = 0
400 while unique_name in used_names:
401 counter += 1
402 unique_name = simple_name + str(counter)
403
404 used_names.add(unique_name)
405 each_import["unique_name"] = unique_name + "$"
406 counter += 1
407 return self.module.imports
408
409 def GetImportedInterfaces(self):
410 interface_to_import = {};
411 for each_import in self.module.transitive_imports:
412 for each_interface in each_import["module"].interfaces:
413 name = each_interface.name
414 interface_to_import[name] = each_import["unique_name"] + "." + name
415 return interface_to_import;
416
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698