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.
5 """Generates JavaScript source files from a mojom.Module."""
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
12 _kind_to_javascript_default_value
= {
24 mojom
.MSGPIPE
: "null",
25 mojom
.SHAREDBUFFER
: "null",
33 def JavaScriptDefaultValue(field
):
35 if isinstance(field
.kind
, mojom
.Struct
):
36 assert field
.default
== "default"
37 return "new %s()" % JavascriptType(field
.kind
)
38 return ExpressionToText(field
.default
)
39 if field
.kind
in mojom
.PRIMITIVES
:
40 return _kind_to_javascript_default_value
[field
.kind
]
41 if isinstance(field
.kind
, mojom
.Struct
):
43 if isinstance(field
.kind
, mojom
.Array
):
45 if isinstance(field
.kind
, mojom
.Interface
) or \
46 isinstance(field
.kind
, mojom
.InterfaceRequest
):
47 return _kind_to_javascript_default_value
[mojom
.MSGPIPE
]
48 if isinstance(field
.kind
, mojom
.Enum
):
52 def JavaScriptPayloadSize(packed
):
53 packed_fields
= packed
.packed_fields
56 last_field
= packed_fields
[-1]
57 offset
= last_field
.offset
+ last_field
.size
58 pad
= pack
.GetPad(offset
, 8)
62 _kind_to_codec_type
= {
63 mojom
.BOOL
: "codec.Uint8",
64 mojom
.INT8
: "codec.Int8",
65 mojom
.UINT8
: "codec.Uint8",
66 mojom
.INT16
: "codec.Int16",
67 mojom
.UINT16
: "codec.Uint16",
68 mojom
.INT32
: "codec.Int32",
69 mojom
.UINT32
: "codec.Uint32",
70 mojom
.FLOAT
: "codec.Float",
71 mojom
.HANDLE
: "codec.Handle",
72 mojom
.DCPIPE
: "codec.Handle",
73 mojom
.DPPIPE
: "codec.Handle",
74 mojom
.MSGPIPE
: "codec.Handle",
75 mojom
.SHAREDBUFFER
: "codec.Handle",
76 mojom
.INT64
: "codec.Int64",
77 mojom
.UINT64
: "codec.Uint64",
78 mojom
.DOUBLE
: "codec.Double",
79 mojom
.STRING
: "codec.String",
84 if kind
in mojom
.PRIMITIVES
:
85 return _kind_to_codec_type
[kind
]
86 if isinstance(kind
, mojom
.Struct
):
87 return "new codec.PointerTo(%s)" % CodecType(kind
.name
)
88 if isinstance(kind
, mojom
.Array
):
89 return "new codec.ArrayOf(%s)" % CodecType(kind
.kind
)
90 if isinstance(kind
, mojom
.Interface
) or \
91 isinstance(kind
, mojom
.InterfaceRequest
):
92 return CodecType(mojom
.MSGPIPE
)
93 if isinstance(kind
, mojom
.Enum
):
94 return _kind_to_codec_type
[mojom
.INT32
]
98 def JavaScriptDecodeSnippet(kind
):
99 if kind
in mojom
.PRIMITIVES
:
100 return "decodeStruct(%s)" % CodecType(kind
)
101 if isinstance(kind
, mojom
.Struct
):
102 return "decodeStructPointer(%s)" % CodecType(kind
.name
)
103 if isinstance(kind
, mojom
.Array
):
104 return "decodeArrayPointer(%s)" % CodecType(kind
.kind
)
105 if isinstance(kind
, mojom
.Interface
) or \
106 isinstance(kind
, mojom
.InterfaceRequest
):
107 return JavaScriptDecodeSnippet(mojom
.MSGPIPE
)
108 if isinstance(kind
, mojom
.Enum
):
109 return JavaScriptDecodeSnippet(mojom
.INT32
)
112 def JavaScriptEncodeSnippet(kind
):
113 if kind
in mojom
.PRIMITIVES
:
114 return "encodeStruct(%s, " % CodecType(kind
)
115 if isinstance(kind
, mojom
.Struct
):
116 return "encodeStructPointer(%s, " % CodecType(kind
.name
)
117 if isinstance(kind
, mojom
.Array
):
118 return "encodeArrayPointer(%s, " % CodecType(kind
.kind
)
119 if isinstance(kind
, mojom
.Interface
) or \
120 isinstance(kind
, mojom
.InterfaceRequest
):
121 return JavaScriptEncodeSnippet(mojom
.MSGPIPE
)
122 if isinstance(kind
, mojom
.Enum
):
123 return JavaScriptEncodeSnippet(mojom
.INT32
)
126 def TranslateConstants(token
):
127 if isinstance(token
, (mojom
.EnumValue
, mojom
.NamedValue
)):
128 # Both variable and enum constants are constructed like:
129 # NamespaceUid.Struct[.Enum].CONSTANT_NAME
131 if token
.imported_from
:
132 name
.append(token
.imported_from
["unique_name"])
133 if token
.parent_kind
:
134 name
.append(token
.parent_kind
.name
)
135 if isinstance(token
, mojom
.EnumValue
):
136 name
.append(token
.enum_name
)
137 name
.append(token
.name
)
138 return ".".join(name
)
142 def ExpressionToText(value
):
143 return TranslateConstants(value
)
146 def JavascriptType(kind
):
147 if kind
.imported_from
:
148 return kind
.imported_from
["unique_name"] + "." + kind
.name
152 class Generator(generator
.Generator
):
155 "default_value": JavaScriptDefaultValue
,
156 "payload_size": JavaScriptPayloadSize
,
157 "decode_snippet": JavaScriptDecodeSnippet
,
158 "encode_snippet": JavaScriptEncodeSnippet
,
159 "expression_to_text": ExpressionToText
,
160 "js_type": JavascriptType
,
161 "stylize_method": generator
.StudlyCapsToCamel
,
164 @UseJinja("js_templates/module.js.tmpl", filters
=js_filters
)
165 def GenerateJsModule(self
):
167 "namespace": self
.module
.namespace
,
168 "imports": self
.GetImports(),
169 "kinds": self
.module
.kinds
,
170 "enums": self
.module
.enums
,
171 "module": self
.module
,
172 "structs": self
.GetStructs() + self
.GetStructsFromMethods(),
173 "interfaces": self
.module
.interfaces
,
176 def GenerateFiles(self
, args
):
177 self
.Write(self
.GenerateJsModule(), "%s.js" % self
.module
.name
)
179 def GetImports(self
):
180 # Since each import is assigned a variable in JS, they need to have unique
183 for each
in self
.module
.imports
:
184 each
["unique_name"] = "import" + str(counter
)
186 return self
.module
.imports