• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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
7import mojom.generate.generator as generator
8import mojom.generate.module as mojom
9import mojom.generate.pack as pack
10import os
11import urllib
12from mojom.generate.template_expander import UseJinja
13
14_kind_to_javascript_default_value = {
15  mojom.BOOL:                  "false",
16  mojom.INT8:                  "0",
17  mojom.UINT8:                 "0",
18  mojom.INT16:                 "0",
19  mojom.UINT16:                "0",
20  mojom.INT32:                 "0",
21  mojom.UINT32:                "0",
22  mojom.FLOAT:                 "0",
23  mojom.HANDLE:                "null",
24  mojom.DCPIPE:                "null",
25  mojom.DPPIPE:                "null",
26  mojom.MSGPIPE:               "null",
27  mojom.SHAREDBUFFER:          "null",
28  mojom.NULLABLE_HANDLE:       "null",
29  mojom.NULLABLE_DCPIPE:       "null",
30  mojom.NULLABLE_DPPIPE:       "null",
31  mojom.NULLABLE_MSGPIPE:      "null",
32  mojom.NULLABLE_SHAREDBUFFER: "null",
33  mojom.INT64:                 "0",
34  mojom.UINT64:                "0",
35  mojom.DOUBLE:                "0",
36  mojom.STRING:                "null",
37  mojom.NULLABLE_STRING:       "null"
38}
39
40_kind_to_codec_type = {
41  mojom.BOOL:                  "codec.Uint8",
42  mojom.INT8:                  "codec.Int8",
43  mojom.UINT8:                 "codec.Uint8",
44  mojom.INT16:                 "codec.Int16",
45  mojom.UINT16:                "codec.Uint16",
46  mojom.INT32:                 "codec.Int32",
47  mojom.UINT32:                "codec.Uint32",
48  mojom.FLOAT:                 "codec.Float",
49  mojom.HANDLE:                "codec.Handle",
50  mojom.DCPIPE:                "codec.Handle",
51  mojom.DPPIPE:                "codec.Handle",
52  mojom.MSGPIPE:               "codec.Handle",
53  mojom.SHAREDBUFFER:          "codec.Handle",
54  mojom.NULLABLE_HANDLE:       "codec.NullableHandle",
55  mojom.NULLABLE_DCPIPE:       "codec.NullableHandle",
56  mojom.NULLABLE_DPPIPE:       "codec.NullableHandle",
57  mojom.NULLABLE_MSGPIPE:      "codec.NullableHandle",
58  mojom.NULLABLE_SHAREDBUFFER: "codec.NullableHandle",
59  mojom.INT64:                 "codec.Int64",
60  mojom.UINT64:                "codec.Uint64",
61  mojom.DOUBLE:                "codec.Double",
62  mojom.STRING:                "codec.String",
63  mojom.NULLABLE_STRING:       "codec.NullableString",
64}
65
66_kind_to_closure_type = {
67  mojom.BOOL:                  "boolean",
68  mojom.INT8:                  "number",
69  mojom.UINT8:                 "number",
70  mojom.INT16:                 "number",
71  mojom.UINT16:                "number",
72  mojom.INT32:                 "number",
73  mojom.UINT32:                "number",
74  mojom.FLOAT:                 "number",
75  mojom.INT64:                 "number",
76  mojom.UINT64:                "number",
77  mojom.DOUBLE:                "number",
78  mojom.STRING:                "string",
79  mojom.NULLABLE_STRING:       "string",
80  mojom.HANDLE:                "mojo.MojoHandle",
81  mojom.DCPIPE:                "mojo.MojoHandle",
82  mojom.DPPIPE:                "mojo.MojoHandle",
83  mojom.MSGPIPE:               "mojo.MojoHandle",
84  mojom.SHAREDBUFFER:          "mojo.MojoHandle",
85  mojom.NULLABLE_HANDLE:       "mojo.MojoHandle",
86  mojom.NULLABLE_DCPIPE:       "mojo.MojoHandle",
87  mojom.NULLABLE_DPPIPE:       "mojo.MojoHandle",
88  mojom.NULLABLE_MSGPIPE:      "mojo.MojoHandle",
89  mojom.NULLABLE_SHAREDBUFFER: "mojo.MojoHandle",
90}
91
92_js_reserved_keywords = [
93    'arguments',
94    'await',
95    'break'
96    'case',
97    'catch',
98    'class',
99    'const',
100    'continue',
101    'debugger',
102    'default',
103    'delete',
104    'do',
105    'else',
106    'enum',
107    'export',
108    'extends',
109    'finally',
110    'for',
111    'function',
112    'if',
113    'implements',
114    'import',
115    'in',
116    'instanceof',
117    'interface',
118    'let',
119    'new',
120    'package',
121    'private',
122    'protected',
123    'public',
124    'return',
125    'static',
126    'super',
127    'switch',
128    'this',
129    'throw',
130    'try',
131    'typeof',
132    'var',
133    'void',
134    'while',
135    'with',
136    'yield',
137]
138
139_primitive_kind_to_fuzz_type = {
140  mojom.BOOL:                  "Bool",
141  mojom.INT8:                  "Int8",
142  mojom.UINT8:                 "Uint8",
143  mojom.INT16:                 "Int16",
144  mojom.UINT16:                "Uint16",
145  mojom.INT32:                 "Int32",
146  mojom.UINT32:                "Uint32",
147  mojom.FLOAT:                 "Float",
148  mojom.INT64:                 "Int64",
149  mojom.UINT64:                "Uint64",
150  mojom.DOUBLE:                "Double",
151  mojom.STRING:                "String",
152  mojom.NULLABLE_STRING:       "String",
153  mojom.HANDLE:                "Handle",
154  mojom.DCPIPE:                "DataPipeConsumer",
155  mojom.DPPIPE:                "DataPipeProducer",
156  mojom.MSGPIPE:               "MessagePipe",
157  mojom.SHAREDBUFFER:          "SharedBuffer",
158  mojom.NULLABLE_HANDLE:       "Handle",
159  mojom.NULLABLE_DCPIPE:       "DataPipeConsumer",
160  mojom.NULLABLE_DPPIPE:       "DataPipeProducer",
161  mojom.NULLABLE_MSGPIPE:      "MessagePipe",
162  mojom.NULLABLE_SHAREDBUFFER: "SharedBuffer",
163}
164
165
166def JavaScriptPayloadSize(packed):
167  packed_fields = packed.packed_fields
168  if not packed_fields:
169    return 0
170  last_field = packed_fields[-1]
171  offset = last_field.offset + last_field.size
172  pad = pack.GetPad(offset, 8)
173  return offset + pad
174
175
176def JavaScriptFieldOffset(packed_field):
177  return "offset + codec.kStructHeaderSize + %s" % packed_field.offset
178
179
180def GetArrayExpectedDimensionSizes(kind):
181  expected_dimension_sizes = []
182  while mojom.IsArrayKind(kind):
183    expected_dimension_sizes.append(generator.ExpectedArraySize(kind) or 0)
184    kind = kind.kind
185  # Strings are serialized as variable-length arrays.
186  if (mojom.IsStringKind(kind)):
187    expected_dimension_sizes.append(0)
188  return expected_dimension_sizes
189
190
191def GetRelativeUrl(module, base_module):
192  return urllib.pathname2url(
193      os.path.relpath(module.path, os.path.dirname(base_module.path)))
194
195
196class JavaScriptStylizer(generator.Stylizer):
197  def StylizeConstant(self, mojom_name):
198    return mojom_name
199
200  def StylizeField(self, mojom_name):
201    return generator.ToCamel(mojom_name, lower_initial=True)
202
203  def StylizeStruct(self, mojom_name):
204    return mojom_name
205
206  def StylizeUnion(self, mojom_name):
207    return mojom_name
208
209  def StylizeParameter(self, mojom_name):
210    return generator.ToCamel(mojom_name, lower_initial=True)
211
212  def StylizeMethod(self, mojom_name):
213    return generator.ToCamel(mojom_name, lower_initial=True)
214
215  def StylizeEnumField(self, mojom_name):
216    return mojom_name
217
218  def StylizeEnum(self, mojom_name):
219    return mojom_name
220
221  def StylizeModule(self, mojom_namespace):
222    return '.'.join(generator.ToCamel(word, lower_initial=True)
223                        for word in mojom_namespace.split('.'))
224
225
226class Generator(generator.Generator):
227  def _GetParameters(self):
228    return {
229      "enums": self.module.enums,
230      "imports": self.module.imports,
231      "interfaces": self.module.interfaces,
232      "kinds": self.module.kinds,
233      "module": self.module,
234      "structs": self.module.structs + self._GetStructsFromMethods(),
235      "unions": self.module.unions,
236      "generate_fuzzing": self.generate_fuzzing,
237    }
238
239  @staticmethod
240  def GetTemplatePrefix():
241    return "js_templates"
242
243  def GetFilters(self):
244    js_filters = {
245      "closure_type": self._ClosureType,
246      "decode_snippet": self._JavaScriptDecodeSnippet,
247      "default_value": self._JavaScriptDefaultValue,
248      "encode_snippet": self._JavaScriptEncodeSnippet,
249      "expression_to_text": self._ExpressionToText,
250      "field_offset": JavaScriptFieldOffset,
251      "get_relative_url": GetRelativeUrl,
252      "has_callbacks": mojom.HasCallbacks,
253      "is_any_handle_or_interface_kind": mojom.IsAnyHandleOrInterfaceKind,
254      "is_array_kind": mojom.IsArrayKind,
255      "is_associated_interface_kind": mojom.IsAssociatedInterfaceKind,
256      "is_associated_interface_request_kind":
257          mojom.IsAssociatedInterfaceRequestKind,
258      "is_bool_kind": mojom.IsBoolKind,
259      "is_enum_kind": mojom.IsEnumKind,
260      "is_any_handle_kind": mojom.IsAnyHandleKind,
261      "is_any_interface_kind": mojom.IsAnyInterfaceKind,
262      "is_interface_kind": mojom.IsInterfaceKind,
263      "is_interface_request_kind": mojom.IsInterfaceRequestKind,
264      "is_map_kind": mojom.IsMapKind,
265      "is_object_kind": mojom.IsObjectKind,
266      "is_reference_kind": mojom.IsReferenceKind,
267      "is_string_kind": mojom.IsStringKind,
268      "is_struct_kind": mojom.IsStructKind,
269      "is_union_kind": mojom.IsUnionKind,
270      "js_type": self._JavaScriptType,
271      "method_passes_associated_kinds": mojom.MethodPassesAssociatedKinds,
272      "namespace_declarations": self._NamespaceDeclarations,
273      "closure_type_with_nullability": self._ClosureTypeWithNullability,
274      "payload_size": JavaScriptPayloadSize,
275      "to_camel": generator.ToCamel,
276      "union_decode_snippet": self._JavaScriptUnionDecodeSnippet,
277      "union_encode_snippet": self._JavaScriptUnionEncodeSnippet,
278      "validate_array_params": self._JavaScriptValidateArrayParams,
279      "validate_enum_params": self._JavaScriptValidateEnumParams,
280      "validate_map_params": self._JavaScriptValidateMapParams,
281      "validate_nullable_params": self._JavaScriptNullableParam,
282      "validate_struct_params": self._JavaScriptValidateStructParams,
283      "validate_union_params": self._JavaScriptValidateUnionParams,
284      "sanitize_identifier": self._JavaScriptSanitizeIdentifier,
285      "contains_handles_or_interfaces": mojom.ContainsHandlesOrInterfaces,
286      "fuzz_handle_name": self._FuzzHandleName,
287      "is_primitive_kind": self._IsPrimitiveKind,
288      "primitive_to_fuzz_type": self._PrimitiveToFuzzType,
289      "to_js_boolean": self._ToJsBoolean,
290    }
291    return js_filters
292
293  @UseJinja("module.amd.tmpl")
294  def _GenerateAMDModule(self):
295    return self._GetParameters()
296
297  @UseJinja("externs/module.externs.tmpl")
298  def _GenerateExterns(self):
299    return self._GetParameters()
300
301  def GenerateFiles(self, args):
302    if self.variant:
303      raise Exception("Variants not supported in JavaScript bindings.")
304
305    self.module.Stylize(JavaScriptStylizer())
306
307    # TODO(crbug.com/795977): Change the media router extension to not mess with
308    # the mojo namespace, so that namespaces such as "mojo.common.mojom" are not
309    # affected and we can remove this method.
310    self._SetUniqueNameForImports()
311
312    self.Write(self._GenerateAMDModule(), "%s.js" % self.module.path)
313    self.Write(self._GenerateExterns(), "%s.externs.js" % self.module.path)
314
315  def _SetUniqueNameForImports(self):
316    used_names = set()
317    for each_import in self.module.imports:
318      simple_name = os.path.basename(each_import.path).split(".")[0]
319
320      # Since each import is assigned a variable in JS, they need to have unique
321      # names.
322      unique_name = simple_name
323      counter = 0
324      while unique_name in used_names:
325        counter += 1
326        unique_name = simple_name + str(counter)
327
328      used_names.add(unique_name)
329      each_import.unique_name = unique_name + "$"
330      counter += 1
331
332  def _ClosureType(self, kind):
333    if kind in mojom.PRIMITIVES:
334      return _kind_to_closure_type[kind]
335    if mojom.IsInterfaceKind(kind):
336      return kind.module.namespace + "." + kind.name + "Ptr"
337    if (mojom.IsStructKind(kind) or
338        mojom.IsEnumKind(kind)):
339      return kind.module.namespace + "." + kind.name
340    # TODO(calamity): Support unions properly.
341    if mojom.IsUnionKind(kind):
342      return "Object"
343    if mojom.IsArrayKind(kind):
344      return "Array<%s>" % self._ClosureType(kind.kind)
345    if mojom.IsMapKind(kind):
346      return "Map<%s, %s>" % (
347          self._ClosureType(kind.key_kind), self._ClosureType(kind.value_kind))
348    if mojom.IsInterfaceRequestKind(kind):
349      return "mojo.InterfaceRequest"
350    # TODO(calamity): Support associated interfaces properly.
351    if mojom.IsAssociatedInterfaceKind(kind):
352      return "mojo.AssociatedInterfacePtrInfo"
353    # TODO(calamity): Support associated interface requests properly.
354    if mojom.IsAssociatedInterfaceRequestKind(kind):
355      return "mojo.AssociatedInterfaceRequest"
356    # TODO(calamity): Support enums properly.
357
358    raise Exception("No valid closure type: %s" % kind)
359
360  def _ClosureTypeWithNullability(self, kind):
361    return ("" if mojom.IsNullableKind(kind) else "!") + self._ClosureType(kind)
362
363  def _NamespaceDeclarations(self, namespace):
364    pieces = namespace.split('.')
365    declarations = []
366    declaration = []
367    for p in pieces:
368      declaration.append(p)
369      declarations.append('.'.join(declaration))
370    return declarations
371
372  def _JavaScriptType(self, kind):
373    name = []
374    if kind.module and kind.module.path != self.module.path:
375      name.append(kind.module.unique_name)
376    if kind.parent_kind:
377      name.append(kind.parent_kind.name)
378    name.append(kind.name)
379    return ".".join(name)
380
381  def _JavaScriptDefaultValue(self, field):
382    if field.default:
383      if mojom.IsStructKind(field.kind):
384        assert field.default == "default"
385        return "new %s()" % self._JavaScriptType(field.kind)
386      return self._ExpressionToText(field.default)
387    if field.kind in mojom.PRIMITIVES:
388      return _kind_to_javascript_default_value[field.kind]
389    if mojom.IsStructKind(field.kind):
390      return "null"
391    if mojom.IsUnionKind(field.kind):
392      return "null"
393    if mojom.IsArrayKind(field.kind):
394      return "null"
395    if mojom.IsMapKind(field.kind):
396      return "null"
397    if mojom.IsInterfaceKind(field.kind):
398      return "new %sPtr()" % self._JavaScriptType(field.kind)
399    if mojom.IsInterfaceRequestKind(field.kind):
400      return "new bindings.InterfaceRequest()"
401    if mojom.IsAssociatedInterfaceKind(field.kind):
402      return "new associatedBindings.AssociatedInterfacePtrInfo()"
403    if mojom.IsAssociatedInterfaceRequestKind(field.kind):
404      return "new associatedBindings.AssociatedInterfaceRequest()"
405    if mojom.IsEnumKind(field.kind):
406      return "0"
407    raise Exception("No valid default: %s" % field)
408
409  def _CodecType(self, kind):
410    if kind in mojom.PRIMITIVES:
411      return _kind_to_codec_type[kind]
412    if mojom.IsStructKind(kind):
413      pointer_type = "NullablePointerTo" if mojom.IsNullableKind(kind) \
414          else "PointerTo"
415      return "new codec.%s(%s)" % (pointer_type, self._JavaScriptType(kind))
416    if mojom.IsUnionKind(kind):
417      return self._JavaScriptType(kind)
418    if mojom.IsArrayKind(kind):
419      array_type = ("NullableArrayOf" if mojom.IsNullableKind(kind)
420                                      else "ArrayOf")
421      array_length = "" if kind.length is None else ", %d" % kind.length
422      element_type = self._ElementCodecType(kind.kind)
423      return "new codec.%s(%s%s)" % (array_type, element_type, array_length)
424    if mojom.IsInterfaceKind(kind):
425      return "new codec.%s(%sPtr)" % (
426          "NullableInterface" if mojom.IsNullableKind(kind) else "Interface",
427          self._JavaScriptType(kind))
428    if mojom.IsInterfaceRequestKind(kind):
429      return "codec.%s" % (
430          "NullableInterfaceRequest" if mojom.IsNullableKind(kind)
431                                     else "InterfaceRequest")
432    if mojom.IsAssociatedInterfaceKind(kind):
433      return "codec.%s" % ("NullableAssociatedInterfacePtrInfo"
434          if mojom.IsNullableKind(kind) else "AssociatedInterfacePtrInfo")
435    if mojom.IsAssociatedInterfaceRequestKind(kind):
436      return "codec.%s" % ("NullableAssociatedInterfaceRequest"
437          if mojom.IsNullableKind(kind) else "AssociatedInterfaceRequest")
438    if mojom.IsEnumKind(kind):
439      return "new codec.Enum(%s)" % self._JavaScriptType(kind)
440    if mojom.IsMapKind(kind):
441      map_type = "NullableMapOf" if mojom.IsNullableKind(kind) else "MapOf"
442      key_type = self._ElementCodecType(kind.key_kind)
443      value_type = self._ElementCodecType(kind.value_kind)
444      return "new codec.%s(%s, %s)" % (map_type, key_type, value_type)
445    raise Exception("No codec type for %s" % kind)
446
447  def _ElementCodecType(self, kind):
448    return ("codec.PackedBool" if mojom.IsBoolKind(kind)
449                               else self._CodecType(kind))
450
451  def _JavaScriptDecodeSnippet(self, kind):
452    if (kind in mojom.PRIMITIVES or mojom.IsUnionKind(kind) or
453        mojom.IsAnyInterfaceKind(kind)):
454      return "decodeStruct(%s)" % self._CodecType(kind)
455    if mojom.IsStructKind(kind):
456      return "decodeStructPointer(%s)" % self._JavaScriptType(kind)
457    if mojom.IsMapKind(kind):
458      return "decodeMapPointer(%s, %s)" % (
459          self._ElementCodecType(kind.key_kind),
460          self._ElementCodecType(kind.value_kind))
461    if mojom.IsArrayKind(kind) and mojom.IsBoolKind(kind.kind):
462      return "decodeArrayPointer(codec.PackedBool)"
463    if mojom.IsArrayKind(kind):
464      return "decodeArrayPointer(%s)" % self._CodecType(kind.kind)
465    if mojom.IsUnionKind(kind):
466      return "decodeUnion(%s)" % self._CodecType(kind)
467    if mojom.IsEnumKind(kind):
468      return self._JavaScriptDecodeSnippet(mojom.INT32)
469    raise Exception("No decode snippet for %s" % kind)
470
471  def _JavaScriptEncodeSnippet(self, kind):
472    if (kind in mojom.PRIMITIVES or mojom.IsUnionKind(kind) or
473        mojom.IsAnyInterfaceKind(kind)):
474      return "encodeStruct(%s, " % self._CodecType(kind)
475    if mojom.IsUnionKind(kind):
476      return "encodeStruct(%s, " % self._JavaScriptType(kind)
477    if mojom.IsStructKind(kind):
478      return "encodeStructPointer(%s, " % self._JavaScriptType(kind)
479    if mojom.IsMapKind(kind):
480      return "encodeMapPointer(%s, %s, " % (
481          self._ElementCodecType(kind.key_kind),
482          self._ElementCodecType(kind.value_kind))
483    if mojom.IsArrayKind(kind) and mojom.IsBoolKind(kind.kind):
484      return "encodeArrayPointer(codec.PackedBool, ";
485    if mojom.IsArrayKind(kind):
486      return "encodeArrayPointer(%s, " % self._CodecType(kind.kind)
487    if mojom.IsEnumKind(kind):
488      return self._JavaScriptEncodeSnippet(mojom.INT32)
489    raise Exception("No encode snippet for %s" % kind)
490
491  def _JavaScriptUnionDecodeSnippet(self, kind):
492    if mojom.IsUnionKind(kind):
493      return "decodeStructPointer(%s)" % self._JavaScriptType(kind)
494    return self._JavaScriptDecodeSnippet(kind)
495
496  def _JavaScriptUnionEncodeSnippet(self, kind):
497    if mojom.IsUnionKind(kind):
498      return "encodeStructPointer(%s, " % self._JavaScriptType(kind)
499    return self._JavaScriptEncodeSnippet(kind)
500
501  def _JavaScriptNullableParam(self, field):
502    return "true" if mojom.IsNullableKind(field.kind) else "false"
503
504  def _JavaScriptValidateArrayParams(self, field):
505    nullable = self._JavaScriptNullableParam(field)
506    element_kind = field.kind.kind
507    element_size = pack.PackedField.GetSizeForKind(element_kind)
508    expected_dimension_sizes = GetArrayExpectedDimensionSizes(
509        field.kind)
510    element_type = self._ElementCodecType(element_kind)
511    return "%s, %s, %s, %s, 0" % \
512        (element_size, element_type, nullable,
513         expected_dimension_sizes)
514
515  def _JavaScriptValidateEnumParams(self, field):
516    return self._JavaScriptType(field.kind)
517
518  def _JavaScriptValidateStructParams(self, field):
519    nullable = self._JavaScriptNullableParam(field)
520    struct_type = self._JavaScriptType(field.kind)
521    return "%s, %s" % (struct_type, nullable)
522
523  def _JavaScriptValidateUnionParams(self, field):
524    nullable = self._JavaScriptNullableParam(field)
525    union_type = self._JavaScriptType(field.kind)
526    return "%s, %s" % (union_type, nullable)
527
528  def _JavaScriptValidateMapParams(self, field):
529    nullable = self._JavaScriptNullableParam(field)
530    keys_type = self._ElementCodecType(field.kind.key_kind)
531    values_kind = field.kind.value_kind;
532    values_type = self._ElementCodecType(values_kind)
533    values_nullable = "true" if mojom.IsNullableKind(values_kind) else "false"
534    return "%s, %s, %s, %s" % \
535        (nullable, keys_type, values_type, values_nullable)
536
537  def _JavaScriptSanitizeIdentifier(self, identifier):
538    if identifier in _js_reserved_keywords:
539      return identifier + '_'
540
541    return identifier
542
543  def _TranslateConstants(self, token):
544    if isinstance(token, (mojom.EnumValue, mojom.NamedValue)):
545      # Both variable and enum constants are constructed like:
546      # NamespaceUid.Struct[.Enum].CONSTANT_NAME
547      name = []
548      if token.module and token.module.path != self.module.path:
549        name.append(token.module.unique_name)
550      if token.parent_kind:
551        name.append(token.parent_kind.name)
552      if isinstance(token, mojom.EnumValue):
553        name.append(token.enum.name)
554      name.append(token.name)
555      return ".".join(name)
556
557    if isinstance(token, mojom.BuiltinValue):
558      if token.value == "double.INFINITY" or token.value == "float.INFINITY":
559        return "Infinity";
560      if token.value == "double.NEGATIVE_INFINITY" or \
561         token.value == "float.NEGATIVE_INFINITY":
562        return "-Infinity";
563      if token.value == "double.NAN" or token.value == "float.NAN":
564        return "NaN";
565
566    return token
567
568  def _ExpressionToText(self, value):
569    return self._TranslateConstants(value)
570
571  def _GetStructsFromMethods(self):
572    result = []
573    for interface in self.module.interfaces:
574      for method in interface.methods:
575        result.append(method.param_struct)
576        if method.response_param_struct is not None:
577          result.append(method.response_param_struct)
578    return result
579
580  def _FuzzHandleName(self, kind):
581    if mojom.IsInterfaceRequestKind(kind):
582      return '{0}.{1}Request'.format(kind.kind.module.namespace,
583                                     kind.kind.name)
584    elif mojom.IsInterfaceKind(kind):
585      return '{0}.{1}Ptr'.format(kind.module.namespace,
586                                 kind.name)
587    elif mojom.IsAssociatedInterfaceRequestKind(kind):
588      return '{0}.{1}AssociatedRequest'.format(kind.kind.module.namespace,
589                                               kind.kind.name)
590    elif mojom.IsAssociatedInterfaceKind(kind):
591      return '{0}.{1}AssociatedPtr'.format(kind.kind.module.namespace,
592                                           kind.kind.name)
593    elif mojom.IsSharedBufferKind(kind):
594      return 'handle<shared_buffer>'
595    elif mojom.IsDataPipeConsumerKind(kind):
596      return 'handle<data_pipe_consumer>'
597    elif mojom.IsDataPipeProducerKind(kind):
598      return 'handle<data_pipe_producer>'
599    elif mojom.IsMessagePipeKind(kind):
600      return 'handle<message_pipe>'
601
602  def _ToJsBoolean(self, value):
603    if value:
604      return 'true'
605
606    return 'false'
607
608  def _IsPrimitiveKind(self, kind):
609    return kind in mojom.PRIMITIVES
610
611  def _PrimitiveToFuzzType(self, kind):
612    return _primitive_kind_to_fuzz_type[kind]
613