1f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)# Copyright 2013 The Chromium Authors. All rights reserved.
2f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)# Use of this source code is governed by a BSD-style license that can be
3f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)# found in the LICENSE file.
4f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
55d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)"""Generates JavaScript source files from a mojom.Module."""
6f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
70529e5d033099cbfc42635f6f6183833b09dff6eBen Murdochimport mojom.generate.generator as generator
80529e5d033099cbfc42635f6f6183833b09dff6eBen Murdochimport mojom.generate.module as mojom
90529e5d033099cbfc42635f6f6183833b09dff6eBen Murdochimport mojom.generate.pack as pack
100529e5d033099cbfc42635f6f6183833b09dff6eBen Murdochfrom mojom.generate.template_expander import UseJinja
11f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)_kind_to_javascript_default_value = {
136e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  mojom.BOOL:                  "false",
146e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  mojom.INT8:                  "0",
156e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  mojom.UINT8:                 "0",
166e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  mojom.INT16:                 "0",
176e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  mojom.UINT16:                "0",
186e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  mojom.INT32:                 "0",
196e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  mojom.UINT32:                "0",
206e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  mojom.FLOAT:                 "0",
216e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  mojom.HANDLE:                "null",
226e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  mojom.DCPIPE:                "null",
236e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  mojom.DPPIPE:                "null",
246e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  mojom.MSGPIPE:               "null",
256e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  mojom.SHAREDBUFFER:          "null",
266e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  mojom.NULLABLE_HANDLE:       "null",
276e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  mojom.NULLABLE_DCPIPE:       "null",
286e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  mojom.NULLABLE_DPPIPE:       "null",
296e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  mojom.NULLABLE_MSGPIPE:      "null",
306e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  mojom.NULLABLE_SHAREDBUFFER: "null",
316e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  mojom.INT64:                 "0",
326e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  mojom.UINT64:                "0",
336e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  mojom.DOUBLE:                "0",
341320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  mojom.STRING:                "null",
351320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  mojom.NULLABLE_STRING:       "null"
36f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
37f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
38f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
3903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)def JavaScriptType(kind):
4003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  if kind.imported_from:
4103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    return kind.imported_from["unique_name"] + "." + kind.name
4203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  return kind.name
4303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
4403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)def JavaScriptDefaultValue(field):
46f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  if field.default:
476e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    if mojom.IsStructKind(field.kind):
4846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      assert field.default == "default"
4903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      return "new %s()" % JavaScriptType(field.kind)
5046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    return ExpressionToText(field.default)
51f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  if field.kind in mojom.PRIMITIVES:
525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return _kind_to_javascript_default_value[field.kind]
536e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  if mojom.IsStructKind(field.kind):
54cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    return "null"
5503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  if mojom.IsAnyArrayKind(field.kind):
56116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    return "null"
576e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  if mojom.IsInterfaceKind(field.kind) or \
586e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)     mojom.IsInterfaceRequestKind(field.kind):
595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return _kind_to_javascript_default_value[mojom.MSGPIPE]
606e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  if mojom.IsEnumKind(field.kind):
61a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    return "0"
62f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
63f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)def JavaScriptPayloadSize(packed):
65f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  packed_fields = packed.packed_fields
66f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  if not packed_fields:
67cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    return 0
68f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  last_field = packed_fields[-1]
69f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  offset = last_field.offset + last_field.size
700529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  pad = pack.GetPad(offset, 8)
71cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  return offset + pad
72f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
73f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
745c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu_kind_to_codec_type = {
756e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  mojom.BOOL:                  "codec.Uint8",
766e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  mojom.INT8:                  "codec.Int8",
776e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  mojom.UINT8:                 "codec.Uint8",
786e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  mojom.INT16:                 "codec.Int16",
796e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  mojom.UINT16:                "codec.Uint16",
806e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  mojom.INT32:                 "codec.Int32",
816e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  mojom.UINT32:                "codec.Uint32",
826e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  mojom.FLOAT:                 "codec.Float",
836e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  mojom.HANDLE:                "codec.Handle",
846e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  mojom.DCPIPE:                "codec.Handle",
856e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  mojom.DPPIPE:                "codec.Handle",
866e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  mojom.MSGPIPE:               "codec.Handle",
876e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  mojom.SHAREDBUFFER:          "codec.Handle",
8803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  mojom.NULLABLE_HANDLE:       "codec.NullableHandle",
8903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  mojom.NULLABLE_DCPIPE:       "codec.NullableHandle",
9003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  mojom.NULLABLE_DPPIPE:       "codec.NullableHandle",
9103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  mojom.NULLABLE_MSGPIPE:      "codec.NullableHandle",
9203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  mojom.NULLABLE_SHAREDBUFFER: "codec.NullableHandle",
936e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  mojom.INT64:                 "codec.Int64",
946e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  mojom.UINT64:                "codec.Uint64",
956e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  mojom.DOUBLE:                "codec.Double",
966e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  mojom.STRING:                "codec.String",
9703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  mojom.NULLABLE_STRING:       "codec.NullableString",
98f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
99f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
100f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
1015c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liudef CodecType(kind):
102f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  if kind in mojom.PRIMITIVES:
1035c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    return _kind_to_codec_type[kind]
1046e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  if mojom.IsStructKind(kind):
10503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    pointer_type = "NullablePointerTo" if mojom.IsNullableKind(kind) \
10603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)        else "PointerTo"
10703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    return "new codec.%s(%s)" % (pointer_type, JavaScriptType(kind))
10803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  if mojom.IsAnyArrayKind(kind):
10903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    array_type = "NullableArrayOf" if mojom.IsNullableKind(kind) else "ArrayOf"
11003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    element_type = "codec.PackedBool" if mojom.IsBoolKind(kind.kind) \
11103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)        else CodecType(kind.kind)
11203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    return "new codec.%s(%s)" % (array_type, element_type)
1136e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  if mojom.IsInterfaceKind(kind) or mojom.IsInterfaceRequestKind(kind):
1145c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    return CodecType(mojom.MSGPIPE)
1156e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  if mojom.IsEnumKind(kind):
1165c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    return _kind_to_codec_type[mojom.INT32]
117f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  return kind
118f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
119f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
1205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)def JavaScriptDecodeSnippet(kind):
121f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  if kind in mojom.PRIMITIVES:
122cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    return "decodeStruct(%s)" % CodecType(kind)
1236e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  if mojom.IsStructKind(kind):
12403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    return "decodeStructPointer(%s)" % JavaScriptType(kind)
12503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  if mojom.IsAnyArrayKind(kind) and mojom.IsBoolKind(kind.kind):
12603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    return "decodeArrayPointer(codec.PackedBool)"
12703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  if mojom.IsAnyArrayKind(kind):
128cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    return "decodeArrayPointer(%s)" % CodecType(kind.kind)
1296e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  if mojom.IsInterfaceKind(kind) or mojom.IsInterfaceRequestKind(kind):
1305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return JavaScriptDecodeSnippet(mojom.MSGPIPE)
1316e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  if mojom.IsEnumKind(kind):
1325c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    return JavaScriptDecodeSnippet(mojom.INT32)
133f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
134f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
1355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)def JavaScriptEncodeSnippet(kind):
136f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  if kind in mojom.PRIMITIVES:
137cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    return "encodeStruct(%s, " % CodecType(kind)
1386e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  if mojom.IsStructKind(kind):
13903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    return "encodeStructPointer(%s, " % JavaScriptType(kind)
14003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  if mojom.IsAnyArrayKind(kind) and mojom.IsBoolKind(kind.kind):
14103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    return "encodeArrayPointer(codec.PackedBool, ";
1426e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  if mojom.IsAnyArrayKind(kind):
143cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    return "encodeArrayPointer(%s, " % CodecType(kind.kind)
1446e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  if mojom.IsInterfaceKind(kind) or mojom.IsInterfaceRequestKind(kind):
1455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return JavaScriptEncodeSnippet(mojom.MSGPIPE)
1466e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  if mojom.IsEnumKind(kind):
1475c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    return JavaScriptEncodeSnippet(mojom.INT32)
148a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
149cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
15003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)def JavaScriptFieldOffset(packed_field):
15103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  return "offset + codec.kStructHeaderSize + %s" % packed_field.offset
15203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
15303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
15403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)def JavaScriptNullableParam(packed_field):
15503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  return "true" if mojom.IsNullableKind(packed_field.field.kind) else "false"
15603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
15703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
15803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)def JavaScriptValidateArrayParams(packed_field):
15903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  nullable = JavaScriptNullableParam(packed_field)
16003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  field_offset = JavaScriptFieldOffset(packed_field)
16103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  element_kind = packed_field.field.kind.kind
16203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  element_size = pack.PackedField.GetSizeForKind(element_kind)
16303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  element_count = generator.ExpectedArraySize(packed_field.field.kind)
16403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  element_type = "codec.PackedBool" if mojom.IsBoolKind(element_kind) \
16503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      else CodecType(element_kind)
16603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  return "%s, %s, %s, %s, %s" % \
16703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      (field_offset, element_size, element_count, element_type, nullable)
16803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
16903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
17003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)def JavaScriptValidateStructParams(packed_field):
17103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  nullable = JavaScriptNullableParam(packed_field)
17203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  field_offset = JavaScriptFieldOffset(packed_field)
17303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  struct_type = JavaScriptType(packed_field.field.kind)
17403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  return "%s, %s, %s" % (field_offset, struct_type, nullable)
17503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
17603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
17703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)def JavaScriptValidateStringParams(packed_field):
17803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  nullable = JavaScriptNullableParam(packed_field)
17903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  return "%s, %s" % (JavaScriptFieldOffset(packed_field), nullable)
18003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
18103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
18203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)def JavaScriptValidateHandleParams(packed_field):
18303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  nullable = JavaScriptNullableParam(packed_field)
18403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  field_offset = JavaScriptFieldOffset(packed_field)
18503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  return "%s, %s" % (field_offset, nullable)
18603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
18703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
18846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)def TranslateConstants(token):
189cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if isinstance(token, (mojom.EnumValue, mojom.NamedValue)):
190cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    # Both variable and enum constants are constructed like:
191cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    # NamespaceUid.Struct[.Enum].CONSTANT_NAME
192a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    name = []
193a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    if token.imported_from:
194a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      name.append(token.imported_from["unique_name"])
195a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    if token.parent_kind:
196cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      name.append(token.parent_kind.name)
197cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    if isinstance(token, mojom.EnumValue):
1981320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      name.append(token.enum.name)
199cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    name.append(token.name)
200a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    return ".".join(name)
2011320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
2021320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  if isinstance(token, mojom.BuiltinValue):
2031320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    if token.value == "double.INFINITY" or token.value == "float.INFINITY":
2041320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      return "Infinity";
2051320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    if token.value == "double.NEGATIVE_INFINITY" or \
2061320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci       token.value == "float.NEGATIVE_INFINITY":
2071320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      return "-Infinity";
2081320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    if token.value == "double.NAN" or token.value == "float.NAN":
2091320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      return "NaN";
2101320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
211a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  return token
2125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
2135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
21446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)def ExpressionToText(value):
21546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  return TranslateConstants(value)
2165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
2175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
21803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)def IsArrayPointerField(field):
21903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  return mojom.IsAnyArrayKind(field.kind)
22003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
22103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)def IsStringPointerField(field):
22203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  return mojom.IsStringKind(field.kind)
22303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
22403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)def IsStructPointerField(field):
22503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  return mojom.IsStructKind(field.kind)
22603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
22703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)def IsHandleField(field):
22803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  return mojom.IsAnyHandleKind(field.kind)
2295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
2305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
2310529e5d033099cbfc42635f6f6183833b09dff6eBen Murdochclass Generator(generator.Generator):
2325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
2335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  js_filters = {
2345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    "default_value": JavaScriptDefaultValue,
2355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    "payload_size": JavaScriptPayloadSize,
2365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    "decode_snippet": JavaScriptDecodeSnippet,
2375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    "encode_snippet": JavaScriptEncodeSnippet,
2385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    "expression_to_text": ExpressionToText,
23903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    "field_offset": JavaScriptFieldOffset,
24003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    "has_callbacks": mojom.HasCallbacks,
24103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    "is_array_pointer_field": IsArrayPointerField,
24203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    "is_struct_pointer_field": IsStructPointerField,
24303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    "is_string_pointer_field": IsStringPointerField,
24403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    "is_handle_field": IsHandleField,
24503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    "js_type": JavaScriptType,
2460529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    "stylize_method": generator.StudlyCapsToCamel,
24703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    "validate_array_params": JavaScriptValidateArrayParams,
24803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    "validate_handle_params": JavaScriptValidateHandleParams,
24903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    "validate_string_params": JavaScriptValidateStringParams,
25003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    "validate_struct_params": JavaScriptValidateStructParams,
251f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
252f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
2535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  @UseJinja("js_templates/module.js.tmpl", filters=js_filters)
2545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  def GenerateJsModule(self):
255f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    return {
256f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      "namespace": self.module.namespace,
2575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      "imports": self.GetImports(),
2585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      "kinds": self.module.kinds,
2595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      "enums": self.module.enums,
2605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      "module": self.module,
261f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      "structs": self.GetStructs() + self.GetStructsFromMethods(),
262f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      "interfaces": self.module.interfaces,
263f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    }
264f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
265cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  def GenerateFiles(self, args):
2665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    self.Write(self.GenerateJsModule(), "%s.js" % self.module.name)
2675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
2685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  def GetImports(self):
2695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    # Since each import is assigned a variable in JS, they need to have unique
2705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    # names.
2715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    counter = 1
2725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    for each in self.module.imports:
2735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      each["unique_name"] = "import" + str(counter)
2745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      counter += 1
2755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return self.module.imports
276