1{%- macro get_handle_deps(kind, name) -%}
2{%-   if kind|is_struct_kind or kind|is_union_kind -%}
3{{name}}.getHandleDeps()
4{%-   elif kind|is_array_kind -%}
5[].concat.apply([], {{name}}.map(function(val) {
6  if (val) {
7    return {{get_handle_deps(kind.kind, 'val')|indent(4)}};
8  }
9  return [];
10}))
11{%-   elif kind|is_map_kind -%}
12[].concat.apply([], Array.from({{name}}.values()).map(function(val) {
13  if (val) {
14    return {{get_handle_deps(kind.value_kind, 'val')|indent(4)}};
15  }
16  return [];
17}))
18{%-   elif kind|is_any_handle_or_interface_kind -%}
19  ["{{kind|fuzz_handle_name}}"]
20{%- else -%}
21  []
22{%-   endif -%}
23{%- endmacro -%}
24
25{%- macro set_handles(kind, name) -%}
26{%-   if kind|is_struct_kind or kind|is_union_kind -%}
27idx = {{name}}.setHandlesInternal_(handles, idx)
28{%-   elif kind|is_array_kind -%}
29{{name}}.forEach(function(val) {
30  {{set_handles(kind.kind, 'val')|indent(2)}};
31})
32{%-   elif kind|is_map_kind -%}
33{{name}}.forEach(function(val) {
34  {{set_handles(kind.value_kind, 'val')|indent(2)}};
35})
36{%-   elif kind|is_any_handle_or_interface_kind -%}
37{{name}} = handles[idx++];
38{%-   endif -%}
39{%- endmacro -%}
40
41{%- macro build_call(obj, operation, type, name) -%}
42{%-   if name -%}
43{{obj}}.{{operation}}{{type}}({{((name,) + varargs)|join(', ')}})
44{%-   else -%}
45{{obj}}.{{operation}}{{type}}({{varargs|join(', ')}})
46{%-   endif -%}
47{%- endmacro -%}
48
49{%- macro generate_or_mutate_enum(obj, operation, kind, name) -%}
50{%-   if kind.max_value is not none -%}
51{{build_call(obj, operation, 'Enum', name, '0', kind.max_value)}}
52{%-   else -%}
53{{build_call(obj, operation, 'Enum', name)}}
54{%-   endif %}
55{%- endmacro -%}
56
57{%- macro generate_or_mutate_array(obj, operation, kind, name) -%}
58{%-   if operation == 'mutate' -%}
59{{obj}}.{{operation}}Array({{name}}, function(val) {
60  return {{generate_or_mutate(obj, operation, kind.kind, 'val')|indent(2)}};
61})
62{%-   else -%}
63{{obj}}.{{operation}}Array(function() {
64  return {{generate_or_mutate(obj, operation, kind.kind)|indent(2)}};
65})
66{%-   endif -%}
67{%- endmacro -%}
68
69{%- macro generate_or_mutate_map(obj, operation, kind, name) -%}
70{%-   if operation == 'mutate' -%}
71{{obj}}.{{operation}}Map({{name}},
72  function(val) {
73    return {{generate_or_mutate(obj, operation, kind.key_kind, 'val')|indent(4)}};
74  },
75  function(val) {
76    return {{generate_or_mutate(obj, operation, kind.value_kind, 'val')|indent(4)}};
77  })
78{%-   else -%}
79{{obj}}.{{operation}}Map(
80  function() {
81    return {{generate_or_mutate(obj, operation, kind.key_kind)|indent(4)}};
82  },
83  function() {
84    return {{generate_or_mutate(obj, operation, kind.value_kind)|indent(4)}};
85  })
86{%-   endif -%}
87{%- endmacro -%}
88
89{%- macro generate_or_mutate_primitive(obj, operation, kind, name) -%}
90{%-   if kind|is_reference_kind -%}
91{{build_call(obj, operation, kind|primitive_to_fuzz_type, name, kind.is_nullable|to_js_boolean)}}
92{%-   else -%}
93{{build_call(obj, operation, kind|primitive_to_fuzz_type, name)}}
94{%-   endif -%}
95{%- endmacro -%}
96
97{%- macro generate_or_mutate_interface(obj, operation, kind, name) -%}
98{%-   if kind|is_interface_request_kind -%}
99{{build_call(obj, operation, 'InterfaceRequest', name, '"' ~ kind.kind.module.namespace ~ '.' ~ kind.kind.name ~ '"', kind.is_nullable|to_js_boolean)}}
100{%-   elif kind|is_interface_kind -%}
101{{build_call(obj, operation, 'Interface', name, '"' ~ kind.module.namespace ~ '.' ~ kind.name ~ '"', kind.is_nullable|to_js_boolean)}}
102{%-   elif kind|is_associated_interface_request_kind -%}
103{{build_call(obj, operation, 'AssociatedInterfaceRequest', name, '"' ~ kind.kind.module.namespace ~ '.' ~ kind.kind.name ~ '"', kind.is_nullable|to_js_boolean)}}
104{%-   elif kind|is_associated_interface_kind -%}
105{{build_call(obj, operation, 'AssociatedInterface', name, '"' ~ kind.kind.module.namespace ~ '.' ~ kind.kind.name ~ '"', kind.is_nullable|to_js_boolean)}}
106{%-   endif -%}
107{%- endmacro -%}
108
109{%- macro generate_or_mutate(obj, operation, kind, name='') -%}
110{%-   if kind|is_primitive_kind -%}
111{{generate_or_mutate_primitive(obj, operation, kind, name)}}
112{%-   elif kind|is_any_interface_kind -%}
113{{generate_or_mutate_interface(obj, operation, kind, name)}}
114{%-   elif kind|is_enum_kind -%}
115{{generate_or_mutate_enum(obj, operation, kind, name)}}
116{%-   elif kind|is_struct_kind -%}
117{{build_call(obj, operation, 'Struct', name, kind.module.namespace ~ '.' ~ kind.name, kind.is_nullable|to_js_boolean)}}
118{%-   elif kind|is_union_kind -%}
119{{build_call(obj, operation, 'Union', name, kind.module.namespace ~ '.' ~ kind.name, kind.is_nullable|to_js_boolean)}}
120{%-   elif kind|is_array_kind -%}
121{{generate_or_mutate_array(obj, operation, kind, name)}}
122{%-   elif kind|is_map_kind -%}
123{{generate_or_mutate_map(obj, operation, kind, name)}}
124{%-   endif -%}
125{%- endmacro -%}
126