blob: 1605ceb55d3d62e85448f381c7fed29e437931fd [file] [log] [blame]
Corentin Wallez59382b72020-04-17 20:43:07 +00001#!/usr/bin/env python3
Corentin Wallez4a9ef4e2018-07-18 11:40:26 +02002# Copyright 2017 The Dawn Authors
Corentin Wallezf07e3bd2017-04-20 14:38:20 -04003#
4# Licensed under the Apache License, Version 2.0 (the "License");
5# you may not use this file except in compliance with the License.
6# You may obtain a copy of the License at
7#
8# http://www.apache.org/licenses/LICENSE-2.0
9#
10# Unless required by applicable law or agreed to in writing, software
11# distributed under the License is distributed on an "AS IS" BASIS,
12# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13# See the License for the specific language governing permissions and
14# limitations under the License.
15
Corentin Wallez0c38e922019-06-07 08:59:17 +000016import json, os, sys
Corentin Wallezf07e3bd2017-04-20 14:38:20 -040017from collections import namedtuple
Corentin Wallez0c38e922019-06-07 08:59:17 +000018
Corentin Wallez0c38e922019-06-07 08:59:17 +000019from generator_lib import Generator, run_generator, FileRender
Corentin Wallez031fbbb2019-06-11 18:03:05 +000020
21############################################################
22# OBJECT MODEL
23############################################################
24
Kai Ninomiya01aeca22020-07-15 19:51:17 +000025
fujunwei76bda372021-11-23 08:47:35 +000026class Metadata:
27 def __init__(self, metadata):
28 self.api = metadata['api']
29 self.namespace = metadata['namespace']
30 self.c_prefix = metadata.get('c_prefix', self.namespace.upper())
fujunwei3a464762021-12-05 05:29:44 +000031 self.proc_table_prefix = metadata['proc_table_prefix']
fujunweia2241d42021-12-16 04:54:38 +000032 self.impl_dir = metadata.get('impl_dir', '')
33 self.native_namespace = metadata['native_namespace']
fujunwei76bda372021-11-23 08:47:35 +000034 self.copyright_year = metadata.get('copyright_year', None)
35
36
Corentin Wallez031fbbb2019-06-11 18:03:05 +000037class Name:
38 def __init__(self, name, native=False):
39 self.native = native
Austin Eng76a8d0b2020-04-03 17:37:48 +000040 self.name = name
Corentin Wallez031fbbb2019-06-11 18:03:05 +000041 if native:
42 self.chunks = [name]
43 else:
44 self.chunks = name.split(' ')
45
Austin Eng76a8d0b2020-04-03 17:37:48 +000046 def get(self):
47 return self.name
48
Corentin Wallez031fbbb2019-06-11 18:03:05 +000049 def CamelChunk(self, chunk):
50 return chunk[0].upper() + chunk[1:]
51
52 def canonical_case(self):
53 return (' '.join(self.chunks)).lower()
54
55 def concatcase(self):
56 return ''.join(self.chunks)
57
58 def camelCase(self):
Kai Ninomiya01aeca22020-07-15 19:51:17 +000059 return self.chunks[0] + ''.join(
60 [self.CamelChunk(chunk) for chunk in self.chunks[1:]])
Corentin Wallez031fbbb2019-06-11 18:03:05 +000061
62 def CamelCase(self):
63 return ''.join([self.CamelChunk(chunk) for chunk in self.chunks])
64
65 def SNAKE_CASE(self):
66 return '_'.join([chunk.upper() for chunk in self.chunks])
67
68 def snake_case(self):
69 return '_'.join(self.chunks)
70
Corentin Wallezec9cf2a2022-01-12 09:17:35 +000071 def namespace_case(self):
72 return '::'.join(self.chunks)
73
Ben Clayton20cbe6d2022-02-04 12:51:25 +000074 def Dirs(self):
75 return '/'.join(self.chunks)
76
Kai Ninomiya7b6246a2020-01-28 23:54:38 +000077 def js_enum_case(self):
78 result = self.chunks[0].lower()
79 for chunk in self.chunks[1:]:
80 if not result[-1].isdigit():
81 result += '-'
82 result += chunk.lower()
83 return result
84
Kai Ninomiya01aeca22020-07-15 19:51:17 +000085
Corentin Wallez031fbbb2019-06-11 18:03:05 +000086def concat_names(*names):
87 return ' '.join([name.canonical_case() for name in names])
88
Kai Ninomiya01aeca22020-07-15 19:51:17 +000089
Corentin Wallez031fbbb2019-06-11 18:03:05 +000090class Type:
91 def __init__(self, name, json_data, native=False):
92 self.json_data = json_data
93 self.dict_name = name
94 self.name = Name(name, native=native)
95 self.category = json_data['category']
Jiawei Shao6d6b63c2021-12-02 07:29:41 +000096 self.is_wire_transparent = False
Corentin Wallez031fbbb2019-06-11 18:03:05 +000097
Kai Ninomiya01aeca22020-07-15 19:51:17 +000098
Kai Ninomiya930e9182021-09-17 19:44:43 +000099EnumValue = namedtuple('EnumValue', ['name', 'value', 'valid', 'json_data'])
Kai Ninomiya01aeca22020-07-15 19:51:17 +0000100
101
Corentin Wallez031fbbb2019-06-11 18:03:05 +0000102class EnumType(Type):
Kai Ninomiya930e9182021-09-17 19:44:43 +0000103 def __init__(self, is_enabled, name, json_data):
Corentin Wallez031fbbb2019-06-11 18:03:05 +0000104 Type.__init__(self, name, json_data)
Kai Ninomiya7b6246a2020-01-28 23:54:38 +0000105
106 self.values = []
107 self.contiguousFromZero = True
108 lastValue = -1
109 for m in self.json_data['values']:
Kai Ninomiya930e9182021-09-17 19:44:43 +0000110 if not is_enabled(m):
111 continue
Kai Ninomiya7b6246a2020-01-28 23:54:38 +0000112 value = m['value']
113 if value != lastValue + 1:
114 self.contiguousFromZero = False
115 lastValue = value
Kai Ninomiya01aeca22020-07-15 19:51:17 +0000116 self.values.append(
Kai Ninomiya930e9182021-09-17 19:44:43 +0000117 EnumValue(Name(m['name']), value, m.get('valid', True), m))
Corentin Wallez031fbbb2019-06-11 18:03:05 +0000118
Corentin Wallez7ac08152019-06-26 19:54:43 +0000119 # Assert that all values are unique in enums
120 all_values = set()
121 for value in self.values:
122 if value.value in all_values:
Kai Ninomiya01aeca22020-07-15 19:51:17 +0000123 raise Exception("Duplicate value {} in enum {}".format(
124 value.value, name))
Corentin Wallez7ac08152019-06-26 19:54:43 +0000125 all_values.add(value.value)
Jiawei Shao6d6b63c2021-12-02 07:29:41 +0000126 self.is_wire_transparent = True
Corentin Wallez7ac08152019-06-26 19:54:43 +0000127
Kai Ninomiya01aeca22020-07-15 19:51:17 +0000128
Kai Ninomiya930e9182021-09-17 19:44:43 +0000129BitmaskValue = namedtuple('BitmaskValue', ['name', 'value', 'json_data'])
Kai Ninomiya01aeca22020-07-15 19:51:17 +0000130
131
Corentin Wallez031fbbb2019-06-11 18:03:05 +0000132class BitmaskType(Type):
Kai Ninomiya930e9182021-09-17 19:44:43 +0000133 def __init__(self, is_enabled, name, json_data):
Corentin Wallez031fbbb2019-06-11 18:03:05 +0000134 Type.__init__(self, name, json_data)
Kai Ninomiya01aeca22020-07-15 19:51:17 +0000135 self.values = [
Kai Ninomiya930e9182021-09-17 19:44:43 +0000136 BitmaskValue(Name(m['name']), m['value'], m)
137 for m in self.json_data['values'] if is_enabled(m)
Kai Ninomiya01aeca22020-07-15 19:51:17 +0000138 ]
Corentin Wallez031fbbb2019-06-11 18:03:05 +0000139 self.full_mask = 0
140 for value in self.values:
141 self.full_mask = self.full_mask | value.value
Jiawei Shao6d6b63c2021-12-02 07:29:41 +0000142 self.is_wire_transparent = True
Corentin Wallez031fbbb2019-06-11 18:03:05 +0000143
Kai Ninomiya01aeca22020-07-15 19:51:17 +0000144
fujunwei23f71622021-12-02 07:41:21 +0000145class FunctionPointerType(Type):
Kai Ninomiya930e9182021-09-17 19:44:43 +0000146 def __init__(self, is_enabled, name, json_data):
Corentin Wallez540abab2019-11-22 13:18:22 +0000147 Type.__init__(self, name, json_data)
fujunwei23f71622021-12-02 07:41:21 +0000148 self.return_type = None
Corentin Wallez540abab2019-11-22 13:18:22 +0000149 self.arguments = []
150
Kai Ninomiya01aeca22020-07-15 19:51:17 +0000151
Brandon Jones58a471a2021-02-08 19:48:06 +0000152class TypedefType(Type):
Kai Ninomiya930e9182021-09-17 19:44:43 +0000153 def __init__(self, is_enabled, name, json_data):
Brandon Jones58a471a2021-02-08 19:48:06 +0000154 Type.__init__(self, name, json_data)
155 self.type = None
156
157
Corentin Wallez031fbbb2019-06-11 18:03:05 +0000158class NativeType(Type):
Kai Ninomiya930e9182021-09-17 19:44:43 +0000159 def __init__(self, is_enabled, name, json_data):
Corentin Wallez031fbbb2019-06-11 18:03:05 +0000160 Type.__init__(self, name, json_data, native=True)
Loko Kung837f1512023-06-06 03:01:15 +0000161 self.is_wire_transparent = json_data.get('wire transparent', True)
Corentin Wallez031fbbb2019-06-11 18:03:05 +0000162
Kai Ninomiya01aeca22020-07-15 19:51:17 +0000163
Corentin Wallez031fbbb2019-06-11 18:03:05 +0000164# Methods and structures are both "records", so record members correspond to
165# method arguments or structure members.
166class RecordMember:
Kai Ninomiya01aeca22020-07-15 19:51:17 +0000167 def __init__(self,
168 name,
169 typ,
170 annotation,
Kai Ninomiya930e9182021-09-17 19:44:43 +0000171 json_data,
Kai Ninomiya01aeca22020-07-15 19:51:17 +0000172 optional=False,
173 is_return_value=False,
174 default_value=None,
Austin Eng6a5418a2019-07-19 16:01:48 +0000175 skip_serialize=False):
Corentin Wallez031fbbb2019-06-11 18:03:05 +0000176 self.name = name
177 self.type = typ
178 self.annotation = annotation
Kai Ninomiya930e9182021-09-17 19:44:43 +0000179 self.json_data = json_data
Corentin Wallez031fbbb2019-06-11 18:03:05 +0000180 self.length = None
181 self.optional = optional
182 self.is_return_value = is_return_value
183 self.handle_type = None
Brendon Tiszka27521c62023-05-15 22:22:07 +0000184 self.id_type = None
Corentin Wallez8f938712019-07-08 19:20:22 +0000185 self.default_value = default_value
Austin Eng6a5418a2019-07-19 16:01:48 +0000186 self.skip_serialize = skip_serialize
Corentin Wallez031fbbb2019-06-11 18:03:05 +0000187
188 def set_handle_type(self, handle_type):
189 assert self.type.dict_name == "ObjectHandle"
190 self.handle_type = handle_type
191
Brendon Tiszka27521c62023-05-15 22:22:07 +0000192 def set_id_type(self, id_type):
193 assert self.type.dict_name == "ObjectId"
194 self.id_type = id_type
195
Kai Ninomiya01aeca22020-07-15 19:51:17 +0000196
Le Hoang Quyen7971bfe2023-04-05 19:35:07 +0000197Method = namedtuple(
198 'Method', ['name', 'return_type', 'arguments', 'autolock', 'json_data'])
Kai Ninomiya01aeca22020-07-15 19:51:17 +0000199
200
Corentin Wallez031fbbb2019-06-11 18:03:05 +0000201class ObjectType(Type):
Kai Ninomiya930e9182021-09-17 19:44:43 +0000202 def __init__(self, is_enabled, name, json_data):
203 json_data_override = {'methods': []}
204 if 'methods' in json_data:
205 json_data_override['methods'] = [
206 m for m in json_data['methods'] if is_enabled(m)
207 ]
208 Type.__init__(self, name, dict(json_data, **json_data_override))
Corentin Wallez031fbbb2019-06-11 18:03:05 +0000209
Kai Ninomiya01aeca22020-07-15 19:51:17 +0000210
Corentin Wallez031fbbb2019-06-11 18:03:05 +0000211class Record:
212 def __init__(self, name):
213 self.name = Name(name)
214 self.members = []
Austin Eng76a8d0b2020-04-03 17:37:48 +0000215 self.may_have_dawn_object = False
Corentin Wallez031fbbb2019-06-11 18:03:05 +0000216
217 def update_metadata(self):
Austin Eng76a8d0b2020-04-03 17:37:48 +0000218 def may_have_dawn_object(member):
Corentin Wallez031fbbb2019-06-11 18:03:05 +0000219 if isinstance(member.type, ObjectType):
220 return True
221 elif isinstance(member.type, StructureType):
Austin Eng76a8d0b2020-04-03 17:37:48 +0000222 return member.type.may_have_dawn_object
Corentin Wallez031fbbb2019-06-11 18:03:05 +0000223 else:
224 return False
225
Kai Ninomiya01aeca22020-07-15 19:51:17 +0000226 self.may_have_dawn_object = any(
227 may_have_dawn_object(member) for member in self.members)
Austin Eng76a8d0b2020-04-03 17:37:48 +0000228
Kai Ninomiya01aeca22020-07-15 19:51:17 +0000229 # Set may_have_dawn_object to true if the type is chained or
230 # extensible. Chained structs may contain a Dawn object.
Austin Eng76a8d0b2020-04-03 17:37:48 +0000231 if isinstance(self, StructureType):
Kai Ninomiya01aeca22020-07-15 19:51:17 +0000232 self.may_have_dawn_object = (self.may_have_dawn_object
233 or self.chained or self.extensible)
234
Corentin Wallez031fbbb2019-06-11 18:03:05 +0000235
236class StructureType(Record, Type):
Kai Ninomiya930e9182021-09-17 19:44:43 +0000237 def __init__(self, is_enabled, name, json_data):
Corentin Wallez031fbbb2019-06-11 18:03:05 +0000238 Record.__init__(self, name)
Kai Ninomiya930e9182021-09-17 19:44:43 +0000239 json_data_override = {}
240 if 'members' in json_data:
241 json_data_override['members'] = [
242 m for m in json_data['members'] if is_enabled(m)
243 ]
244 Type.__init__(self, name, dict(json_data, **json_data_override))
Corentin Walleza45561b2022-07-14 12:58:25 +0000245 self.chained = json_data.get('chained', None)
246 self.extensible = json_data.get('extensible', None)
Austin Eng0c824052021-09-20 16:07:25 +0000247 if self.chained:
Corentin Walleza45561b2022-07-14 12:58:25 +0000248 assert self.chained == 'in' or self.chained == 'out'
249 assert 'chain roots' in json_data
Austin Eng0c824052021-09-20 16:07:25 +0000250 if self.extensible:
Corentin Walleza45561b2022-07-14 12:58:25 +0000251 assert self.extensible == 'in' or self.extensible == 'out'
Kai Ninomiya01aeca22020-07-15 19:51:17 +0000252 # Chained structs inherit from wgpu::ChainedStruct, which has
253 # nextInChain, so setting both extensible and chained would result in
254 # two nextInChain members.
255 assert not (self.extensible and self.chained)
256
Jiawei Shao1fa386c2021-12-21 04:04:51 +0000257 def update_metadata(self):
258 Record.update_metadata(self)
259
260 if self.may_have_dawn_object:
261 self.is_wire_transparent = False
262 return
263
264 assert not (self.chained or self.extensible)
265
266 def get_is_wire_transparent(member):
267 return member.type.is_wire_transparent and member.annotation == 'value'
268
269 self.is_wire_transparent = all(
270 get_is_wire_transparent(m) for m in self.members)
271
Austin Eng0c824052021-09-20 16:07:25 +0000272 @property
273 def output(self):
274 return self.chained == "out" or self.extensible == "out"
275
Corentin Wallez031fbbb2019-06-11 18:03:05 +0000276
fujunwei4e876902021-11-25 08:44:01 +0000277class ConstantDefinition():
278 def __init__(self, is_enabled, name, json_data):
279 self.type = None
280 self.value = json_data['value']
281 self.json_data = json_data
282 self.name = Name(name)
283
284
fujunwei23f71622021-12-02 07:41:21 +0000285class FunctionDeclaration():
286 def __init__(self, is_enabled, name, json_data):
287 self.return_type = None
288 self.arguments = []
289 self.json_data = json_data
290 self.name = Name(name)
291
292
Corentin Wallez031fbbb2019-06-11 18:03:05 +0000293class Command(Record):
294 def __init__(self, name, members=None):
295 Record.__init__(self, name)
296 self.members = members or []
297 self.derived_object = None
298 self.derived_method = None
299
Kai Ninomiya01aeca22020-07-15 19:51:17 +0000300
Corentin Wallez031fbbb2019-06-11 18:03:05 +0000301def linked_record_members(json_data, types):
302 members = []
303 members_by_name = {}
304 for m in json_data:
Kai Ninomiya01aeca22020-07-15 19:51:17 +0000305 member = RecordMember(Name(m['name']),
306 types[m['type']],
Corentin Wallez8f938712019-07-08 19:20:22 +0000307 m.get('annotation', 'value'),
Kai Ninomiya930e9182021-09-17 19:44:43 +0000308 m,
Corentin Wallez8f938712019-07-08 19:20:22 +0000309 optional=m.get('optional', False),
310 is_return_value=m.get('is_return_value', False),
Austin Eng6a5418a2019-07-19 16:01:48 +0000311 default_value=m.get('default', None),
312 skip_serialize=m.get('skip_serialize', False))
Corentin Wallez031fbbb2019-06-11 18:03:05 +0000313 handle_type = m.get('handle_type')
314 if handle_type:
315 member.set_handle_type(types[handle_type])
Brendon Tiszka27521c62023-05-15 22:22:07 +0000316 id_type = m.get('id_type')
317 if id_type:
318 member.set_id_type(types[id_type])
Corentin Wallez031fbbb2019-06-11 18:03:05 +0000319 members.append(member)
320 members_by_name[member.name.canonical_case()] = member
321
322 for (member, m) in zip(members, json_data):
323 if member.annotation != 'value':
324 if not 'length' in m:
325 if member.type.category != 'object':
326 member.length = "constant"
327 member.constant_length = 1
328 else:
Kai Ninomiya01aeca22020-07-15 19:51:17 +0000329 assert False
Corentin Wallez031fbbb2019-06-11 18:03:05 +0000330 elif m['length'] == 'strlen':
331 member.length = 'strlen'
Yan52040532021-12-15 04:08:56 +0000332 elif isinstance(m['length'], int):
333 assert m['length'] > 0
334 member.length = "constant"
335 member.constant_length = m['length']
Corentin Wallez031fbbb2019-06-11 18:03:05 +0000336 else:
337 member.length = members_by_name[m['length']]
338
339 return members
Corentin Walleza6416542018-05-17 16:55:53 -0400340
Kai Ninomiya01aeca22020-07-15 19:51:17 +0000341
Brendon Tiszka27521c62023-05-15 22:22:07 +0000342def mark_lengths_non_serializable_lpm(record_members):
343 # Remove member length values from command metadata,
344 # these are set to the length of the protobuf array.
345 for record_member in record_members:
346 lengths = set()
347 for member in record_member.members:
348 lengths.add(member.length)
349
350 for member in record_member.members:
351 if member in lengths:
352 member.skip_serialize = True
353
Corentin Wallezf07e3bd2017-04-20 14:38:20 -0400354############################################################
355# PARSE
356############################################################
Corentin Wallez4b410a32017-04-20 14:42:36 -0400357
Kai Ninomiya01aeca22020-07-15 19:51:17 +0000358
Corentin Walleze2f94842018-12-05 17:49:04 +0000359def link_object(obj, types):
Le Hoang Quyen7971bfe2023-04-05 19:35:07 +0000360 # Disable method's autolock if obj's "no autolock" = True
361 obj_scoped_autolock_enabled = not obj.json_data.get('no autolock', False)
362
Corentin Walleze2f94842018-12-05 17:49:04 +0000363 def make_method(json_data):
Corentin Wallez031fbbb2019-06-11 18:03:05 +0000364 arguments = linked_record_members(json_data.get('args', []), types)
Le Hoang Quyen7971bfe2023-04-05 19:35:07 +0000365 autolock_enabled = obj_scoped_autolock_enabled and not json_data.get(
366 'no autolock', False)
Kai Ninomiya01aeca22020-07-15 19:51:17 +0000367 return Method(Name(json_data['name']),
Le Hoang Quyen7971bfe2023-04-05 19:35:07 +0000368 types[json_data.get('returns', 'void')], arguments,
369 autolock_enabled, json_data)
Corentin Walleze2f94842018-12-05 17:49:04 +0000370
Corentin Wallezaca8c4a2019-11-22 14:02:52 +0000371 obj.methods = [make_method(m) for m in obj.json_data.get('methods', [])]
Corentin Wallez97231682019-10-08 07:38:01 +0000372 obj.methods.sort(key=lambda method: method.name.canonical_case())
Corentin Wallezf07e3bd2017-04-20 14:38:20 -0400373
Kai Ninomiya01aeca22020-07-15 19:51:17 +0000374
Corentin Walleza6416542018-05-17 16:55:53 -0400375def link_structure(struct, types):
Corentin Wallez031fbbb2019-06-11 18:03:05 +0000376 struct.members = linked_record_members(struct.json_data['members'], types)
Corentin Walleza45561b2022-07-14 12:58:25 +0000377 struct.chain_roots = [types[root] for root in struct.json_data.get('chain roots', [])]
378 assert all((root.category == 'structure' for root in struct.chain_roots))
Corentin Walleza6416542018-05-17 16:55:53 -0400379
Corentin Wallez540abab2019-11-22 13:18:22 +0000380
fujunwei23f71622021-12-02 07:41:21 +0000381def link_function_pointer(function_pointer, types):
382 link_function(function_pointer, types)
Kai Ninomiya01aeca22020-07-15 19:51:17 +0000383
384
Brandon Jones58a471a2021-02-08 19:48:06 +0000385def link_typedef(typedef, types):
386 typedef.type = types[typedef.json_data['type']]
387
388
fujunwei4e876902021-11-25 08:44:01 +0000389def link_constant(constant, types):
390 constant.type = types[constant.json_data['type']]
391 assert constant.type.name.native
392
393
fujunwei23f71622021-12-02 07:41:21 +0000394def link_function(function, types):
395 function.return_type = types[function.json_data.get('returns', 'void')]
396 function.arguments = linked_record_members(function.json_data['args'],
397 types)
398
Kai Ninomiya01aeca22020-07-15 19:51:17 +0000399# Sort structures so that if struct A has struct B as a member, then B is
400# listed before A.
401#
402# This is a form of topological sort where we try to keep the order reasonably
403# similar to the original order (though the sort isn't technically stable).
404#
405# It works by computing for each struct type what is the depth of its DAG of
Kai Ninomiya7d174a12021-09-21 17:36:27 +0000406# dependents, then re-sorting based on that depth using Python's stable sort.
Kai Ninomiya01aeca22020-07-15 19:51:17 +0000407# This makes a toposort because if A depends on B then its depth will be bigger
408# than B's. It is also nice because all nodes with the same depth are kept in
409# the input order.
Corentin Wallez29353d62018-09-18 12:49:22 +0000410def topo_sort_structure(structs):
411 for struct in structs:
412 struct.visited = False
413 struct.subdag_depth = 0
414
415 def compute_depth(struct):
416 if struct.visited:
417 return struct.subdag_depth
418
419 max_dependent_depth = 0
420 for member in struct.members:
Corentin Walleze2f94842018-12-05 17:49:04 +0000421 if member.type.category == 'structure':
Kai Ninomiya01aeca22020-07-15 19:51:17 +0000422 max_dependent_depth = max(max_dependent_depth,
423 compute_depth(member.type) + 1)
Corentin Wallez29353d62018-09-18 12:49:22 +0000424
425 struct.subdag_depth = max_dependent_depth
426 struct.visited = True
427 return struct.subdag_depth
428
429 for struct in structs:
430 compute_depth(struct)
431
432 result = sorted(structs, key=lambda struct: struct.subdag_depth)
433
434 for struct in structs:
435 del struct.visited
436 del struct.subdag_depth
437
438 return result
439
Kai Ninomiya01aeca22020-07-15 19:51:17 +0000440
Austin Eng2f218e22021-12-22 19:02:23 +0000441def parse_json(json, enabled_tags, disabled_tags=None):
442 is_enabled = lambda json_data: item_is_enabled(
443 enabled_tags, json_data) and not item_is_disabled(
444 disabled_tags, json_data)
Corentin Wallezf07e3bd2017-04-20 14:38:20 -0400445 category_to_parser = {
Corentin Wallez031fbbb2019-06-11 18:03:05 +0000446 'bitmask': BitmaskType,
447 'enum': EnumType,
448 'native': NativeType,
fujunwei23f71622021-12-02 07:41:21 +0000449 'function pointer': FunctionPointerType,
Corentin Wallez031fbbb2019-06-11 18:03:05 +0000450 'object': ObjectType,
451 'structure': StructureType,
Brandon Jones58a471a2021-02-08 19:48:06 +0000452 'typedef': TypedefType,
fujunwei4e876902021-11-25 08:44:01 +0000453 'constant': ConstantDefinition,
fujunwei23f71622021-12-02 07:41:21 +0000454 'function': FunctionDeclaration
Corentin Wallezf07e3bd2017-04-20 14:38:20 -0400455 }
456
457 types = {}
458
459 by_category = {}
460 for name in category_to_parser.keys():
461 by_category[name] = []
462
Corentin Walleze2f94842018-12-05 17:49:04 +0000463 for (name, json_data) in json.items():
Austin Eng2f218e22021-12-22 19:02:23 +0000464 if name[0] == '_' or not is_enabled(json_data):
Corentin Wallezf07e3bd2017-04-20 14:38:20 -0400465 continue
Corentin Walleze2f94842018-12-05 17:49:04 +0000466 category = json_data['category']
Kai Ninomiya930e9182021-09-17 19:44:43 +0000467 parsed = category_to_parser[category](is_enabled, name, json_data)
Corentin Wallezf07e3bd2017-04-20 14:38:20 -0400468 by_category[category].append(parsed)
469 types[name] = parsed
470
471 for obj in by_category['object']:
472 link_object(obj, types)
473
Corentin Walleza6416542018-05-17 16:55:53 -0400474 for struct in by_category['structure']:
475 link_structure(struct, types)
476
fujunwei23f71622021-12-02 07:41:21 +0000477 for function_pointer in by_category['function pointer']:
478 link_function_pointer(function_pointer, types)
Corentin Wallez540abab2019-11-22 13:18:22 +0000479
Brandon Jones58a471a2021-02-08 19:48:06 +0000480 for typedef in by_category['typedef']:
481 link_typedef(typedef, types)
482
fujunwei4e876902021-11-25 08:44:01 +0000483 for constant in by_category['constant']:
484 link_constant(constant, types)
485
fujunwei23f71622021-12-02 07:41:21 +0000486 for function in by_category['function']:
487 link_function(function, types)
488
Corentin Wallezf07e3bd2017-04-20 14:38:20 -0400489 for category in by_category.keys():
Kai Ninomiya01aeca22020-07-15 19:51:17 +0000490 by_category[category] = sorted(
491 by_category[category], key=lambda typ: typ.name.canonical_case())
Corentin Wallezf07e3bd2017-04-20 14:38:20 -0400492
Corentin Wallez29353d62018-09-18 12:49:22 +0000493 by_category['structure'] = topo_sort_structure(by_category['structure'])
494
Austin Engc7f416c2019-01-15 20:49:53 +0000495 for struct in by_category['structure']:
496 struct.update_metadata()
497
Kai Ninomiya930e9182021-09-17 19:44:43 +0000498 api_params = {
499 'types': types,
500 'by_category': by_category,
501 'enabled_tags': enabled_tags,
Austin Eng2f218e22021-12-22 19:02:23 +0000502 'disabled_tags': disabled_tags,
Kai Ninomiya930e9182021-09-17 19:44:43 +0000503 }
504 return {
fujunwei76bda372021-11-23 08:47:35 +0000505 'metadata': Metadata(json['_metadata']),
Kai Ninomiya930e9182021-09-17 19:44:43 +0000506 'types': types,
507 'by_category': by_category,
508 'enabled_tags': enabled_tags,
Austin Eng2f218e22021-12-22 19:02:23 +0000509 'disabled_tags': disabled_tags,
Kai Ninomiya930e9182021-09-17 19:44:43 +0000510 'c_methods': lambda typ: c_methods(api_params, typ),
511 'c_methods_sorted_by_name': get_c_methods_sorted_by_name(api_params),
512 }
Kai Ninomiya01aeca22020-07-15 19:51:17 +0000513
Corentin Wallezf07e3bd2017-04-20 14:38:20 -0400514
Corentin Wallez031fbbb2019-06-11 18:03:05 +0000515############################################################
516# WIRE STUFF
517############################################################
518
Kai Ninomiya01aeca22020-07-15 19:51:17 +0000519
Corentin Wallez031fbbb2019-06-11 18:03:05 +0000520# Create wire commands from api methods
521def compute_wire_params(api_params, wire_json):
522 wire_params = api_params.copy()
523 types = wire_params['types']
524
525 commands = []
526 return_commands = []
527
Kai Ninomiya01aeca22020-07-15 19:51:17 +0000528 wire_json['special items']['client_handwritten_commands'] += wire_json[
529 'special items']['client_side_commands']
Corentin Wallez540abab2019-11-22 13:18:22 +0000530
Corentin Wallez031fbbb2019-06-11 18:03:05 +0000531 # Generate commands from object methods
532 for api_object in wire_params['by_category']['object']:
533 for method in api_object.methods:
534 command_name = concat_names(api_object.name, method.name)
535 command_suffix = Name(command_name).CamelCase()
536
Kai Ninomiya01aeca22020-07-15 19:51:17 +0000537 # Only object return values or void are supported.
538 # Other methods must be handwritten.
539 is_object = method.return_type.category == 'object'
540 is_void = method.return_type.name.canonical_case() == 'void'
541 if not (is_object or is_void):
542 assert command_suffix in (
543 wire_json['special items']['client_handwritten_commands'])
Corentin Wallez031fbbb2019-06-11 18:03:05 +0000544 continue
545
Kai Ninomiya01aeca22020-07-15 19:51:17 +0000546 if command_suffix in (
547 wire_json['special items']['client_side_commands']):
Corentin Wallez031fbbb2019-06-11 18:03:05 +0000548 continue
549
550 # Create object method commands by prepending "self"
Kai Ninomiya01aeca22020-07-15 19:51:17 +0000551 members = [
552 RecordMember(Name('self'), types[api_object.dict_name],
Kai Ninomiya930e9182021-09-17 19:44:43 +0000553 'value', {})
Kai Ninomiya01aeca22020-07-15 19:51:17 +0000554 ]
Corentin Wallez031fbbb2019-06-11 18:03:05 +0000555 members += method.arguments
556
Kai Ninomiya01aeca22020-07-15 19:51:17 +0000557 # Client->Server commands that return an object return the
558 # result object handle
Corentin Wallez031fbbb2019-06-11 18:03:05 +0000559 if method.return_type.category == 'object':
Kai Ninomiya01aeca22020-07-15 19:51:17 +0000560 result = RecordMember(Name('result'),
561 types['ObjectHandle'],
Kai Ninomiya930e9182021-09-17 19:44:43 +0000562 'value', {},
Kai Ninomiya01aeca22020-07-15 19:51:17 +0000563 is_return_value=True)
Corentin Wallez031fbbb2019-06-11 18:03:05 +0000564 result.set_handle_type(method.return_type)
565 members.append(result)
566
567 command = Command(command_name, members)
568 command.derived_object = api_object
569 command.derived_method = method
570 commands.append(command)
571
572 for (name, json_data) in wire_json['commands'].items():
573 commands.append(Command(name, linked_record_members(json_data, types)))
574
575 for (name, json_data) in wire_json['return commands'].items():
Kai Ninomiya01aeca22020-07-15 19:51:17 +0000576 return_commands.append(
577 Command(name, linked_record_members(json_data, types)))
Corentin Wallez031fbbb2019-06-11 18:03:05 +0000578
579 wire_params['cmd_records'] = {
580 'command': commands,
581 'return command': return_commands
582 }
583
584 for commands in wire_params['cmd_records'].values():
585 for command in commands:
586 command.update_metadata()
587 commands.sort(key=lambda c: c.name.canonical_case())
588
589 wire_params.update(wire_json.get('special items', {}))
590
591 return wire_params
592
Brendon Tiszkaa0456432023-03-23 16:02:20 +0000593############################################################
594# DAWN LPM FUZZ STUFF
595############################################################
596
597
598def compute_lpm_params(api_and_wire_params, lpm_json):
599 # Start with all commands in dawn.json and dawn_wire.json
600 lpm_params = api_and_wire_params.copy()
601
Brendon Tiszka1f8413f2023-05-02 21:41:22 +0000602 # Commands that are built through codegen
603 generated_commands = []
Brendon Tiszkaa0456432023-03-23 16:02:20 +0000604
605 # All commands, including hand written commands that we can't generate
606 # through codegen
Brendon Tiszka1f8413f2023-05-02 21:41:22 +0000607 all_commands = []
Brendon Tiszkaa0456432023-03-23 16:02:20 +0000608
609 # Remove blocklisted commands from protobuf generation params
610 blocklisted_cmds_proto = lpm_json.get('blocklisted_cmds')
611 custom_cmds_proto = lpm_json.get('custom_cmds')
612 for command in lpm_params['cmd_records']['command']:
613 blocklisted = command.name.get() in blocklisted_cmds_proto
614 custom = command.name.get() in custom_cmds_proto
615
Brendon Tiszka1f8413f2023-05-02 21:41:22 +0000616 if blocklisted:
617 continue
618
619 if not custom:
620 generated_commands.append(command)
621 all_commands.append(command)
Brendon Tiszkaa0456432023-03-23 16:02:20 +0000622
Brendon Tiszka27521c62023-05-15 22:22:07 +0000623 # Set all fields that are marked as the "length" of another field to
624 # skip_serialize. The values passed by libprotobuf-mutator will cause
625 # an instant crash during serialization if these don't match the length
626 # of the data they are passing. These values aren't used in
627 # deserialization.
628 mark_lengths_non_serializable_lpm(
629 api_and_wire_params['cmd_records']['command'])
630 mark_lengths_non_serializable_lpm(
631 api_and_wire_params['by_category']['structure'])
632
Brendon Tiszkaa0456432023-03-23 16:02:20 +0000633 lpm_params['cmd_records'] = {
Brendon Tiszka1f8413f2023-05-02 21:41:22 +0000634 'proto_generated_commands': generated_commands,
635 'proto_all_commands': all_commands,
Brendon Tiszka27521c62023-05-15 22:22:07 +0000636 'cpp_generated_commands': generated_commands,
637 'lpm_info': lpm_json.get("lpm_info")
Brendon Tiszkaa0456432023-03-23 16:02:20 +0000638 }
639
640 return lpm_params
641
642
643def as_protobufTypeLPM(member):
644 assert 'type' in member.json_data
645
646 if member.type.name.native:
647 typ = member.json_data['type']
648 cpp_to_protobuf_type = {
649 "bool": "bool",
650 "float": "float",
651 "double": "double",
652 "int8_t": "int32",
653 "int16_t": "int32",
654 "int32_t": "int32",
655 "int64_t": "int64",
656 "uint8_t": "uint32",
657 "uint16_t": "uint32",
658 "uint32_t": "uint32",
659 "uint64_t": "uint64",
660 }
661
662 assert typ in cpp_to_protobuf_type
663
664 return cpp_to_protobuf_type[typ]
665
666 return member.type.name.CamelCase()
667
668
Brendon Tiszka27521c62023-05-15 22:22:07 +0000669# Helper that generates names for protobuf grammars from contents
670# of dawn*.json like files. example: membera
Brendon Tiszkaa0456432023-03-23 16:02:20 +0000671def as_protobufNameLPM(*names):
Brendon Tiszka27521c62023-05-15 22:22:07 +0000672 # `descriptor` is a reserved keyword in lib-protobuf-mutator
Brendon Tiszkaa0456432023-03-23 16:02:20 +0000673 if (names[0].concatcase() == "descriptor"):
674 return "desc"
675 return as_varName(*names)
676
677
Brendon Tiszka27521c62023-05-15 22:22:07 +0000678# Helper to generate member accesses within C++ of protobuf objects
679# example: cmd.membera().memberb()
680def as_protobufMemberNameLPM(*names):
681 # `descriptor` is a reserved keyword in lib-protobuf-mutator
682 if (names[0].concatcase() == "descriptor"):
683 return "desc"
684 return ''.join([name.concatcase().lower() for name in names])
685
686
Brendon Tiszkaa0456432023-03-23 16:02:20 +0000687def unreachable_code():
688 assert False
Kai Ninomiya01aeca22020-07-15 19:51:17 +0000689
Brendon Tiszka27521c62023-05-15 22:22:07 +0000690
Corentin Wallezf07e3bd2017-04-20 14:38:20 -0400691#############################################################
Corentin Wallez0c38e922019-06-07 08:59:17 +0000692# Generator
Corentin Wallezf07e3bd2017-04-20 14:38:20 -0400693#############################################################
Corentin Wallezf07e3bd2017-04-20 14:38:20 -0400694
Kai Ninomiya01aeca22020-07-15 19:51:17 +0000695
Corentin Wallezf07e3bd2017-04-20 14:38:20 -0400696def as_varName(*names):
Kai Ninomiya01aeca22020-07-15 19:51:17 +0000697 return names[0].camelCase() + ''.join(
698 [name.CamelCase() for name in names[1:]])
699
Corentin Wallezf07e3bd2017-04-20 14:38:20 -0400700
fujunwei76bda372021-11-23 08:47:35 +0000701def as_cType(c_prefix, name):
Corentin Wallezf07e3bd2017-04-20 14:38:20 -0400702 if name.native:
703 return name.concatcase()
704 else:
fujunwei76bda372021-11-23 08:47:35 +0000705 return c_prefix + name.CamelCase()
Corentin Wallez919812e2019-10-17 08:46:07 +0000706
Kai Ninomiya01aeca22020-07-15 19:51:17 +0000707
Loko Kungcd162942023-06-01 19:03:05 +0000708def as_cReturnType(c_prefix, typ):
709 if typ.category != 'bitmask':
710 return as_cType(c_prefix, typ.name)
711 else:
712 return as_cType(c_prefix, typ.name) + 'Flags'
713
714
Corentin Wallezf07e3bd2017-04-20 14:38:20 -0400715def as_cppType(name):
716 if name.native:
717 return name.concatcase()
718 else:
719 return name.CamelCase()
720
Kai Ninomiya01aeca22020-07-15 19:51:17 +0000721
Kai Ninomiya7b6246a2020-01-28 23:54:38 +0000722def as_jsEnumValue(value):
Kai Ninomiya930e9182021-09-17 19:44:43 +0000723 if 'jsrepr' in value.json_data: return value.json_data['jsrepr']
Kai Ninomiya7b6246a2020-01-28 23:54:38 +0000724 return "'" + value.name.js_enum_case() + "'"
725
Kai Ninomiya01aeca22020-07-15 19:51:17 +0000726
Austin Eng740995c2019-05-15 18:55:22 +0000727def convert_cType_to_cppType(typ, annotation, arg, indent=0):
728 if typ.category == 'native':
729 return arg
730 if annotation == 'value':
731 if typ.category == 'object':
732 return '{}::Acquire({})'.format(as_cppType(typ.name), arg)
733 elif typ.category == 'structure':
734 converted_members = [
735 convert_cType_to_cppType(
736 member.type, member.annotation,
Kai Ninomiya01aeca22020-07-15 19:51:17 +0000737 '{}.{}'.format(arg, as_varName(member.name)), indent + 1)
738 for member in typ.members
739 ]
Austin Eng740995c2019-05-15 18:55:22 +0000740
Kai Ninomiya01aeca22020-07-15 19:51:17 +0000741 converted_members = [(' ' * 4) + m for m in converted_members]
Austin Eng740995c2019-05-15 18:55:22 +0000742 converted_members = ',\n'.join(converted_members)
743
744 return as_cppType(typ.name) + ' {\n' + converted_members + '\n}'
fujunweid3cac112021-12-14 02:20:15 +0000745 elif typ.category == 'function pointer':
746 return 'reinterpret_cast<{}>({})'.format(as_cppType(typ.name), arg)
Austin Eng740995c2019-05-15 18:55:22 +0000747 else:
748 return 'static_cast<{}>({})'.format(as_cppType(typ.name), arg)
749 else:
Kai Ninomiya01aeca22020-07-15 19:51:17 +0000750 return 'reinterpret_cast<{} {}>({})'.format(as_cppType(typ.name),
751 annotation, arg)
752
Austin Eng740995c2019-05-15 18:55:22 +0000753
Corentin Wallezf07e3bd2017-04-20 14:38:20 -0400754def decorate(name, typ, arg):
755 if arg.annotation == 'value':
756 return typ + ' ' + name
Austin Eng740995c2019-05-15 18:55:22 +0000757 elif arg.annotation == '*':
758 return typ + ' * ' + name
Corentin Wallezf07e3bd2017-04-20 14:38:20 -0400759 elif arg.annotation == 'const*':
760 return typ + ' const * ' + name
Austin Eng2f218e22021-12-22 19:02:23 +0000761 elif arg.annotation == 'const*const*':
762 return 'const ' + typ + '* const * ' + name
Corentin Wallezf07e3bd2017-04-20 14:38:20 -0400763 else:
Kai Ninomiya01aeca22020-07-15 19:51:17 +0000764 assert False
765
Corentin Wallezf07e3bd2017-04-20 14:38:20 -0400766
767def annotated(typ, arg):
768 name = as_varName(arg.name)
769 return decorate(name, typ, arg)
770
Kai Ninomiya01aeca22020-07-15 19:51:17 +0000771
Kai Ninomiya930e9182021-09-17 19:44:43 +0000772def item_is_enabled(enabled_tags, json_data):
773 tags = json_data.get('tags')
774 if tags is None: return True
775 return any(tag in enabled_tags for tag in tags)
776
777
Austin Eng2f218e22021-12-22 19:02:23 +0000778def item_is_disabled(disabled_tags, json_data):
779 if disabled_tags is None: return False
780 tags = json_data.get('tags')
781 if tags is None: return False
782
783 return any(tag in disabled_tags for tag in tags)
784
785
Corentin Wallezf07e3bd2017-04-20 14:38:20 -0400786def as_cppEnum(value_name):
Kai Ninomiya01aeca22020-07-15 19:51:17 +0000787 assert not value_name.native
Corentin Wallezf07e3bd2017-04-20 14:38:20 -0400788 if value_name.concatcase()[0].isdigit():
789 return "e" + value_name.CamelCase()
790 return value_name.CamelCase()
791
Kai Ninomiya01aeca22020-07-15 19:51:17 +0000792
Corentin Wallezf07e3bd2017-04-20 14:38:20 -0400793def as_MethodSuffix(type_name, method_name):
Kai Ninomiya01aeca22020-07-15 19:51:17 +0000794 assert not type_name.native and not method_name.native
Corentin Wallezf07e3bd2017-04-20 14:38:20 -0400795 return type_name.CamelCase() + method_name.CamelCase()
796
Kai Ninomiya01aeca22020-07-15 19:51:17 +0000797
fujunwei76bda372021-11-23 08:47:35 +0000798def as_frontendType(metadata, typ):
Corentin Wallezf07e3bd2017-04-20 14:38:20 -0400799 if typ.category == 'object':
Corentin Wallez4f5fc2d2019-04-01 21:48:38 +0000800 return typ.name.CamelCase() + 'Base*'
Corentin Wallezfe253f12018-08-01 15:12:10 +0200801 elif typ.category in ['bitmask', 'enum']:
fujunwei76bda372021-11-23 08:47:35 +0000802 return metadata.namespace + '::' + typ.name.CamelCase()
Corentin Wallezfe253f12018-08-01 15:12:10 +0200803 elif typ.category == 'structure':
804 return as_cppType(typ.name)
Corentin Wallezf07e3bd2017-04-20 14:38:20 -0400805 else:
fujunwei76bda372021-11-23 08:47:35 +0000806 return as_cType(metadata.c_prefix, typ.name)
Corentin Wallezf07e3bd2017-04-20 14:38:20 -0400807
Kai Ninomiya01aeca22020-07-15 19:51:17 +0000808
fujunwei76bda372021-11-23 08:47:35 +0000809def as_wireType(metadata, typ):
Austin Engcb0cb652019-08-27 21:41:56 +0000810 if typ.category == 'object':
811 return typ.name.CamelCase() + '*'
Brandon Jones6f2bbe92021-04-05 23:34:17 +0000812 elif typ.category in ['bitmask', 'enum', 'structure']:
fujunwei76bda372021-11-23 08:47:35 +0000813 return metadata.c_prefix + typ.name.CamelCase()
Austin Engcb0cb652019-08-27 21:41:56 +0000814 else:
815 return as_cppType(typ.name)
816
Kai Ninomiya01aeca22020-07-15 19:51:17 +0000817
Loko Kung4d835252022-03-19 00:21:48 +0000818def as_formatType(typ):
819 # Unsigned integral types
820 if typ.json_data['type'] in ['bool', 'uint32_t', 'uint64_t']:
821 return 'u'
822
823 # Defaults everything else to strings.
824 return 's'
825
826
Kai Ninomiya930e9182021-09-17 19:44:43 +0000827def c_methods(params, typ):
Corentin Wallezaca8c4a2019-11-22 14:02:52 +0000828 return typ.methods + [
Corentin Wallez2c89f5c2023-05-23 09:39:29 +0000829 Method(Name('reference'), params['types']['void'], [], False, {}),
830 Method(Name('release'), params['types']['void'], [], False, {}),
Corentin Wallez4b410a32017-04-20 14:42:36 -0400831 ]
832
Corentin Wallezaca8c4a2019-11-22 14:02:52 +0000833def get_c_methods_sorted_by_name(api_params):
Corentin Wallezc57b1802019-10-15 12:08:48 +0000834 unsorted = [(as_MethodSuffix(typ.name, method.name), typ, method) \
835 for typ in api_params['by_category']['object'] \
Kai Ninomiya930e9182021-09-17 19:44:43 +0000836 for method in c_methods(api_params, typ) ]
Corentin Wallezc57b1802019-10-15 12:08:48 +0000837 return [(typ, method) for (_, typ, method) in sorted(unsorted)]
838
Kai Ninomiya01aeca22020-07-15 19:51:17 +0000839
Corentin Wallez540abab2019-11-22 13:18:22 +0000840def has_callback_arguments(method):
fujunwei23f71622021-12-02 07:41:21 +0000841 return any(arg.type.category == 'function pointer' for arg in method.arguments)
Corentin Wallez540abab2019-11-22 13:18:22 +0000842
Kai Ninomiya01aeca22020-07-15 19:51:17 +0000843
fujunwei76bda372021-11-23 08:47:35 +0000844def make_base_render_params(metadata):
845 c_prefix = metadata.c_prefix
846
847 def as_cTypeEnumSpecialCase(typ):
848 if typ.category == 'bitmask':
849 return as_cType(c_prefix, typ.name) + 'Flags'
850 return as_cType(c_prefix, typ.name)
851
852 def as_cEnum(type_name, value_name):
853 assert not type_name.native and not value_name.native
854 return c_prefix + type_name.CamelCase() + '_' + value_name.CamelCase()
855
856 def as_cMethod(type_name, method_name):
fujunwei23f71622021-12-02 07:41:21 +0000857 c_method = c_prefix.lower()
858 if type_name != None:
859 assert not type_name.native
860 c_method += type_name.CamelCase()
861 assert not method_name.native
862 c_method += method_name.CamelCase()
863 return c_method
fujunwei76bda372021-11-23 08:47:35 +0000864
865 def as_cProc(type_name, method_name):
fujunwei23f71622021-12-02 07:41:21 +0000866 c_proc = c_prefix + 'Proc'
867 if type_name != None:
868 assert not type_name.native
869 c_proc += type_name.CamelCase()
870 assert not method_name.native
871 c_proc += method_name.CamelCase()
872 return c_proc
fujunwei76bda372021-11-23 08:47:35 +0000873
874 return {
875 'Name': lambda name: Name(name),
876 'as_annotated_cType': \
877 lambda arg: annotated(as_cTypeEnumSpecialCase(arg.type), arg),
878 'as_annotated_cppType': \
879 lambda arg: annotated(as_cppType(arg.type.name), arg),
880 'as_cEnum': as_cEnum,
881 'as_cppEnum': as_cppEnum,
882 'as_cMethod': as_cMethod,
883 'as_MethodSuffix': as_MethodSuffix,
884 'as_cProc': as_cProc,
885 'as_cType': lambda name: as_cType(c_prefix, name),
Loko Kungcd162942023-06-01 19:03:05 +0000886 'as_cReturnType': lambda typ: as_cReturnType(c_prefix, typ),
fujunwei76bda372021-11-23 08:47:35 +0000887 'as_cppType': as_cppType,
888 'as_jsEnumValue': as_jsEnumValue,
889 'convert_cType_to_cppType': convert_cType_to_cppType,
890 'as_varName': as_varName,
Loko Kung4d835252022-03-19 00:21:48 +0000891 'decorate': decorate,
892 'as_formatType': as_formatType
fujunwei76bda372021-11-23 08:47:35 +0000893 }
894
895
Corentin Wallez0c38e922019-06-07 08:59:17 +0000896class MultiGeneratorFromDawnJSON(Generator):
897 def get_description(self):
898 return 'Generates code for various target from Dawn.json.'
Corentin Wallezf07e3bd2017-04-20 14:38:20 -0400899
Corentin Wallez0c38e922019-06-07 08:59:17 +0000900 def add_commandline_arguments(self, parser):
Kai Ninomiya01aeca22020-07-15 19:51:17 +0000901 allowed_targets = [
Ben Clayton35940f92022-02-04 17:15:16 +0000902 'dawn_headers', 'cpp_headers', 'cpp', 'proc', 'mock_api', 'wire',
Brendon Tiszkad0b284b2023-02-08 20:43:18 +0000903 'native_utils', 'dawn_lpmfuzz_cpp', 'dawn_lpmfuzz_proto'
Kai Ninomiya01aeca22020-07-15 19:51:17 +0000904 ]
Corentin Wallezf07e3bd2017-04-20 14:38:20 -0400905
Kai Ninomiya01aeca22020-07-15 19:51:17 +0000906 parser.add_argument('--dawn-json',
907 required=True,
908 type=str,
909 help='The DAWN JSON definition to use.')
910 parser.add_argument('--wire-json',
911 default=None,
912 type=str,
913 help='The DAWN WIRE JSON definition to use.')
Brendon Tiszkad0b284b2023-02-08 20:43:18 +0000914 parser.add_argument("--lpm-json",
915 default=None,
916 type=str,
917 help='The DAWN LPM FUZZER definitions to use.')
Kai Ninomiya01aeca22020-07-15 19:51:17 +0000918 parser.add_argument(
919 '--targets',
920 required=True,
921 type=str,
922 help=
923 'Comma-separated subset of targets to output. Available targets: '
924 + ', '.join(allowed_targets))
Brendon Tiszkad0b284b2023-02-08 20:43:18 +0000925
Corentin Wallez0c38e922019-06-07 08:59:17 +0000926 def get_file_renders(self, args):
927 with open(args.dawn_json) as f:
928 loaded_json = json.loads(f.read())
Corentin Wallezf07e3bd2017-04-20 14:38:20 -0400929
Corentin Wallez0c38e922019-06-07 08:59:17 +0000930 targets = args.targets.split(',')
Corentin Wallez4b410a32017-04-20 14:42:36 -0400931
Corentin Wallez0c38e922019-06-07 08:59:17 +0000932 wire_json = None
933 if args.wire_json:
934 with open(args.wire_json) as f:
935 wire_json = json.loads(f.read())
Corentin Wallezf07e3bd2017-04-20 14:38:20 -0400936
Brendon Tiszkad0b284b2023-02-08 20:43:18 +0000937 lpm_json = None
938 if args.lpm_json:
939 with open(args.lpm_json) as f:
940 lpm_json = json.loads(f.read())
941
Kai Ninomiya930e9182021-09-17 19:44:43 +0000942 renders = []
943
Kai Ninomiya930e9182021-09-17 19:44:43 +0000944 params_dawn = parse_json(loaded_json,
945 enabled_tags=['dawn', 'native', 'deprecated'])
fujunwei76bda372021-11-23 08:47:35 +0000946 metadata = params_dawn['metadata']
947 RENDER_PARAMS_BASE = make_base_render_params(metadata)
Corentin Wallez79a62bf2017-05-24 16:04:55 +0200948
fujunweic7d4f2c2021-12-07 00:46:35 +0000949 api = metadata.api.lower()
fujunweia8405742021-12-10 01:35:19 +0000950 prefix = metadata.proc_table_prefix.lower()
Ben Clayton35940f92022-02-04 17:15:16 +0000951 if 'headers' in targets:
Kai Ninomiya01aeca22020-07-15 19:51:17 +0000952 renders.append(
Ben Clayton9fb7a512022-02-04 18:18:18 +0000953 FileRender('api.h', 'include/dawn/' + api + '.h',
Kai Ninomiya930e9182021-09-17 19:44:43 +0000954 [RENDER_PARAMS_BASE, params_dawn]))
Kai Ninomiya01aeca22020-07-15 19:51:17 +0000955 renders.append(
956 FileRender('dawn_proc_table.h',
Ben Clayton9fb7a512022-02-04 18:18:18 +0000957 'include/dawn/' + prefix + '_proc_table.h',
Kai Ninomiya930e9182021-09-17 19:44:43 +0000958 [RENDER_PARAMS_BASE, params_dawn]))
Corentin Wallezf07e3bd2017-04-20 14:38:20 -0400959
Ben Clayton35940f92022-02-04 17:15:16 +0000960 if 'cpp_headers' in targets:
Kai Ninomiya01aeca22020-07-15 19:51:17 +0000961 renders.append(
Ben Clayton9fb7a512022-02-04 18:18:18 +0000962 FileRender('api_cpp.h', 'include/dawn/' + api + '_cpp.h',
Kai Ninomiya930e9182021-09-17 19:44:43 +0000963 [RENDER_PARAMS_BASE, params_dawn]))
Austin Engcc071e42019-10-16 10:26:01 +0000964
Austin Enga9e39e12021-06-01 18:49:12 +0000965 renders.append(
fujunweic7d4f2c2021-12-07 00:46:35 +0000966 FileRender('api_cpp_print.h',
Ben Clayton9fb7a512022-02-04 18:18:18 +0000967 'include/dawn/' + api + '_cpp_print.h',
Kai Ninomiya930e9182021-09-17 19:44:43 +0000968 [RENDER_PARAMS_BASE, params_dawn]))
Austin Enga9e39e12021-06-01 18:49:12 +0000969
Loko Kung14ed5332023-05-16 04:50:32 +0000970 renders.append(
971 FileRender('api_cpp_chained_struct.h',
972 'include/dawn/' + api + '_cpp_chained_struct.h',
973 [RENDER_PARAMS_BASE, params_dawn]))
974
Ben Clayton35940f92022-02-04 17:15:16 +0000975 if 'proc' in targets:
Kai Ninomiya01aeca22020-07-15 19:51:17 +0000976 renders.append(
fujunweia8405742021-12-10 01:35:19 +0000977 FileRender('dawn_proc.c', 'src/dawn/' + prefix + '_proc.c',
Kai Ninomiya930e9182021-09-17 19:44:43 +0000978 [RENDER_PARAMS_BASE, params_dawn]))
Austin Eng16e01af2020-10-06 16:13:42 +0000979 renders.append(
980 FileRender('dawn_thread_dispatch_proc.cpp',
fujunweia8405742021-12-10 01:35:19 +0000981 'src/dawn/' + prefix + '_thread_dispatch_proc.cpp',
Kai Ninomiya930e9182021-09-17 19:44:43 +0000982 [RENDER_PARAMS_BASE, params_dawn]))
Corentin Wallez96496822019-10-15 11:44:38 +0000983
Austin Eng63f65462021-12-09 20:03:48 +0000984 if 'webgpu_dawn_native_proc' in targets:
985 renders.append(
Ben Clayton818001d2022-02-04 17:07:46 +0000986 FileRender('dawn/native/api_dawn_native_proc.cpp',
987 'src/dawn/native/webgpu_dawn_native_proc.cpp',
Austin Eng63f65462021-12-09 20:03:48 +0000988 [RENDER_PARAMS_BASE, params_dawn]))
989
Ben Clayton35940f92022-02-04 17:15:16 +0000990 if 'cpp' in targets:
Kai Ninomiya01aeca22020-07-15 19:51:17 +0000991 renders.append(
fujunweid3cac112021-12-14 02:20:15 +0000992 FileRender('api_cpp.cpp', 'src/dawn/' + api + '_cpp.cpp',
Kai Ninomiya930e9182021-09-17 19:44:43 +0000993 [RENDER_PARAMS_BASE, params_dawn]))
994
995 if 'webgpu_headers' in targets:
996 params_upstream = parse_json(loaded_json,
Shrek Shao1554a7d2022-03-08 20:56:10 +0000997 enabled_tags=['upstream', 'native'],
998 disabled_tags=['dawn'])
Kai Ninomiya930e9182021-09-17 19:44:43 +0000999 renders.append(
fujunweic7d4f2c2021-12-07 00:46:35 +00001000 FileRender('api.h', 'webgpu-headers/' + api + '.h',
Kai Ninomiya930e9182021-09-17 19:44:43 +00001001 [RENDER_PARAMS_BASE, params_upstream]))
Corentin Wallez59e7fad2018-08-16 15:32:35 +02001002
Kai Ninomiya7b6246a2020-01-28 23:54:38 +00001003 if 'emscripten_bits' in targets:
Shrek Shaoee50bc02022-02-08 20:21:40 +00001004 params_emscripten = parse_json(loaded_json,
1005 enabled_tags=['emscripten'])
Kai Ninomiya930e9182021-09-17 19:44:43 +00001006 renders.append(
fujunweic7d4f2c2021-12-07 00:46:35 +00001007 FileRender('api.h', 'emscripten-bits/' + api + '.h',
Kai Ninomiya930e9182021-09-17 19:44:43 +00001008 [RENDER_PARAMS_BASE, params_emscripten]))
1009 renders.append(
fujunweic7d4f2c2021-12-07 00:46:35 +00001010 FileRender('api_cpp.h', 'emscripten-bits/' + api + '_cpp.h',
Kai Ninomiya930e9182021-09-17 19:44:43 +00001011 [RENDER_PARAMS_BASE, params_emscripten]))
1012 renders.append(
fujunweid3cac112021-12-14 02:20:15 +00001013 FileRender('api_cpp.cpp', 'emscripten-bits/' + api + '_cpp.cpp',
Kai Ninomiya930e9182021-09-17 19:44:43 +00001014 [RENDER_PARAMS_BASE, params_emscripten]))
Kai Ninomiya01aeca22020-07-15 19:51:17 +00001015 renders.append(
fujunwei16ae3b82021-12-15 04:35:26 +00001016 FileRender('api_struct_info.json',
1017 'emscripten-bits/' + api + '_struct_info.json',
Kai Ninomiya930e9182021-09-17 19:44:43 +00001018 [RENDER_PARAMS_BASE, params_emscripten]))
Kai Ninomiya01aeca22020-07-15 19:51:17 +00001019 renders.append(
fujunwei16ae3b82021-12-15 04:35:26 +00001020 FileRender('library_api_enum_tables.js',
1021 'emscripten-bits/library_' + api + '_enum_tables.js',
Kai Ninomiya930e9182021-09-17 19:44:43 +00001022 [RENDER_PARAMS_BASE, params_emscripten]))
Kai Ninomiya7b6246a2020-01-28 23:54:38 +00001023
fujunwei16ae3b82021-12-15 04:35:26 +00001024 if 'mock_api' in targets:
Corentin Wallez540abab2019-11-22 13:18:22 +00001025 mock_params = [
Kai Ninomiya930e9182021-09-17 19:44:43 +00001026 RENDER_PARAMS_BASE, params_dawn, {
Corentin Wallez540abab2019-11-22 13:18:22 +00001027 'has_callback_arguments': has_callback_arguments
1028 }
1029 ]
Kai Ninomiya01aeca22020-07-15 19:51:17 +00001030 renders.append(
fujunwei16ae3b82021-12-15 04:35:26 +00001031 FileRender('mock_api.h', 'src/dawn/mock_' + api + '.h',
Kai Ninomiya01aeca22020-07-15 19:51:17 +00001032 mock_params))
1033 renders.append(
fujunwei16ae3b82021-12-15 04:35:26 +00001034 FileRender('mock_api.cpp', 'src/dawn/mock_' + api + '.cpp',
Kai Ninomiya01aeca22020-07-15 19:51:17 +00001035 mock_params))
Corentin Wallez59e7fad2018-08-16 15:32:35 +02001036
Ben Clayton818001d2022-02-04 17:07:46 +00001037 if 'native_utils' in targets:
Corentin Wallez0c38e922019-06-07 08:59:17 +00001038 frontend_params = [
Kai Ninomiya930e9182021-09-17 19:44:43 +00001039 RENDER_PARAMS_BASE,
1040 params_dawn,
Corentin Wallez0c38e922019-06-07 08:59:17 +00001041 {
Kai Ninomiya01aeca22020-07-15 19:51:17 +00001042 # TODO: as_frontendType and co. take a Type, not a Name :(
fujunwei76bda372021-11-23 08:47:35 +00001043 'as_frontendType': lambda typ: as_frontendType(metadata, typ),
Kai Ninomiya01aeca22020-07-15 19:51:17 +00001044 'as_annotated_frontendType': \
fujunwei76bda372021-11-23 08:47:35 +00001045 lambda arg: annotated(as_frontendType(metadata, arg.type), arg),
Corentin Wallez0c38e922019-06-07 08:59:17 +00001046 }
1047 ]
Corentin Wallez59e7fad2018-08-16 15:32:35 +02001048
fujunweia2241d42021-12-16 04:54:38 +00001049 impl_dir = metadata.impl_dir + '/' if metadata.impl_dir else ''
Ben Clayton818001d2022-02-04 17:07:46 +00001050 native_dir = impl_dir + Name(metadata.native_namespace).Dirs()
fujunwei7f3f8ac2021-12-21 03:27:34 +00001051 namespace = metadata.namespace
Kai Ninomiya01aeca22020-07-15 19:51:17 +00001052 renders.append(
Ben Clayton818001d2022-02-04 17:07:46 +00001053 FileRender('dawn/native/ValidationUtils.h',
fujunweia2241d42021-12-16 04:54:38 +00001054 'src/' + native_dir + '/ValidationUtils_autogen.h',
Kai Ninomiya01aeca22020-07-15 19:51:17 +00001055 frontend_params))
1056 renders.append(
Ben Clayton818001d2022-02-04 17:07:46 +00001057 FileRender('dawn/native/ValidationUtils.cpp',
fujunweia2241d42021-12-16 04:54:38 +00001058 'src/' + native_dir + '/ValidationUtils_autogen.cpp',
Kai Ninomiya01aeca22020-07-15 19:51:17 +00001059 frontend_params))
1060 renders.append(
Ben Clayton818001d2022-02-04 17:07:46 +00001061 FileRender('dawn/native/dawn_platform.h',
fujunweifc38f7d2021-12-17 00:46:08 +00001062 'src/' + native_dir + '/' + prefix + '_platform_autogen.h',
Austin Eng3faa4782021-10-27 19:07:37 +00001063 frontend_params))
1064 renders.append(
Ben Clayton818001d2022-02-04 17:07:46 +00001065 FileRender('dawn/native/api_structs.h',
fujunwei7f3f8ac2021-12-21 03:27:34 +00001066 'src/' + native_dir + '/' + namespace + '_structs_autogen.h',
Kai Ninomiya01aeca22020-07-15 19:51:17 +00001067 frontend_params))
1068 renders.append(
Ben Clayton818001d2022-02-04 17:07:46 +00001069 FileRender('dawn/native/api_structs.cpp',
fujunwei7f3f8ac2021-12-21 03:27:34 +00001070 'src/' + native_dir + '/' + namespace + '_structs_autogen.cpp',
Kai Ninomiya01aeca22020-07-15 19:51:17 +00001071 frontend_params))
1072 renders.append(
Ben Clayton818001d2022-02-04 17:07:46 +00001073 FileRender('dawn/native/ProcTable.cpp',
Ningxin Hu7e5930b2021-12-22 06:12:13 +00001074 'src/' + native_dir + '/ProcTable.cpp', frontend_params))
Brian Ho5346e772021-04-22 17:49:42 +00001075 renders.append(
Ben Clayton818001d2022-02-04 17:07:46 +00001076 FileRender('dawn/native/ChainUtils.h',
fujunwei2b1dcd92021-12-22 01:05:03 +00001077 'src/' + native_dir + '/ChainUtils_autogen.h',
Brian Ho5346e772021-04-22 17:49:42 +00001078 frontend_params))
1079 renders.append(
Ben Clayton818001d2022-02-04 17:07:46 +00001080 FileRender('dawn/native/ChainUtils.cpp',
fujunwei2b1dcd92021-12-22 01:05:03 +00001081 'src/' + native_dir + '/ChainUtils_autogen.cpp',
Brian Ho5346e772021-04-22 17:49:42 +00001082 frontend_params))
Brandon Jonesba662952021-09-23 21:26:33 +00001083 renders.append(
Ben Clayton818001d2022-02-04 17:07:46 +00001084 FileRender('dawn/native/api_absl_format.h',
fujunweif001ef52021-12-23 05:16:04 +00001085 'src/' + native_dir + '/' + api + '_absl_format_autogen.h',
Brandon Jonesba662952021-09-23 21:26:33 +00001086 frontend_params))
1087 renders.append(
Ben Clayton818001d2022-02-04 17:07:46 +00001088 FileRender('dawn/native/api_absl_format.cpp',
fujunweif001ef52021-12-23 05:16:04 +00001089 'src/' + native_dir + '/' + api + '_absl_format_autogen.cpp',
Brandon Jonesba662952021-09-23 21:26:33 +00001090 frontend_params))
Loko Kung8d195d52021-09-28 15:40:01 +00001091 renders.append(
Austin Engbc285fb2022-07-29 00:36:21 +00001092 FileRender(
1093 'dawn/native/api_StreamImpl.cpp', 'src/' + native_dir +
1094 '/' + api + '_StreamImpl_autogen.cpp', frontend_params))
1095 renders.append(
Ben Clayton818001d2022-02-04 17:07:46 +00001096 FileRender('dawn/native/ObjectType.h',
fujunwei2b1dcd92021-12-22 01:05:03 +00001097 'src/' + native_dir + '/ObjectType_autogen.h',
Loko Kung8d195d52021-09-28 15:40:01 +00001098 frontend_params))
1099 renders.append(
Ben Clayton818001d2022-02-04 17:07:46 +00001100 FileRender('dawn/native/ObjectType.cpp',
fujunwei2b1dcd92021-12-22 01:05:03 +00001101 'src/' + native_dir + '/ObjectType_autogen.cpp',
Loko Kung8d195d52021-09-28 15:40:01 +00001102 frontend_params))
Corentin Wallez59e7fad2018-08-16 15:32:35 +02001103
Ben Clayton20cbe6d2022-02-04 12:51:25 +00001104 if 'wire' in targets:
Austin Eng2f218e22021-12-22 19:02:23 +00001105 params_dawn_wire = parse_json(loaded_json,
1106 enabled_tags=['dawn', 'deprecated'],
1107 disabled_tags=['native'])
1108 additional_params = compute_wire_params(params_dawn_wire,
1109 wire_json)
Corentin Wallez59e7fad2018-08-16 15:32:35 +02001110
Corentin Wallez0c38e922019-06-07 08:59:17 +00001111 wire_params = [
Austin Eng2f218e22021-12-22 19:02:23 +00001112 RENDER_PARAMS_BASE, params_dawn_wire, {
fujunwei76bda372021-11-23 08:47:35 +00001113 'as_wireType': lambda type : as_wireType(metadata, type),
Kai Ninomiya01aeca22020-07-15 19:51:17 +00001114 'as_annotated_wireType': \
fujunwei76bda372021-11-23 08:47:35 +00001115 lambda arg: annotated(as_wireType(metadata, arg.type), arg),
Kai Ninomiya01aeca22020-07-15 19:51:17 +00001116 }, additional_params
Corentin Wallez0c38e922019-06-07 08:59:17 +00001117 ]
Kai Ninomiya01aeca22020-07-15 19:51:17 +00001118 renders.append(
Ben Clayton20cbe6d2022-02-04 12:51:25 +00001119 FileRender('dawn/wire/ObjectType.h',
1120 'src/dawn/wire/ObjectType_autogen.h', wire_params))
Austin Eng3120d5e2020-11-11 19:46:18 +00001121 renders.append(
Ben Clayton20cbe6d2022-02-04 12:51:25 +00001122 FileRender('dawn/wire/WireCmd.h',
1123 'src/dawn/wire/WireCmd_autogen.h', wire_params))
Kai Ninomiya01aeca22020-07-15 19:51:17 +00001124 renders.append(
Ben Clayton20cbe6d2022-02-04 12:51:25 +00001125 FileRender('dawn/wire/WireCmd.cpp',
1126 'src/dawn/wire/WireCmd_autogen.cpp', wire_params))
Kai Ninomiya01aeca22020-07-15 19:51:17 +00001127 renders.append(
Ben Clayton20cbe6d2022-02-04 12:51:25 +00001128 FileRender('dawn/wire/client/ApiObjects.h',
1129 'src/dawn/wire/client/ApiObjects_autogen.h',
Kai Ninomiya01aeca22020-07-15 19:51:17 +00001130 wire_params))
1131 renders.append(
Ben Clayton20cbe6d2022-02-04 12:51:25 +00001132 FileRender('dawn/wire/client/ApiProcs.cpp',
1133 'src/dawn/wire/client/ApiProcs_autogen.cpp',
Kai Ninomiya01aeca22020-07-15 19:51:17 +00001134 wire_params))
1135 renders.append(
Ben Clayton20cbe6d2022-02-04 12:51:25 +00001136 FileRender('dawn/wire/client/ClientBase.h',
1137 'src/dawn/wire/client/ClientBase_autogen.h',
Kai Ninomiya01aeca22020-07-15 19:51:17 +00001138 wire_params))
1139 renders.append(
Ben Clayton20cbe6d2022-02-04 12:51:25 +00001140 FileRender('dawn/wire/client/ClientHandlers.cpp',
1141 'src/dawn/wire/client/ClientHandlers_autogen.cpp',
Kai Ninomiya01aeca22020-07-15 19:51:17 +00001142 wire_params))
1143 renders.append(
1144 FileRender(
Ben Clayton20cbe6d2022-02-04 12:51:25 +00001145 'dawn/wire/client/ClientPrototypes.inc',
1146 'src/dawn/wire/client/ClientPrototypes_autogen.inc',
Kai Ninomiya01aeca22020-07-15 19:51:17 +00001147 wire_params))
1148 renders.append(
Ben Clayton20cbe6d2022-02-04 12:51:25 +00001149 FileRender('dawn/wire/server/ServerBase.h',
1150 'src/dawn/wire/server/ServerBase_autogen.h',
Kai Ninomiya01aeca22020-07-15 19:51:17 +00001151 wire_params))
1152 renders.append(
Ben Clayton20cbe6d2022-02-04 12:51:25 +00001153 FileRender('dawn/wire/server/ServerDoers.cpp',
1154 'src/dawn/wire/server/ServerDoers_autogen.cpp',
Kai Ninomiya01aeca22020-07-15 19:51:17 +00001155 wire_params))
1156 renders.append(
Ben Clayton20cbe6d2022-02-04 12:51:25 +00001157 FileRender('dawn/wire/server/ServerHandlers.cpp',
1158 'src/dawn/wire/server/ServerHandlers_autogen.cpp',
Kai Ninomiya01aeca22020-07-15 19:51:17 +00001159 wire_params))
1160 renders.append(
1161 FileRender(
Ben Clayton20cbe6d2022-02-04 12:51:25 +00001162 'dawn/wire/server/ServerPrototypes.inc',
1163 'src/dawn/wire/server/ServerPrototypes_autogen.inc',
Kai Ninomiya01aeca22020-07-15 19:51:17 +00001164 wire_params))
Corentin Wallez59e7fad2018-08-16 15:32:35 +02001165
Brendon Tiszkad0b284b2023-02-08 20:43:18 +00001166 if 'dawn_lpmfuzz_proto' in targets:
1167 params_dawn_wire = parse_json(loaded_json,
1168 enabled_tags=['dawn', 'deprecated'],
1169 disabled_tags=['native'])
Brendon Tiszkaa0456432023-03-23 16:02:20 +00001170 api_and_wire_params = compute_wire_params(params_dawn_wire,
1171 wire_json)
1172
1173 fuzzer_params = compute_lpm_params(api_and_wire_params, lpm_json)
Brendon Tiszkad0b284b2023-02-08 20:43:18 +00001174
1175 lpm_params = [
Brendon Tiszkaa0456432023-03-23 16:02:20 +00001176 RENDER_PARAMS_BASE, params_dawn_wire, {
1177 'as_protobufTypeLPM': as_protobufTypeLPM,
1178 'as_protobufNameLPM': as_protobufNameLPM,
1179 'unreachable': unreachable_code
1180 }, api_and_wire_params, fuzzer_params
Brendon Tiszkad0b284b2023-02-08 20:43:18 +00001181 ]
1182
1183 renders.append(
1184 FileRender('dawn/fuzzers/lpmfuzz/dawn_lpm.proto',
1185 'src/dawn/fuzzers/lpmfuzz/dawn_lpm_autogen.proto',
1186 lpm_params))
1187
Brendon Tiszka1f8413f2023-05-02 21:41:22 +00001188 renders.append(
1189 FileRender(
1190 'dawn/fuzzers/lpmfuzz/dawn_object_types_lpm.proto',
1191 'src/dawn/fuzzers/lpmfuzz/dawn_object_types_lpm_autogen.proto',
1192 lpm_params))
1193
Brendon Tiszkad0b284b2023-02-08 20:43:18 +00001194 if 'dawn_lpmfuzz_cpp' in targets:
1195 params_dawn_wire = parse_json(loaded_json,
1196 enabled_tags=['dawn', 'deprecated'],
1197 disabled_tags=['native'])
Brendon Tiszkaa0456432023-03-23 16:02:20 +00001198 api_and_wire_params = compute_wire_params(params_dawn_wire,
1199 wire_json)
Brendon Tiszkad0b284b2023-02-08 20:43:18 +00001200
Brendon Tiszka1f8413f2023-05-02 21:41:22 +00001201 fuzzer_params = compute_lpm_params(api_and_wire_params, lpm_json)
1202
Brendon Tiszkad0b284b2023-02-08 20:43:18 +00001203 lpm_params = [
Brendon Tiszka27521c62023-05-15 22:22:07 +00001204 RENDER_PARAMS_BASE, params_dawn_wire, {
1205 'as_protobufMemberName': as_protobufMemberNameLPM,
1206 'unreachable_code': unreachable_code
1207 }, api_and_wire_params, fuzzer_params
Brendon Tiszkad0b284b2023-02-08 20:43:18 +00001208 ]
1209
1210 renders.append(
1211 FileRender(
1212 'dawn/fuzzers/lpmfuzz/DawnLPMSerializer.cpp',
1213 'src/dawn/fuzzers/lpmfuzz/DawnLPMSerializer_autogen.cpp',
1214 lpm_params))
1215
1216 renders.append(
1217 FileRender(
1218 'dawn/fuzzers/lpmfuzz/DawnLPMSerializer.h',
1219 'src/dawn/fuzzers/lpmfuzz/DawnLPMSerializer_autogen.h',
1220 lpm_params))
1221
Brendon Tiszkaa0456432023-03-23 16:02:20 +00001222 renders.append(
1223 FileRender(
1224 'dawn/fuzzers/lpmfuzz/DawnLPMConstants.h',
1225 'src/dawn/fuzzers/lpmfuzz/DawnLPMConstants_autogen.h',
1226 lpm_params))
1227
Corentin Wallez0c38e922019-06-07 08:59:17 +00001228 return renders
Corentin Wallez59e7fad2018-08-16 15:32:35 +02001229
Corentin Wallez0c38e922019-06-07 08:59:17 +00001230 def get_dependencies(self, args):
1231 deps = [os.path.abspath(args.dawn_json)]
1232 if args.wire_json != None:
1233 deps += [os.path.abspath(args.wire_json)]
Brendon Tiszkad0b284b2023-02-08 20:43:18 +00001234 if args.lpm_json != None:
1235 deps += [os.path.abspath(args.lpm_json)]
Corentin Wallez0c38e922019-06-07 08:59:17 +00001236 return deps
Corentin Wallezf07e3bd2017-04-20 14:38:20 -04001237
Kai Ninomiya01aeca22020-07-15 19:51:17 +00001238
Corentin Wallezf07e3bd2017-04-20 14:38:20 -04001239if __name__ == '__main__':
Corentin Wallez0c38e922019-06-07 08:59:17 +00001240 sys.exit(run_generator(MultiGeneratorFromDawnJSON()))