blob: 72851b8abf45af0583b657f78cc31a1a30232c87 [file] [log] [blame]
Corentin Wallez59382b72020-04-17 20:43:07 +00001#!/usr/bin/env python3
Austin Engcc2516a2023-10-17 20:57:54 +00002# Copyright 2017 The Dawn & Tint Authors
Corentin Wallezf07e3bd2017-04-20 14:38:20 -04003#
Austin Engcc2516a2023-10-17 20:57:54 +00004# Redistribution and use in source and binary forms, with or without
5# modification, are permitted provided that the following conditions are met:
Corentin Wallezf07e3bd2017-04-20 14:38:20 -04006#
Austin Engcc2516a2023-10-17 20:57:54 +00007# 1. Redistributions of source code must retain the above copyright notice, this
8# list of conditions and the following disclaimer.
Corentin Wallezf07e3bd2017-04-20 14:38:20 -04009#
Austin Engcc2516a2023-10-17 20:57:54 +000010# 2. Redistributions in binary form must reproduce the above copyright notice,
11# this list of conditions and the following disclaimer in the documentation
12# and/or other materials provided with the distribution.
13#
14# 3. Neither the name of the copyright holder nor the names of its
15# contributors may be used to endorse or promote products derived from
16# this software without specific prior written permission.
17#
18# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
19# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
21# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
22# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
24# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
25# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
26# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
27# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
Corentin Wallezf07e3bd2017-04-20 14:38:20 -040028
Corentin Wallez0c38e922019-06-07 08:59:17 +000029import json, os, sys
Corentin Wallezf07e3bd2017-04-20 14:38:20 -040030from collections import namedtuple
Corentin Wallez0c38e922019-06-07 08:59:17 +000031
Corentin Wallez0c38e922019-06-07 08:59:17 +000032from generator_lib import Generator, run_generator, FileRender
Corentin Wallez031fbbb2019-06-11 18:03:05 +000033
34############################################################
35# OBJECT MODEL
36############################################################
37
Kai Ninomiya01aeca22020-07-15 19:51:17 +000038
fujunwei76bda372021-11-23 08:47:35 +000039class Metadata:
40 def __init__(self, metadata):
41 self.api = metadata['api']
42 self.namespace = metadata['namespace']
43 self.c_prefix = metadata.get('c_prefix', self.namespace.upper())
fujunwei3a464762021-12-05 05:29:44 +000044 self.proc_table_prefix = metadata['proc_table_prefix']
fujunweia2241d42021-12-16 04:54:38 +000045 self.impl_dir = metadata.get('impl_dir', '')
46 self.native_namespace = metadata['native_namespace']
fujunwei76bda372021-11-23 08:47:35 +000047 self.copyright_year = metadata.get('copyright_year', None)
48
49
Corentin Wallez031fbbb2019-06-11 18:03:05 +000050class Name:
51 def __init__(self, name, native=False):
52 self.native = native
Austin Eng76a8d0b2020-04-03 17:37:48 +000053 self.name = name
Corentin Wallez031fbbb2019-06-11 18:03:05 +000054 if native:
55 self.chunks = [name]
56 else:
57 self.chunks = name.split(' ')
58
Austin Eng76a8d0b2020-04-03 17:37:48 +000059 def get(self):
60 return self.name
61
Corentin Wallez031fbbb2019-06-11 18:03:05 +000062 def CamelChunk(self, chunk):
63 return chunk[0].upper() + chunk[1:]
64
65 def canonical_case(self):
Corentin Wallez7d256c72023-12-01 16:27:15 +000066 return ' '.join(self.chunks)
Corentin Wallez031fbbb2019-06-11 18:03:05 +000067
68 def concatcase(self):
69 return ''.join(self.chunks)
70
71 def camelCase(self):
Kai Ninomiya01aeca22020-07-15 19:51:17 +000072 return self.chunks[0] + ''.join(
73 [self.CamelChunk(chunk) for chunk in self.chunks[1:]])
Corentin Wallez031fbbb2019-06-11 18:03:05 +000074
75 def CamelCase(self):
76 return ''.join([self.CamelChunk(chunk) for chunk in self.chunks])
77
78 def SNAKE_CASE(self):
79 return '_'.join([chunk.upper() for chunk in self.chunks])
80
81 def snake_case(self):
82 return '_'.join(self.chunks)
83
Corentin Wallezec9cf2a2022-01-12 09:17:35 +000084 def namespace_case(self):
85 return '::'.join(self.chunks)
86
Ben Clayton20cbe6d2022-02-04 12:51:25 +000087 def Dirs(self):
88 return '/'.join(self.chunks)
89
Kai Ninomiya7b6246a2020-01-28 23:54:38 +000090 def js_enum_case(self):
91 result = self.chunks[0].lower()
92 for chunk in self.chunks[1:]:
93 if not result[-1].isdigit():
94 result += '-'
95 result += chunk.lower()
96 return result
97
Kai Ninomiya01aeca22020-07-15 19:51:17 +000098
Corentin Wallez031fbbb2019-06-11 18:03:05 +000099def concat_names(*names):
100 return ' '.join([name.canonical_case() for name in names])
101
Kai Ninomiya01aeca22020-07-15 19:51:17 +0000102
Corentin Wallez031fbbb2019-06-11 18:03:05 +0000103class Type:
104 def __init__(self, name, json_data, native=False):
105 self.json_data = json_data
106 self.dict_name = name
107 self.name = Name(name, native=native)
108 self.category = json_data['category']
Jiawei Shao6d6b63c2021-12-02 07:29:41 +0000109 self.is_wire_transparent = False
Corentin Wallez031fbbb2019-06-11 18:03:05 +0000110
Kai Ninomiya01aeca22020-07-15 19:51:17 +0000111
Kai Ninomiya930e9182021-09-17 19:44:43 +0000112EnumValue = namedtuple('EnumValue', ['name', 'value', 'valid', 'json_data'])
Kai Ninomiya01aeca22020-07-15 19:51:17 +0000113
114
Corentin Wallez031fbbb2019-06-11 18:03:05 +0000115class EnumType(Type):
Kai Ninomiya930e9182021-09-17 19:44:43 +0000116 def __init__(self, is_enabled, name, json_data):
Corentin Wallez031fbbb2019-06-11 18:03:05 +0000117 Type.__init__(self, name, json_data)
Kai Ninomiya7b6246a2020-01-28 23:54:38 +0000118
119 self.values = []
Kai Ninomiya98dce272024-01-04 08:14:00 +0000120 self.hasUndefined = False
Kai Ninomiya7b6246a2020-01-28 23:54:38 +0000121 self.contiguousFromZero = True
122 lastValue = -1
123 for m in self.json_data['values']:
Kai Ninomiya930e9182021-09-17 19:44:43 +0000124 if not is_enabled(m):
125 continue
Kai Ninomiya7b6246a2020-01-28 23:54:38 +0000126 value = m['value']
Kai Ninomiya98dce272024-01-04 08:14:00 +0000127 name = m['name']
128 if name == "undefined":
129 assert value == 0
130 self.hasUndefined = True
Kai Ninomiya7b6246a2020-01-28 23:54:38 +0000131 if value != lastValue + 1:
132 self.contiguousFromZero = False
133 lastValue = value
Kai Ninomiya01aeca22020-07-15 19:51:17 +0000134 self.values.append(
Kai Ninomiya98dce272024-01-04 08:14:00 +0000135 EnumValue(Name(name), value, m.get('valid', True), m))
Corentin Wallez031fbbb2019-06-11 18:03:05 +0000136
Corentin Wallez7ac08152019-06-26 19:54:43 +0000137 # Assert that all values are unique in enums
138 all_values = set()
139 for value in self.values:
140 if value.value in all_values:
Kai Ninomiya01aeca22020-07-15 19:51:17 +0000141 raise Exception("Duplicate value {} in enum {}".format(
142 value.value, name))
Corentin Wallez7ac08152019-06-26 19:54:43 +0000143 all_values.add(value.value)
Jiawei Shao6d6b63c2021-12-02 07:29:41 +0000144 self.is_wire_transparent = True
Corentin Wallez7ac08152019-06-26 19:54:43 +0000145
Kai Ninomiya01aeca22020-07-15 19:51:17 +0000146
Kai Ninomiya930e9182021-09-17 19:44:43 +0000147BitmaskValue = namedtuple('BitmaskValue', ['name', 'value', 'json_data'])
Kai Ninomiya01aeca22020-07-15 19:51:17 +0000148
149
Corentin Wallez031fbbb2019-06-11 18:03:05 +0000150class BitmaskType(Type):
Kai Ninomiya930e9182021-09-17 19:44:43 +0000151 def __init__(self, is_enabled, name, json_data):
Corentin Wallez031fbbb2019-06-11 18:03:05 +0000152 Type.__init__(self, name, json_data)
Kai Ninomiya01aeca22020-07-15 19:51:17 +0000153 self.values = [
Kai Ninomiya930e9182021-09-17 19:44:43 +0000154 BitmaskValue(Name(m['name']), m['value'], m)
155 for m in self.json_data['values'] if is_enabled(m)
Kai Ninomiya01aeca22020-07-15 19:51:17 +0000156 ]
Corentin Wallez031fbbb2019-06-11 18:03:05 +0000157 self.full_mask = 0
158 for value in self.values:
159 self.full_mask = self.full_mask | value.value
Jiawei Shao6d6b63c2021-12-02 07:29:41 +0000160 self.is_wire_transparent = True
Corentin Wallez031fbbb2019-06-11 18:03:05 +0000161
Kai Ninomiya01aeca22020-07-15 19:51:17 +0000162
fujunwei23f71622021-12-02 07:41:21 +0000163class FunctionPointerType(Type):
Kai Ninomiya930e9182021-09-17 19:44:43 +0000164 def __init__(self, is_enabled, name, json_data):
Corentin Wallez540abab2019-11-22 13:18:22 +0000165 Type.__init__(self, name, json_data)
fujunwei23f71622021-12-02 07:41:21 +0000166 self.return_type = None
Corentin Wallez540abab2019-11-22 13:18:22 +0000167 self.arguments = []
168
Kai Ninomiya01aeca22020-07-15 19:51:17 +0000169
Brandon Jones58a471a2021-02-08 19:48:06 +0000170class TypedefType(Type):
Kai Ninomiya930e9182021-09-17 19:44:43 +0000171 def __init__(self, is_enabled, name, json_data):
Brandon Jones58a471a2021-02-08 19:48:06 +0000172 Type.__init__(self, name, json_data)
173 self.type = None
174
175
Corentin Wallez031fbbb2019-06-11 18:03:05 +0000176class NativeType(Type):
Kai Ninomiya930e9182021-09-17 19:44:43 +0000177 def __init__(self, is_enabled, name, json_data):
Corentin Wallez031fbbb2019-06-11 18:03:05 +0000178 Type.__init__(self, name, json_data, native=True)
Loko Kung837f1512023-06-06 03:01:15 +0000179 self.is_wire_transparent = json_data.get('wire transparent', True)
Corentin Wallez031fbbb2019-06-11 18:03:05 +0000180
Kai Ninomiya01aeca22020-07-15 19:51:17 +0000181
Corentin Wallez031fbbb2019-06-11 18:03:05 +0000182# Methods and structures are both "records", so record members correspond to
183# method arguments or structure members.
184class RecordMember:
Kai Ninomiya01aeca22020-07-15 19:51:17 +0000185 def __init__(self,
186 name,
187 typ,
188 annotation,
Kai Ninomiya930e9182021-09-17 19:44:43 +0000189 json_data,
Kai Ninomiya01aeca22020-07-15 19:51:17 +0000190 optional=False,
191 is_return_value=False,
192 default_value=None,
Austin Eng6a5418a2019-07-19 16:01:48 +0000193 skip_serialize=False):
Corentin Wallez031fbbb2019-06-11 18:03:05 +0000194 self.name = name
195 self.type = typ
196 self.annotation = annotation
Kai Ninomiya930e9182021-09-17 19:44:43 +0000197 self.json_data = json_data
Corentin Wallez031fbbb2019-06-11 18:03:05 +0000198 self.length = None
199 self.optional = optional
200 self.is_return_value = is_return_value
201 self.handle_type = None
Brendon Tiszka27521c62023-05-15 22:22:07 +0000202 self.id_type = None
Corentin Wallez8f938712019-07-08 19:20:22 +0000203 self.default_value = default_value
Austin Eng6a5418a2019-07-19 16:01:48 +0000204 self.skip_serialize = skip_serialize
Corentin Wallez031fbbb2019-06-11 18:03:05 +0000205
206 def set_handle_type(self, handle_type):
207 assert self.type.dict_name == "ObjectHandle"
208 self.handle_type = handle_type
209
Brendon Tiszka27521c62023-05-15 22:22:07 +0000210 def set_id_type(self, id_type):
211 assert self.type.dict_name == "ObjectId"
212 self.id_type = id_type
213
Kai Ninomiyaa8516c12024-01-09 03:33:23 +0000214 @property
215 def requires_struct_defaulting(self):
216 if self.annotation != "value":
217 return False
218
219 if self.type.category == "structure":
220 return self.type.any_member_requires_struct_defaulting
221 elif self.type.category == "enum":
222 return (self.type.hasUndefined
223 and self.default_value not in [None, "undefined"])
224 else:
225 return False
226
Kai Ninomiya01aeca22020-07-15 19:51:17 +0000227
Le Hoang Quyen7971bfe2023-04-05 19:35:07 +0000228Method = namedtuple(
229 'Method', ['name', 'return_type', 'arguments', 'autolock', 'json_data'])
Kai Ninomiya01aeca22020-07-15 19:51:17 +0000230
231
Corentin Wallez031fbbb2019-06-11 18:03:05 +0000232class ObjectType(Type):
Kai Ninomiya930e9182021-09-17 19:44:43 +0000233 def __init__(self, is_enabled, name, json_data):
234 json_data_override = {'methods': []}
235 if 'methods' in json_data:
236 json_data_override['methods'] = [
237 m for m in json_data['methods'] if is_enabled(m)
238 ]
239 Type.__init__(self, name, dict(json_data, **json_data_override))
Corentin Wallez031fbbb2019-06-11 18:03:05 +0000240
Kai Ninomiya01aeca22020-07-15 19:51:17 +0000241
Corentin Wallez031fbbb2019-06-11 18:03:05 +0000242class Record:
243 def __init__(self, name):
244 self.name = Name(name)
245 self.members = []
Austin Eng76a8d0b2020-04-03 17:37:48 +0000246 self.may_have_dawn_object = False
Corentin Wallez031fbbb2019-06-11 18:03:05 +0000247
248 def update_metadata(self):
Austin Eng76a8d0b2020-04-03 17:37:48 +0000249 def may_have_dawn_object(member):
Corentin Wallez031fbbb2019-06-11 18:03:05 +0000250 if isinstance(member.type, ObjectType):
251 return True
252 elif isinstance(member.type, StructureType):
Austin Eng76a8d0b2020-04-03 17:37:48 +0000253 return member.type.may_have_dawn_object
Corentin Wallez031fbbb2019-06-11 18:03:05 +0000254 else:
255 return False
256
Kai Ninomiya01aeca22020-07-15 19:51:17 +0000257 self.may_have_dawn_object = any(
258 may_have_dawn_object(member) for member in self.members)
Austin Eng76a8d0b2020-04-03 17:37:48 +0000259
Kai Ninomiya01aeca22020-07-15 19:51:17 +0000260 # Set may_have_dawn_object to true if the type is chained or
261 # extensible. Chained structs may contain a Dawn object.
Austin Eng76a8d0b2020-04-03 17:37:48 +0000262 if isinstance(self, StructureType):
Kai Ninomiya01aeca22020-07-15 19:51:17 +0000263 self.may_have_dawn_object = (self.may_have_dawn_object
264 or self.chained or self.extensible)
265
Corentin Wallez031fbbb2019-06-11 18:03:05 +0000266
267class StructureType(Record, Type):
Kai Ninomiya930e9182021-09-17 19:44:43 +0000268 def __init__(self, is_enabled, name, json_data):
Corentin Wallez031fbbb2019-06-11 18:03:05 +0000269 Record.__init__(self, name)
Kai Ninomiya930e9182021-09-17 19:44:43 +0000270 json_data_override = {}
271 if 'members' in json_data:
272 json_data_override['members'] = [
273 m for m in json_data['members'] if is_enabled(m)
274 ]
275 Type.__init__(self, name, dict(json_data, **json_data_override))
Corentin Walleza45561b2022-07-14 12:58:25 +0000276 self.chained = json_data.get('chained', None)
277 self.extensible = json_data.get('extensible', None)
Austin Eng0c824052021-09-20 16:07:25 +0000278 if self.chained:
Corentin Walleza45561b2022-07-14 12:58:25 +0000279 assert self.chained == 'in' or self.chained == 'out'
280 assert 'chain roots' in json_data
Loko Kung0af86f22023-08-17 23:39:51 +0000281 self.chain_roots = []
Austin Eng0c824052021-09-20 16:07:25 +0000282 if self.extensible:
Corentin Walleza45561b2022-07-14 12:58:25 +0000283 assert self.extensible == 'in' or self.extensible == 'out'
Kai Ninomiya01aeca22020-07-15 19:51:17 +0000284 # Chained structs inherit from wgpu::ChainedStruct, which has
285 # nextInChain, so setting both extensible and chained would result in
286 # two nextInChain members.
287 assert not (self.extensible and self.chained)
Loko Kung0af86f22023-08-17 23:39:51 +0000288 self.extensions = []
Kai Ninomiya01aeca22020-07-15 19:51:17 +0000289
Jiawei Shao1fa386c2021-12-21 04:04:51 +0000290 def update_metadata(self):
291 Record.update_metadata(self)
292
293 if self.may_have_dawn_object:
294 self.is_wire_transparent = False
295 return
296
297 assert not (self.chained or self.extensible)
298
299 def get_is_wire_transparent(member):
300 return member.type.is_wire_transparent and member.annotation == 'value'
301
302 self.is_wire_transparent = all(
303 get_is_wire_transparent(m) for m in self.members)
304
Austin Eng0c824052021-09-20 16:07:25 +0000305 @property
306 def output(self):
307 return self.chained == "out" or self.extensible == "out"
308
Austin Eng643625a2023-08-09 00:59:33 +0000309 @property
310 def has_free_members_function(self):
311 if not self.output:
312 return False
313 for m in self.members:
314 if m.annotation != 'value':
315 return True
316 return False
317
Kai Ninomiya98dce272024-01-04 08:14:00 +0000318 @property
319 def any_member_requires_struct_defaulting(self):
320 return any(member.requires_struct_defaulting
321 for member in self.members)
322
Corentin Wallez031fbbb2019-06-11 18:03:05 +0000323
fujunwei4e876902021-11-25 08:44:01 +0000324class ConstantDefinition():
325 def __init__(self, is_enabled, name, json_data):
326 self.type = None
327 self.value = json_data['value']
328 self.json_data = json_data
329 self.name = Name(name)
330
331
fujunwei23f71622021-12-02 07:41:21 +0000332class FunctionDeclaration():
Austin Eng643625a2023-08-09 00:59:33 +0000333 def __init__(self, is_enabled, name, json_data, no_cpp=False):
fujunwei23f71622021-12-02 07:41:21 +0000334 self.return_type = None
335 self.arguments = []
336 self.json_data = json_data
337 self.name = Name(name)
Austin Eng643625a2023-08-09 00:59:33 +0000338 self.no_cpp = no_cpp
fujunwei23f71622021-12-02 07:41:21 +0000339
340
Corentin Wallez031fbbb2019-06-11 18:03:05 +0000341class Command(Record):
342 def __init__(self, name, members=None):
343 Record.__init__(self, name)
344 self.members = members or []
345 self.derived_object = None
346 self.derived_method = None
347
Kai Ninomiya01aeca22020-07-15 19:51:17 +0000348
Corentin Wallez031fbbb2019-06-11 18:03:05 +0000349def linked_record_members(json_data, types):
350 members = []
351 members_by_name = {}
352 for m in json_data:
Kai Ninomiya01aeca22020-07-15 19:51:17 +0000353 member = RecordMember(Name(m['name']),
354 types[m['type']],
Corentin Wallez8f938712019-07-08 19:20:22 +0000355 m.get('annotation', 'value'),
Kai Ninomiya930e9182021-09-17 19:44:43 +0000356 m,
Corentin Wallez8f938712019-07-08 19:20:22 +0000357 optional=m.get('optional', False),
358 is_return_value=m.get('is_return_value', False),
Austin Eng6a5418a2019-07-19 16:01:48 +0000359 default_value=m.get('default', None),
360 skip_serialize=m.get('skip_serialize', False))
Corentin Wallez031fbbb2019-06-11 18:03:05 +0000361 handle_type = m.get('handle_type')
362 if handle_type:
363 member.set_handle_type(types[handle_type])
Brendon Tiszka27521c62023-05-15 22:22:07 +0000364 id_type = m.get('id_type')
365 if id_type:
366 member.set_id_type(types[id_type])
Corentin Wallez031fbbb2019-06-11 18:03:05 +0000367 members.append(member)
368 members_by_name[member.name.canonical_case()] = member
369
370 for (member, m) in zip(members, json_data):
371 if member.annotation != 'value':
372 if not 'length' in m:
373 if member.type.category != 'object':
374 member.length = "constant"
375 member.constant_length = 1
376 else:
Kai Ninomiya01aeca22020-07-15 19:51:17 +0000377 assert False
Corentin Wallez031fbbb2019-06-11 18:03:05 +0000378 elif m['length'] == 'strlen':
379 member.length = 'strlen'
Yan52040532021-12-15 04:08:56 +0000380 elif isinstance(m['length'], int):
381 assert m['length'] > 0
382 member.length = "constant"
383 member.constant_length = m['length']
Corentin Wallez031fbbb2019-06-11 18:03:05 +0000384 else:
385 member.length = members_by_name[m['length']]
386
387 return members
Corentin Walleza6416542018-05-17 16:55:53 -0400388
Kai Ninomiya01aeca22020-07-15 19:51:17 +0000389
Brendon Tiszka27521c62023-05-15 22:22:07 +0000390def mark_lengths_non_serializable_lpm(record_members):
391 # Remove member length values from command metadata,
392 # these are set to the length of the protobuf array.
393 for record_member in record_members:
394 lengths = set()
395 for member in record_member.members:
396 lengths.add(member.length)
397
398 for member in record_member.members:
399 if member in lengths:
400 member.skip_serialize = True
401
Corentin Wallezf07e3bd2017-04-20 14:38:20 -0400402############################################################
403# PARSE
404############################################################
Corentin Wallez4b410a32017-04-20 14:42:36 -0400405
Kai Ninomiya01aeca22020-07-15 19:51:17 +0000406
Corentin Walleze2f94842018-12-05 17:49:04 +0000407def link_object(obj, types):
Le Hoang Quyen7971bfe2023-04-05 19:35:07 +0000408 # Disable method's autolock if obj's "no autolock" = True
409 obj_scoped_autolock_enabled = not obj.json_data.get('no autolock', False)
410
Corentin Walleze2f94842018-12-05 17:49:04 +0000411 def make_method(json_data):
Corentin Wallez031fbbb2019-06-11 18:03:05 +0000412 arguments = linked_record_members(json_data.get('args', []), types)
Le Hoang Quyen7971bfe2023-04-05 19:35:07 +0000413 autolock_enabled = obj_scoped_autolock_enabled and not json_data.get(
414 'no autolock', False)
Kai Ninomiya01aeca22020-07-15 19:51:17 +0000415 return Method(Name(json_data['name']),
Le Hoang Quyen7971bfe2023-04-05 19:35:07 +0000416 types[json_data.get('returns', 'void')], arguments,
417 autolock_enabled, json_data)
Corentin Walleze2f94842018-12-05 17:49:04 +0000418
Corentin Wallezaca8c4a2019-11-22 14:02:52 +0000419 obj.methods = [make_method(m) for m in obj.json_data.get('methods', [])]
Corentin Wallez97231682019-10-08 07:38:01 +0000420 obj.methods.sort(key=lambda method: method.name.canonical_case())
Corentin Wallezf07e3bd2017-04-20 14:38:20 -0400421
Kai Ninomiya01aeca22020-07-15 19:51:17 +0000422
Corentin Walleza6416542018-05-17 16:55:53 -0400423def link_structure(struct, types):
Corentin Wallez031fbbb2019-06-11 18:03:05 +0000424 struct.members = linked_record_members(struct.json_data['members'], types)
Loko Kung0af86f22023-08-17 23:39:51 +0000425 for root in struct.json_data.get('chain roots', []):
426 struct.chain_roots.append(types[root])
427 types[root].extensions.append(struct)
Corentin Walleza45561b2022-07-14 12:58:25 +0000428 struct.chain_roots = [types[root] for root in struct.json_data.get('chain roots', [])]
429 assert all((root.category == 'structure' for root in struct.chain_roots))
Corentin Walleza6416542018-05-17 16:55:53 -0400430
Corentin Wallez540abab2019-11-22 13:18:22 +0000431
fujunwei23f71622021-12-02 07:41:21 +0000432def link_function_pointer(function_pointer, types):
433 link_function(function_pointer, types)
Kai Ninomiya01aeca22020-07-15 19:51:17 +0000434
435
Brandon Jones58a471a2021-02-08 19:48:06 +0000436def link_typedef(typedef, types):
437 typedef.type = types[typedef.json_data['type']]
438
439
fujunwei4e876902021-11-25 08:44:01 +0000440def link_constant(constant, types):
441 constant.type = types[constant.json_data['type']]
442 assert constant.type.name.native
443
444
fujunwei23f71622021-12-02 07:41:21 +0000445def link_function(function, types):
446 function.return_type = types[function.json_data.get('returns', 'void')]
447 function.arguments = linked_record_members(function.json_data['args'],
448 types)
449
Kai Ninomiya01aeca22020-07-15 19:51:17 +0000450# Sort structures so that if struct A has struct B as a member, then B is
451# listed before A.
452#
453# This is a form of topological sort where we try to keep the order reasonably
454# similar to the original order (though the sort isn't technically stable).
455#
456# It works by computing for each struct type what is the depth of its DAG of
Kai Ninomiya7d174a12021-09-21 17:36:27 +0000457# dependents, then re-sorting based on that depth using Python's stable sort.
Kai Ninomiya01aeca22020-07-15 19:51:17 +0000458# This makes a toposort because if A depends on B then its depth will be bigger
459# than B's. It is also nice because all nodes with the same depth are kept in
460# the input order.
Corentin Wallez29353d62018-09-18 12:49:22 +0000461def topo_sort_structure(structs):
462 for struct in structs:
463 struct.visited = False
464 struct.subdag_depth = 0
465
466 def compute_depth(struct):
467 if struct.visited:
468 return struct.subdag_depth
469
470 max_dependent_depth = 0
471 for member in struct.members:
Corentin Walleze2f94842018-12-05 17:49:04 +0000472 if member.type.category == 'structure':
Kai Ninomiya01aeca22020-07-15 19:51:17 +0000473 max_dependent_depth = max(max_dependent_depth,
474 compute_depth(member.type) + 1)
Corentin Wallez29353d62018-09-18 12:49:22 +0000475
476 struct.subdag_depth = max_dependent_depth
477 struct.visited = True
478 return struct.subdag_depth
479
480 for struct in structs:
481 compute_depth(struct)
482
483 result = sorted(structs, key=lambda struct: struct.subdag_depth)
484
485 for struct in structs:
486 del struct.visited
487 del struct.subdag_depth
488
489 return result
490
Kai Ninomiya01aeca22020-07-15 19:51:17 +0000491
Austin Eng2f218e22021-12-22 19:02:23 +0000492def parse_json(json, enabled_tags, disabled_tags=None):
493 is_enabled = lambda json_data: item_is_enabled(
494 enabled_tags, json_data) and not item_is_disabled(
495 disabled_tags, json_data)
Corentin Wallezf07e3bd2017-04-20 14:38:20 -0400496 category_to_parser = {
Corentin Wallez031fbbb2019-06-11 18:03:05 +0000497 'bitmask': BitmaskType,
498 'enum': EnumType,
499 'native': NativeType,
fujunwei23f71622021-12-02 07:41:21 +0000500 'function pointer': FunctionPointerType,
Corentin Wallez031fbbb2019-06-11 18:03:05 +0000501 'object': ObjectType,
502 'structure': StructureType,
Brandon Jones58a471a2021-02-08 19:48:06 +0000503 'typedef': TypedefType,
fujunwei4e876902021-11-25 08:44:01 +0000504 'constant': ConstantDefinition,
fujunwei23f71622021-12-02 07:41:21 +0000505 'function': FunctionDeclaration
Corentin Wallezf07e3bd2017-04-20 14:38:20 -0400506 }
507
508 types = {}
509
510 by_category = {}
511 for name in category_to_parser.keys():
512 by_category[name] = []
513
Corentin Walleze2f94842018-12-05 17:49:04 +0000514 for (name, json_data) in json.items():
Austin Eng2f218e22021-12-22 19:02:23 +0000515 if name[0] == '_' or not is_enabled(json_data):
Corentin Wallezf07e3bd2017-04-20 14:38:20 -0400516 continue
Corentin Walleze2f94842018-12-05 17:49:04 +0000517 category = json_data['category']
Kai Ninomiya930e9182021-09-17 19:44:43 +0000518 parsed = category_to_parser[category](is_enabled, name, json_data)
Corentin Wallezf07e3bd2017-04-20 14:38:20 -0400519 by_category[category].append(parsed)
520 types[name] = parsed
521
522 for obj in by_category['object']:
523 link_object(obj, types)
524
Corentin Walleza6416542018-05-17 16:55:53 -0400525 for struct in by_category['structure']:
526 link_structure(struct, types)
527
Austin Eng643625a2023-08-09 00:59:33 +0000528 if struct.has_free_members_function:
529 name = struct.name.get() + " free members"
530 func_decl = FunctionDeclaration(
531 True,
532 name, {
533 "returns":
534 "void",
535 "args": [{
536 "name": "value",
537 "type": struct.name.get(),
538 "annotation": "value",
539 }]
540 },
541 no_cpp=True)
542 types[name] = func_decl
543 by_category['function'].append(func_decl)
544
fujunwei23f71622021-12-02 07:41:21 +0000545 for function_pointer in by_category['function pointer']:
546 link_function_pointer(function_pointer, types)
Corentin Wallez540abab2019-11-22 13:18:22 +0000547
Brandon Jones58a471a2021-02-08 19:48:06 +0000548 for typedef in by_category['typedef']:
549 link_typedef(typedef, types)
550
fujunwei4e876902021-11-25 08:44:01 +0000551 for constant in by_category['constant']:
552 link_constant(constant, types)
553
fujunwei23f71622021-12-02 07:41:21 +0000554 for function in by_category['function']:
555 link_function(function, types)
556
Corentin Wallezf07e3bd2017-04-20 14:38:20 -0400557 for category in by_category.keys():
Kai Ninomiya01aeca22020-07-15 19:51:17 +0000558 by_category[category] = sorted(
559 by_category[category], key=lambda typ: typ.name.canonical_case())
Corentin Wallezf07e3bd2017-04-20 14:38:20 -0400560
Corentin Wallez29353d62018-09-18 12:49:22 +0000561 by_category['structure'] = topo_sort_structure(by_category['structure'])
562
Austin Engc7f416c2019-01-15 20:49:53 +0000563 for struct in by_category['structure']:
564 struct.update_metadata()
565
Kai Ninomiya930e9182021-09-17 19:44:43 +0000566 api_params = {
567 'types': types,
568 'by_category': by_category,
569 'enabled_tags': enabled_tags,
Austin Eng2f218e22021-12-22 19:02:23 +0000570 'disabled_tags': disabled_tags,
Kai Ninomiya930e9182021-09-17 19:44:43 +0000571 }
572 return {
fujunwei76bda372021-11-23 08:47:35 +0000573 'metadata': Metadata(json['_metadata']),
Kai Ninomiya930e9182021-09-17 19:44:43 +0000574 'types': types,
575 'by_category': by_category,
576 'enabled_tags': enabled_tags,
Austin Eng2f218e22021-12-22 19:02:23 +0000577 'disabled_tags': disabled_tags,
Kai Ninomiya930e9182021-09-17 19:44:43 +0000578 'c_methods': lambda typ: c_methods(api_params, typ),
579 'c_methods_sorted_by_name': get_c_methods_sorted_by_name(api_params),
580 }
Kai Ninomiya01aeca22020-07-15 19:51:17 +0000581
Corentin Wallezf07e3bd2017-04-20 14:38:20 -0400582
Corentin Wallez031fbbb2019-06-11 18:03:05 +0000583############################################################
584# WIRE STUFF
585############################################################
586
Kai Ninomiya01aeca22020-07-15 19:51:17 +0000587
Corentin Wallez031fbbb2019-06-11 18:03:05 +0000588# Create wire commands from api methods
589def compute_wire_params(api_params, wire_json):
590 wire_params = api_params.copy()
591 types = wire_params['types']
592
593 commands = []
594 return_commands = []
595
Kai Ninomiya01aeca22020-07-15 19:51:17 +0000596 wire_json['special items']['client_handwritten_commands'] += wire_json[
597 'special items']['client_side_commands']
Corentin Wallez540abab2019-11-22 13:18:22 +0000598
Corentin Wallez031fbbb2019-06-11 18:03:05 +0000599 # Generate commands from object methods
600 for api_object in wire_params['by_category']['object']:
601 for method in api_object.methods:
602 command_name = concat_names(api_object.name, method.name)
603 command_suffix = Name(command_name).CamelCase()
604
Kai Ninomiya01aeca22020-07-15 19:51:17 +0000605 # Only object return values or void are supported.
606 # Other methods must be handwritten.
607 is_object = method.return_type.category == 'object'
608 is_void = method.return_type.name.canonical_case() == 'void'
609 if not (is_object or is_void):
610 assert command_suffix in (
Kai Ninomiya8d524b22023-09-02 01:11:30 +0000611 wire_json['special items']['client_handwritten_commands']
612 ), command_suffix
Corentin Wallez031fbbb2019-06-11 18:03:05 +0000613 continue
614
Kai Ninomiya01aeca22020-07-15 19:51:17 +0000615 if command_suffix in (
616 wire_json['special items']['client_side_commands']):
Corentin Wallez031fbbb2019-06-11 18:03:05 +0000617 continue
618
619 # Create object method commands by prepending "self"
Kai Ninomiya01aeca22020-07-15 19:51:17 +0000620 members = [
621 RecordMember(Name('self'), types[api_object.dict_name],
Kai Ninomiya930e9182021-09-17 19:44:43 +0000622 'value', {})
Kai Ninomiya01aeca22020-07-15 19:51:17 +0000623 ]
Corentin Wallez031fbbb2019-06-11 18:03:05 +0000624 members += method.arguments
625
Kai Ninomiya01aeca22020-07-15 19:51:17 +0000626 # Client->Server commands that return an object return the
627 # result object handle
Corentin Wallez031fbbb2019-06-11 18:03:05 +0000628 if method.return_type.category == 'object':
Kai Ninomiya01aeca22020-07-15 19:51:17 +0000629 result = RecordMember(Name('result'),
630 types['ObjectHandle'],
Kai Ninomiya930e9182021-09-17 19:44:43 +0000631 'value', {},
Kai Ninomiya01aeca22020-07-15 19:51:17 +0000632 is_return_value=True)
Corentin Wallez031fbbb2019-06-11 18:03:05 +0000633 result.set_handle_type(method.return_type)
634 members.append(result)
635
636 command = Command(command_name, members)
637 command.derived_object = api_object
638 command.derived_method = method
639 commands.append(command)
640
641 for (name, json_data) in wire_json['commands'].items():
642 commands.append(Command(name, linked_record_members(json_data, types)))
643
644 for (name, json_data) in wire_json['return commands'].items():
Kai Ninomiya01aeca22020-07-15 19:51:17 +0000645 return_commands.append(
646 Command(name, linked_record_members(json_data, types)))
Corentin Wallez031fbbb2019-06-11 18:03:05 +0000647
648 wire_params['cmd_records'] = {
649 'command': commands,
650 'return command': return_commands
651 }
652
653 for commands in wire_params['cmd_records'].values():
654 for command in commands:
655 command.update_metadata()
656 commands.sort(key=lambda c: c.name.canonical_case())
657
658 wire_params.update(wire_json.get('special items', {}))
659
660 return wire_params
661
Brendon Tiszkaa0456432023-03-23 16:02:20 +0000662############################################################
663# DAWN LPM FUZZ STUFF
664############################################################
665
666
667def compute_lpm_params(api_and_wire_params, lpm_json):
668 # Start with all commands in dawn.json and dawn_wire.json
669 lpm_params = api_and_wire_params.copy()
670
Brendon Tiszka1f8413f2023-05-02 21:41:22 +0000671 # Commands that are built through codegen
672 generated_commands = []
Brendon Tiszkaa0456432023-03-23 16:02:20 +0000673
674 # All commands, including hand written commands that we can't generate
675 # through codegen
Brendon Tiszka1f8413f2023-05-02 21:41:22 +0000676 all_commands = []
Brendon Tiszkaa0456432023-03-23 16:02:20 +0000677
678 # Remove blocklisted commands from protobuf generation params
679 blocklisted_cmds_proto = lpm_json.get('blocklisted_cmds')
680 custom_cmds_proto = lpm_json.get('custom_cmds')
681 for command in lpm_params['cmd_records']['command']:
682 blocklisted = command.name.get() in blocklisted_cmds_proto
683 custom = command.name.get() in custom_cmds_proto
684
Brendon Tiszka1f8413f2023-05-02 21:41:22 +0000685 if blocklisted:
686 continue
687
688 if not custom:
689 generated_commands.append(command)
690 all_commands.append(command)
Brendon Tiszkaa0456432023-03-23 16:02:20 +0000691
Brendon Tiszka27521c62023-05-15 22:22:07 +0000692 # Set all fields that are marked as the "length" of another field to
693 # skip_serialize. The values passed by libprotobuf-mutator will cause
694 # an instant crash during serialization if these don't match the length
695 # of the data they are passing. These values aren't used in
696 # deserialization.
697 mark_lengths_non_serializable_lpm(
698 api_and_wire_params['cmd_records']['command'])
699 mark_lengths_non_serializable_lpm(
700 api_and_wire_params['by_category']['structure'])
701
Brendon Tiszkaa0456432023-03-23 16:02:20 +0000702 lpm_params['cmd_records'] = {
Brendon Tiszka1f8413f2023-05-02 21:41:22 +0000703 'proto_generated_commands': generated_commands,
704 'proto_all_commands': all_commands,
Brendon Tiszka27521c62023-05-15 22:22:07 +0000705 'cpp_generated_commands': generated_commands,
706 'lpm_info': lpm_json.get("lpm_info")
Brendon Tiszkaa0456432023-03-23 16:02:20 +0000707 }
708
709 return lpm_params
710
711
712def as_protobufTypeLPM(member):
713 assert 'type' in member.json_data
714
715 if member.type.name.native:
716 typ = member.json_data['type']
717 cpp_to_protobuf_type = {
718 "bool": "bool",
719 "float": "float",
720 "double": "double",
721 "int8_t": "int32",
722 "int16_t": "int32",
723 "int32_t": "int32",
724 "int64_t": "int64",
725 "uint8_t": "uint32",
726 "uint16_t": "uint32",
727 "uint32_t": "uint32",
728 "uint64_t": "uint64",
Brendon Tiszka881dc3b2023-09-20 12:22:26 +0000729 "size_t": "uint64",
Brendon Tiszkaa0456432023-03-23 16:02:20 +0000730 }
731
732 assert typ in cpp_to_protobuf_type
733
734 return cpp_to_protobuf_type[typ]
735
736 return member.type.name.CamelCase()
737
738
Brendon Tiszka27521c62023-05-15 22:22:07 +0000739# Helper that generates names for protobuf grammars from contents
740# of dawn*.json like files. example: membera
Brendon Tiszkaa0456432023-03-23 16:02:20 +0000741def as_protobufNameLPM(*names):
Brendon Tiszka27521c62023-05-15 22:22:07 +0000742 # `descriptor` is a reserved keyword in lib-protobuf-mutator
Brendon Tiszkaa0456432023-03-23 16:02:20 +0000743 if (names[0].concatcase() == "descriptor"):
744 return "desc"
745 return as_varName(*names)
746
747
Brendon Tiszka27521c62023-05-15 22:22:07 +0000748# Helper to generate member accesses within C++ of protobuf objects
749# example: cmd.membera().memberb()
750def as_protobufMemberNameLPM(*names):
751 # `descriptor` is a reserved keyword in lib-protobuf-mutator
752 if (names[0].concatcase() == "descriptor"):
753 return "desc"
754 return ''.join([name.concatcase().lower() for name in names])
755
756
Brendon Tiszkaa0456432023-03-23 16:02:20 +0000757def unreachable_code():
758 assert False
Kai Ninomiya01aeca22020-07-15 19:51:17 +0000759
Brendon Tiszka27521c62023-05-15 22:22:07 +0000760
Corentin Wallezf07e3bd2017-04-20 14:38:20 -0400761#############################################################
Corentin Wallez0c38e922019-06-07 08:59:17 +0000762# Generator
Corentin Wallezf07e3bd2017-04-20 14:38:20 -0400763#############################################################
Corentin Wallezf07e3bd2017-04-20 14:38:20 -0400764
Kai Ninomiya01aeca22020-07-15 19:51:17 +0000765
Corentin Wallezf07e3bd2017-04-20 14:38:20 -0400766def as_varName(*names):
Kai Ninomiya01aeca22020-07-15 19:51:17 +0000767 return names[0].camelCase() + ''.join(
768 [name.CamelCase() for name in names[1:]])
769
Corentin Wallezf07e3bd2017-04-20 14:38:20 -0400770
fujunwei76bda372021-11-23 08:47:35 +0000771def as_cType(c_prefix, name):
Loko Kung440a30c2023-08-04 23:41:21 +0000772 # Special case for 'bool' because it has a typedef for compatibility.
773 if name.native and name.get() != 'bool':
Corentin Wallezf07e3bd2017-04-20 14:38:20 -0400774 return name.concatcase()
775 else:
fujunwei76bda372021-11-23 08:47:35 +0000776 return c_prefix + name.CamelCase()
Corentin Wallez919812e2019-10-17 08:46:07 +0000777
Kai Ninomiya01aeca22020-07-15 19:51:17 +0000778
Loko Kungcd162942023-06-01 19:03:05 +0000779def as_cReturnType(c_prefix, typ):
780 if typ.category != 'bitmask':
781 return as_cType(c_prefix, typ.name)
782 else:
783 return as_cType(c_prefix, typ.name) + 'Flags'
784
785
Corentin Wallezf07e3bd2017-04-20 14:38:20 -0400786def as_cppType(name):
Loko Kung440a30c2023-08-04 23:41:21 +0000787 # Special case for 'bool' because it has a typedef for compatibility.
788 if name.native and name.get() != 'bool':
Corentin Wallezf07e3bd2017-04-20 14:38:20 -0400789 return name.concatcase()
790 else:
791 return name.CamelCase()
792
Kai Ninomiya01aeca22020-07-15 19:51:17 +0000793
Kai Ninomiya7b6246a2020-01-28 23:54:38 +0000794def as_jsEnumValue(value):
Kai Ninomiya930e9182021-09-17 19:44:43 +0000795 if 'jsrepr' in value.json_data: return value.json_data['jsrepr']
Kai Ninomiya7b6246a2020-01-28 23:54:38 +0000796 return "'" + value.name.js_enum_case() + "'"
797
Kai Ninomiya01aeca22020-07-15 19:51:17 +0000798
Austin Eng740995c2019-05-15 18:55:22 +0000799def convert_cType_to_cppType(typ, annotation, arg, indent=0):
800 if typ.category == 'native':
801 return arg
802 if annotation == 'value':
803 if typ.category == 'object':
804 return '{}::Acquire({})'.format(as_cppType(typ.name), arg)
805 elif typ.category == 'structure':
806 converted_members = [
807 convert_cType_to_cppType(
808 member.type, member.annotation,
Kai Ninomiya01aeca22020-07-15 19:51:17 +0000809 '{}.{}'.format(arg, as_varName(member.name)), indent + 1)
810 for member in typ.members
811 ]
Austin Eng740995c2019-05-15 18:55:22 +0000812
Kai Ninomiya01aeca22020-07-15 19:51:17 +0000813 converted_members = [(' ' * 4) + m for m in converted_members]
Austin Eng740995c2019-05-15 18:55:22 +0000814 converted_members = ',\n'.join(converted_members)
815
816 return as_cppType(typ.name) + ' {\n' + converted_members + '\n}'
fujunweid3cac112021-12-14 02:20:15 +0000817 elif typ.category == 'function pointer':
818 return 'reinterpret_cast<{}>({})'.format(as_cppType(typ.name), arg)
Austin Eng740995c2019-05-15 18:55:22 +0000819 else:
820 return 'static_cast<{}>({})'.format(as_cppType(typ.name), arg)
821 else:
Kai Ninomiya01aeca22020-07-15 19:51:17 +0000822 return 'reinterpret_cast<{} {}>({})'.format(as_cppType(typ.name),
823 annotation, arg)
824
Austin Eng740995c2019-05-15 18:55:22 +0000825
Austin Eng643625a2023-08-09 00:59:33 +0000826def decorate(name, typ, arg, make_const=False):
827 maybe_const = ' const ' if make_const else ' '
Corentin Wallezf07e3bd2017-04-20 14:38:20 -0400828 if arg.annotation == 'value':
Austin Eng643625a2023-08-09 00:59:33 +0000829 return typ + maybe_const + name
Austin Eng740995c2019-05-15 18:55:22 +0000830 elif arg.annotation == '*':
Austin Eng643625a2023-08-09 00:59:33 +0000831 return typ + ' *' + maybe_const + name
Corentin Wallezf07e3bd2017-04-20 14:38:20 -0400832 elif arg.annotation == 'const*':
Austin Eng643625a2023-08-09 00:59:33 +0000833 return typ + ' const *' + maybe_const + name
Austin Eng2f218e22021-12-22 19:02:23 +0000834 elif arg.annotation == 'const*const*':
Austin Eng643625a2023-08-09 00:59:33 +0000835 return 'const ' + typ + '* const *' + maybe_const + name
Corentin Wallezf07e3bd2017-04-20 14:38:20 -0400836 else:
Kai Ninomiya01aeca22020-07-15 19:51:17 +0000837 assert False
838
Corentin Wallezf07e3bd2017-04-20 14:38:20 -0400839
Austin Eng643625a2023-08-09 00:59:33 +0000840def annotated(typ, arg, make_const=False):
Corentin Wallezf07e3bd2017-04-20 14:38:20 -0400841 name = as_varName(arg.name)
Austin Eng643625a2023-08-09 00:59:33 +0000842 return decorate(name, typ, arg, make_const)
Corentin Wallezf07e3bd2017-04-20 14:38:20 -0400843
Kai Ninomiya01aeca22020-07-15 19:51:17 +0000844
Kai Ninomiya930e9182021-09-17 19:44:43 +0000845def item_is_enabled(enabled_tags, json_data):
846 tags = json_data.get('tags')
847 if tags is None: return True
848 return any(tag in enabled_tags for tag in tags)
849
850
Austin Eng2f218e22021-12-22 19:02:23 +0000851def item_is_disabled(disabled_tags, json_data):
852 if disabled_tags is None: return False
853 tags = json_data.get('tags')
854 if tags is None: return False
855
856 return any(tag in disabled_tags for tag in tags)
857
858
Corentin Wallezf07e3bd2017-04-20 14:38:20 -0400859def as_cppEnum(value_name):
Kai Ninomiya01aeca22020-07-15 19:51:17 +0000860 assert not value_name.native
Corentin Wallezf07e3bd2017-04-20 14:38:20 -0400861 if value_name.concatcase()[0].isdigit():
862 return "e" + value_name.CamelCase()
863 return value_name.CamelCase()
864
Kai Ninomiya01aeca22020-07-15 19:51:17 +0000865
Corentin Wallezf07e3bd2017-04-20 14:38:20 -0400866def as_MethodSuffix(type_name, method_name):
Kai Ninomiya01aeca22020-07-15 19:51:17 +0000867 assert not type_name.native and not method_name.native
Corentin Wallezf07e3bd2017-04-20 14:38:20 -0400868 return type_name.CamelCase() + method_name.CamelCase()
869
Kai Ninomiya01aeca22020-07-15 19:51:17 +0000870
Loko Kungd46120e2024-03-01 08:51:34 +0000871def as_CppMethodSuffix(type_name, method_name):
872 assert not type_name.native and not method_name.native
873 original_method_name_str = method_name.CamelCase()
874 if method_name.chunks[-1] == 'f':
875 return type_name.CamelCase() + original_method_name_str[:-1]
876 return type_name.CamelCase() + original_method_name_str
877
878
fujunwei76bda372021-11-23 08:47:35 +0000879def as_frontendType(metadata, typ):
Corentin Wallezf07e3bd2017-04-20 14:38:20 -0400880 if typ.category == 'object':
Corentin Wallez4f5fc2d2019-04-01 21:48:38 +0000881 return typ.name.CamelCase() + 'Base*'
Loko Kung440a30c2023-08-04 23:41:21 +0000882 elif typ.category in ['bitmask', 'enum'] or typ.name.get() == 'bool':
fujunwei76bda372021-11-23 08:47:35 +0000883 return metadata.namespace + '::' + typ.name.CamelCase()
Corentin Wallezfe253f12018-08-01 15:12:10 +0200884 elif typ.category == 'structure':
885 return as_cppType(typ.name)
Corentin Wallezf07e3bd2017-04-20 14:38:20 -0400886 else:
fujunwei76bda372021-11-23 08:47:35 +0000887 return as_cType(metadata.c_prefix, typ.name)
Corentin Wallezf07e3bd2017-04-20 14:38:20 -0400888
Kai Ninomiya01aeca22020-07-15 19:51:17 +0000889
fujunwei76bda372021-11-23 08:47:35 +0000890def as_wireType(metadata, typ):
Austin Engcb0cb652019-08-27 21:41:56 +0000891 if typ.category == 'object':
892 return typ.name.CamelCase() + '*'
Brandon Jones6f2bbe92021-04-05 23:34:17 +0000893 elif typ.category in ['bitmask', 'enum', 'structure']:
fujunwei76bda372021-11-23 08:47:35 +0000894 return metadata.c_prefix + typ.name.CamelCase()
Austin Engcb0cb652019-08-27 21:41:56 +0000895 else:
896 return as_cppType(typ.name)
897
Kai Ninomiya01aeca22020-07-15 19:51:17 +0000898
Loko Kung4d835252022-03-19 00:21:48 +0000899def as_formatType(typ):
900 # Unsigned integral types
901 if typ.json_data['type'] in ['bool', 'uint32_t', 'uint64_t']:
902 return 'u'
903
904 # Defaults everything else to strings.
905 return 's'
906
907
Kai Ninomiya930e9182021-09-17 19:44:43 +0000908def c_methods(params, typ):
Corentin Wallezaca8c4a2019-11-22 14:02:52 +0000909 return typ.methods + [
Corentin Wallez2c89f5c2023-05-23 09:39:29 +0000910 Method(Name('reference'), params['types']['void'], [], False, {}),
911 Method(Name('release'), params['types']['void'], [], False, {}),
Corentin Wallez4b410a32017-04-20 14:42:36 -0400912 ]
913
Corentin Wallezaca8c4a2019-11-22 14:02:52 +0000914def get_c_methods_sorted_by_name(api_params):
Corentin Wallezc57b1802019-10-15 12:08:48 +0000915 unsorted = [(as_MethodSuffix(typ.name, method.name), typ, method) \
916 for typ in api_params['by_category']['object'] \
Kai Ninomiya930e9182021-09-17 19:44:43 +0000917 for method in c_methods(api_params, typ) ]
Corentin Wallezc57b1802019-10-15 12:08:48 +0000918 return [(typ, method) for (_, typ, method) in sorted(unsorted)]
919
Kai Ninomiya01aeca22020-07-15 19:51:17 +0000920
Corentin Wallez540abab2019-11-22 13:18:22 +0000921def has_callback_arguments(method):
fujunwei23f71622021-12-02 07:41:21 +0000922 return any(arg.type.category == 'function pointer' for arg in method.arguments)
Corentin Wallez540abab2019-11-22 13:18:22 +0000923
Kai Ninomiya01aeca22020-07-15 19:51:17 +0000924
Loko Kungd46120e2024-03-01 08:51:34 +0000925def has_callback_info(method):
926 return method.return_type.name.get() == 'future' and any(
927 arg.name.get() == 'callback info' for arg in method.arguments)
928
fujunwei76bda372021-11-23 08:47:35 +0000929def make_base_render_params(metadata):
930 c_prefix = metadata.c_prefix
931
932 def as_cTypeEnumSpecialCase(typ):
933 if typ.category == 'bitmask':
934 return as_cType(c_prefix, typ.name) + 'Flags'
935 return as_cType(c_prefix, typ.name)
936
937 def as_cEnum(type_name, value_name):
938 assert not type_name.native and not value_name.native
939 return c_prefix + type_name.CamelCase() + '_' + value_name.CamelCase()
940
941 def as_cMethod(type_name, method_name):
fujunwei23f71622021-12-02 07:41:21 +0000942 c_method = c_prefix.lower()
943 if type_name != None:
944 assert not type_name.native
945 c_method += type_name.CamelCase()
946 assert not method_name.native
947 c_method += method_name.CamelCase()
948 return c_method
fujunwei76bda372021-11-23 08:47:35 +0000949
950 def as_cProc(type_name, method_name):
fujunwei23f71622021-12-02 07:41:21 +0000951 c_proc = c_prefix + 'Proc'
952 if type_name != None:
953 assert not type_name.native
954 c_proc += type_name.CamelCase()
955 assert not method_name.native
956 c_proc += method_name.CamelCase()
957 return c_proc
fujunwei76bda372021-11-23 08:47:35 +0000958
959 return {
960 'Name': lambda name: Name(name),
961 'as_annotated_cType': \
Austin Eng643625a2023-08-09 00:59:33 +0000962 lambda arg, make_const=False: annotated(as_cTypeEnumSpecialCase(arg.type), arg, make_const),
fujunwei76bda372021-11-23 08:47:35 +0000963 'as_annotated_cppType': \
Austin Eng643625a2023-08-09 00:59:33 +0000964 lambda arg, make_const=False: annotated(as_cppType(arg.type.name), arg, make_const),
fujunwei76bda372021-11-23 08:47:35 +0000965 'as_cEnum': as_cEnum,
966 'as_cppEnum': as_cppEnum,
967 'as_cMethod': as_cMethod,
968 'as_MethodSuffix': as_MethodSuffix,
Loko Kungd46120e2024-03-01 08:51:34 +0000969 'as_CppMethodSuffix': as_CppMethodSuffix,
fujunwei76bda372021-11-23 08:47:35 +0000970 'as_cProc': as_cProc,
971 'as_cType': lambda name: as_cType(c_prefix, name),
Loko Kungcd162942023-06-01 19:03:05 +0000972 'as_cReturnType': lambda typ: as_cReturnType(c_prefix, typ),
fujunwei76bda372021-11-23 08:47:35 +0000973 'as_cppType': as_cppType,
974 'as_jsEnumValue': as_jsEnumValue,
975 'convert_cType_to_cppType': convert_cType_to_cppType,
976 'as_varName': as_varName,
Loko Kung4d835252022-03-19 00:21:48 +0000977 'decorate': decorate,
978 'as_formatType': as_formatType
fujunwei76bda372021-11-23 08:47:35 +0000979 }
980
981
Corentin Wallez0c38e922019-06-07 08:59:17 +0000982class MultiGeneratorFromDawnJSON(Generator):
983 def get_description(self):
984 return 'Generates code for various target from Dawn.json.'
Corentin Wallezf07e3bd2017-04-20 14:38:20 -0400985
Corentin Wallez0c38e922019-06-07 08:59:17 +0000986 def add_commandline_arguments(self, parser):
Kai Ninomiya01aeca22020-07-15 19:51:17 +0000987 allowed_targets = [
Ben Clayton35940f92022-02-04 17:15:16 +0000988 'dawn_headers', 'cpp_headers', 'cpp', 'proc', 'mock_api', 'wire',
Brendon Tiszkad0b284b2023-02-08 20:43:18 +0000989 'native_utils', 'dawn_lpmfuzz_cpp', 'dawn_lpmfuzz_proto'
Kai Ninomiya01aeca22020-07-15 19:51:17 +0000990 ]
Corentin Wallezf07e3bd2017-04-20 14:38:20 -0400991
Kai Ninomiya01aeca22020-07-15 19:51:17 +0000992 parser.add_argument('--dawn-json',
993 required=True,
994 type=str,
995 help='The DAWN JSON definition to use.')
996 parser.add_argument('--wire-json',
997 default=None,
998 type=str,
999 help='The DAWN WIRE JSON definition to use.')
Brendon Tiszkad0b284b2023-02-08 20:43:18 +00001000 parser.add_argument("--lpm-json",
1001 default=None,
1002 type=str,
1003 help='The DAWN LPM FUZZER definitions to use.')
Kai Ninomiya01aeca22020-07-15 19:51:17 +00001004 parser.add_argument(
1005 '--targets',
1006 required=True,
1007 type=str,
1008 help=
1009 'Comma-separated subset of targets to output. Available targets: '
1010 + ', '.join(allowed_targets))
Brendon Tiszkad0b284b2023-02-08 20:43:18 +00001011
Corentin Wallez0c38e922019-06-07 08:59:17 +00001012 def get_file_renders(self, args):
1013 with open(args.dawn_json) as f:
1014 loaded_json = json.loads(f.read())
Corentin Wallezf07e3bd2017-04-20 14:38:20 -04001015
Corentin Wallez0c38e922019-06-07 08:59:17 +00001016 targets = args.targets.split(',')
Corentin Wallez4b410a32017-04-20 14:42:36 -04001017
Corentin Wallez0c38e922019-06-07 08:59:17 +00001018 wire_json = None
1019 if args.wire_json:
1020 with open(args.wire_json) as f:
1021 wire_json = json.loads(f.read())
Corentin Wallezf07e3bd2017-04-20 14:38:20 -04001022
Brendon Tiszkad0b284b2023-02-08 20:43:18 +00001023 lpm_json = None
1024 if args.lpm_json:
1025 with open(args.lpm_json) as f:
1026 lpm_json = json.loads(f.read())
1027
Kai Ninomiya930e9182021-09-17 19:44:43 +00001028 renders = []
1029
Kai Ninomiya930e9182021-09-17 19:44:43 +00001030 params_dawn = parse_json(loaded_json,
1031 enabled_tags=['dawn', 'native', 'deprecated'])
fujunwei76bda372021-11-23 08:47:35 +00001032 metadata = params_dawn['metadata']
1033 RENDER_PARAMS_BASE = make_base_render_params(metadata)
Corentin Wallez79a62bf2017-05-24 16:04:55 +02001034
fujunweic7d4f2c2021-12-07 00:46:35 +00001035 api = metadata.api.lower()
fujunweia8405742021-12-10 01:35:19 +00001036 prefix = metadata.proc_table_prefix.lower()
Ben Clayton35940f92022-02-04 17:15:16 +00001037 if 'headers' in targets:
Kai Ninomiya01aeca22020-07-15 19:51:17 +00001038 renders.append(
Ben Clayton9fb7a512022-02-04 18:18:18 +00001039 FileRender('api.h', 'include/dawn/' + api + '.h',
Kai Ninomiya930e9182021-09-17 19:44:43 +00001040 [RENDER_PARAMS_BASE, params_dawn]))
Kai Ninomiya01aeca22020-07-15 19:51:17 +00001041 renders.append(
1042 FileRender('dawn_proc_table.h',
Ben Clayton9fb7a512022-02-04 18:18:18 +00001043 'include/dawn/' + prefix + '_proc_table.h',
Kai Ninomiya930e9182021-09-17 19:44:43 +00001044 [RENDER_PARAMS_BASE, params_dawn]))
Corentin Wallezf07e3bd2017-04-20 14:38:20 -04001045
Ben Clayton35940f92022-02-04 17:15:16 +00001046 if 'cpp_headers' in targets:
Kai Ninomiya01aeca22020-07-15 19:51:17 +00001047 renders.append(
Ben Clayton9fb7a512022-02-04 18:18:18 +00001048 FileRender('api_cpp.h', 'include/dawn/' + api + '_cpp.h',
Kai Ninomiya930e9182021-09-17 19:44:43 +00001049 [RENDER_PARAMS_BASE, params_dawn]))
Austin Engcc071e42019-10-16 10:26:01 +00001050
Austin Enga9e39e12021-06-01 18:49:12 +00001051 renders.append(
fujunweic7d4f2c2021-12-07 00:46:35 +00001052 FileRender('api_cpp_print.h',
Ben Clayton9fb7a512022-02-04 18:18:18 +00001053 'include/dawn/' + api + '_cpp_print.h',
Kai Ninomiya930e9182021-09-17 19:44:43 +00001054 [RENDER_PARAMS_BASE, params_dawn]))
Austin Enga9e39e12021-06-01 18:49:12 +00001055
Loko Kung14ed5332023-05-16 04:50:32 +00001056 renders.append(
1057 FileRender('api_cpp_chained_struct.h',
Kai Ninomiya68892272024-01-04 10:02:49 +00001058 'include/webgpu/' + api + '_cpp_chained_struct.h',
Loko Kung14ed5332023-05-16 04:50:32 +00001059 [RENDER_PARAMS_BASE, params_dawn]))
1060
Ben Clayton35940f92022-02-04 17:15:16 +00001061 if 'proc' in targets:
Kai Ninomiya01aeca22020-07-15 19:51:17 +00001062 renders.append(
fujunweia8405742021-12-10 01:35:19 +00001063 FileRender('dawn_proc.c', 'src/dawn/' + prefix + '_proc.c',
Kai Ninomiya930e9182021-09-17 19:44:43 +00001064 [RENDER_PARAMS_BASE, params_dawn]))
Austin Eng16e01af2020-10-06 16:13:42 +00001065 renders.append(
1066 FileRender('dawn_thread_dispatch_proc.cpp',
fujunweia8405742021-12-10 01:35:19 +00001067 'src/dawn/' + prefix + '_thread_dispatch_proc.cpp',
Kai Ninomiya930e9182021-09-17 19:44:43 +00001068 [RENDER_PARAMS_BASE, params_dawn]))
Corentin Wallez96496822019-10-15 11:44:38 +00001069
Austin Eng63f65462021-12-09 20:03:48 +00001070 if 'webgpu_dawn_native_proc' in targets:
1071 renders.append(
Ben Clayton818001d2022-02-04 17:07:46 +00001072 FileRender('dawn/native/api_dawn_native_proc.cpp',
1073 'src/dawn/native/webgpu_dawn_native_proc.cpp',
Austin Eng63f65462021-12-09 20:03:48 +00001074 [RENDER_PARAMS_BASE, params_dawn]))
1075
Ben Clayton35940f92022-02-04 17:15:16 +00001076 if 'cpp' in targets:
Kai Ninomiya01aeca22020-07-15 19:51:17 +00001077 renders.append(
fujunweid3cac112021-12-14 02:20:15 +00001078 FileRender('api_cpp.cpp', 'src/dawn/' + api + '_cpp.cpp',
Kai Ninomiya930e9182021-09-17 19:44:43 +00001079 [RENDER_PARAMS_BASE, params_dawn]))
1080
1081 if 'webgpu_headers' in targets:
1082 params_upstream = parse_json(loaded_json,
Shrek Shao1554a7d2022-03-08 20:56:10 +00001083 enabled_tags=['upstream', 'native'],
1084 disabled_tags=['dawn'])
Kai Ninomiya930e9182021-09-17 19:44:43 +00001085 renders.append(
fujunweic7d4f2c2021-12-07 00:46:35 +00001086 FileRender('api.h', 'webgpu-headers/' + api + '.h',
Kai Ninomiya930e9182021-09-17 19:44:43 +00001087 [RENDER_PARAMS_BASE, params_upstream]))
Corentin Wallez59e7fad2018-08-16 15:32:35 +02001088
Kai Ninomiya7b6246a2020-01-28 23:54:38 +00001089 if 'emscripten_bits' in targets:
Kai Ninomiya68892272024-01-04 10:02:49 +00001090 assert api == 'webgpu'
Shrek Shaoee50bc02022-02-08 20:21:40 +00001091 params_emscripten = parse_json(loaded_json,
1092 enabled_tags=['emscripten'])
Kai Ninomiya68892272024-01-04 10:02:49 +00001093 # system/include/webgpu
Kai Ninomiya930e9182021-09-17 19:44:43 +00001094 renders.append(
Kai Ninomiya68892272024-01-04 10:02:49 +00001095 FileRender('api.h',
1096 'emscripten-bits/system/include/webgpu/webgpu.h',
Kai Ninomiya930e9182021-09-17 19:44:43 +00001097 [RENDER_PARAMS_BASE, params_emscripten]))
1098 renders.append(
Kai Ninomiya68892272024-01-04 10:02:49 +00001099 FileRender(
1100 'api_cpp.h',
1101 'emscripten-bits/system/include/webgpu/webgpu_cpp.h',
1102 [RENDER_PARAMS_BASE, params_emscripten]))
Kai Ninomiya930e9182021-09-17 19:44:43 +00001103 renders.append(
Kai Ninomiya68892272024-01-04 10:02:49 +00001104 FileRender(
1105 'api_cpp_chained_struct.h',
1106 'emscripten-bits/system/include/webgpu/webgpu_cpp_chained_struct.h',
1107 [RENDER_PARAMS_BASE, params_emscripten]))
1108 # system/lib/webgpu
1109 renders.append(
1110 FileRender('api_cpp.cpp',
1111 'emscripten-bits/system/lib/webgpu/webgpu_cpp.cpp',
Kai Ninomiya930e9182021-09-17 19:44:43 +00001112 [RENDER_PARAMS_BASE, params_emscripten]))
Kai Ninomiya68892272024-01-04 10:02:49 +00001113 # Snippets to paste into existing Emscripten files
Kai Ninomiya01aeca22020-07-15 19:51:17 +00001114 renders.append(
fujunwei16ae3b82021-12-15 04:35:26 +00001115 FileRender('api_struct_info.json',
Kai Ninomiya68892272024-01-04 10:02:49 +00001116 'emscripten-bits/webgpu_struct_info.json',
Kai Ninomiya930e9182021-09-17 19:44:43 +00001117 [RENDER_PARAMS_BASE, params_emscripten]))
Kai Ninomiya01aeca22020-07-15 19:51:17 +00001118 renders.append(
fujunwei16ae3b82021-12-15 04:35:26 +00001119 FileRender('library_api_enum_tables.js',
Kai Ninomiya68892272024-01-04 10:02:49 +00001120 'emscripten-bits/library_webgpu_enum_tables.js',
Kai Ninomiya930e9182021-09-17 19:44:43 +00001121 [RENDER_PARAMS_BASE, params_emscripten]))
Kai Ninomiya7b6246a2020-01-28 23:54:38 +00001122
fujunwei16ae3b82021-12-15 04:35:26 +00001123 if 'mock_api' in targets:
Corentin Wallez540abab2019-11-22 13:18:22 +00001124 mock_params = [
Kai Ninomiya930e9182021-09-17 19:44:43 +00001125 RENDER_PARAMS_BASE, params_dawn, {
Loko Kungd46120e2024-03-01 08:51:34 +00001126 'has_callback_arguments': has_callback_arguments,
1127 "has_callback_info": has_callback_info
Corentin Wallez540abab2019-11-22 13:18:22 +00001128 }
1129 ]
Kai Ninomiya01aeca22020-07-15 19:51:17 +00001130 renders.append(
fujunwei16ae3b82021-12-15 04:35:26 +00001131 FileRender('mock_api.h', 'src/dawn/mock_' + api + '.h',
Kai Ninomiya01aeca22020-07-15 19:51:17 +00001132 mock_params))
1133 renders.append(
fujunwei16ae3b82021-12-15 04:35:26 +00001134 FileRender('mock_api.cpp', 'src/dawn/mock_' + api + '.cpp',
Kai Ninomiya01aeca22020-07-15 19:51:17 +00001135 mock_params))
Corentin Wallez59e7fad2018-08-16 15:32:35 +02001136
Ben Clayton818001d2022-02-04 17:07:46 +00001137 if 'native_utils' in targets:
Corentin Wallez0c38e922019-06-07 08:59:17 +00001138 frontend_params = [
Kai Ninomiya930e9182021-09-17 19:44:43 +00001139 RENDER_PARAMS_BASE,
1140 params_dawn,
Corentin Wallez0c38e922019-06-07 08:59:17 +00001141 {
Kai Ninomiya01aeca22020-07-15 19:51:17 +00001142 # TODO: as_frontendType and co. take a Type, not a Name :(
fujunwei76bda372021-11-23 08:47:35 +00001143 'as_frontendType': lambda typ: as_frontendType(metadata, typ),
Kai Ninomiya01aeca22020-07-15 19:51:17 +00001144 'as_annotated_frontendType': \
fujunwei76bda372021-11-23 08:47:35 +00001145 lambda arg: annotated(as_frontendType(metadata, arg.type), arg),
Corentin Wallez0c38e922019-06-07 08:59:17 +00001146 }
1147 ]
Corentin Wallez59e7fad2018-08-16 15:32:35 +02001148
fujunweia2241d42021-12-16 04:54:38 +00001149 impl_dir = metadata.impl_dir + '/' if metadata.impl_dir else ''
Ben Clayton818001d2022-02-04 17:07:46 +00001150 native_dir = impl_dir + Name(metadata.native_namespace).Dirs()
fujunwei7f3f8ac2021-12-21 03:27:34 +00001151 namespace = metadata.namespace
Kai Ninomiya01aeca22020-07-15 19:51:17 +00001152 renders.append(
Ben Clayton818001d2022-02-04 17:07:46 +00001153 FileRender('dawn/native/ValidationUtils.h',
fujunweia2241d42021-12-16 04:54:38 +00001154 'src/' + native_dir + '/ValidationUtils_autogen.h',
Kai Ninomiya01aeca22020-07-15 19:51:17 +00001155 frontend_params))
1156 renders.append(
Ben Clayton818001d2022-02-04 17:07:46 +00001157 FileRender('dawn/native/ValidationUtils.cpp',
fujunweia2241d42021-12-16 04:54:38 +00001158 'src/' + native_dir + '/ValidationUtils_autogen.cpp',
Kai Ninomiya01aeca22020-07-15 19:51:17 +00001159 frontend_params))
1160 renders.append(
Ben Clayton818001d2022-02-04 17:07:46 +00001161 FileRender('dawn/native/dawn_platform.h',
fujunweifc38f7d2021-12-17 00:46:08 +00001162 'src/' + native_dir + '/' + prefix + '_platform_autogen.h',
Austin Eng3faa4782021-10-27 19:07:37 +00001163 frontend_params))
1164 renders.append(
Ben Clayton818001d2022-02-04 17:07:46 +00001165 FileRender('dawn/native/api_structs.h',
fujunwei7f3f8ac2021-12-21 03:27:34 +00001166 'src/' + native_dir + '/' + namespace + '_structs_autogen.h',
Kai Ninomiya01aeca22020-07-15 19:51:17 +00001167 frontend_params))
1168 renders.append(
Ben Clayton818001d2022-02-04 17:07:46 +00001169 FileRender('dawn/native/api_structs.cpp',
fujunwei7f3f8ac2021-12-21 03:27:34 +00001170 'src/' + native_dir + '/' + namespace + '_structs_autogen.cpp',
Kai Ninomiya01aeca22020-07-15 19:51:17 +00001171 frontend_params))
1172 renders.append(
Ben Clayton818001d2022-02-04 17:07:46 +00001173 FileRender('dawn/native/ProcTable.cpp',
Ningxin Hu7e5930b2021-12-22 06:12:13 +00001174 'src/' + native_dir + '/ProcTable.cpp', frontend_params))
Brian Ho5346e772021-04-22 17:49:42 +00001175 renders.append(
Ben Clayton818001d2022-02-04 17:07:46 +00001176 FileRender('dawn/native/ChainUtils.h',
fujunwei2b1dcd92021-12-22 01:05:03 +00001177 'src/' + native_dir + '/ChainUtils_autogen.h',
Brian Ho5346e772021-04-22 17:49:42 +00001178 frontend_params))
1179 renders.append(
Ben Clayton818001d2022-02-04 17:07:46 +00001180 FileRender('dawn/native/ChainUtils.cpp',
fujunwei2b1dcd92021-12-22 01:05:03 +00001181 'src/' + native_dir + '/ChainUtils_autogen.cpp',
Brian Ho5346e772021-04-22 17:49:42 +00001182 frontend_params))
Brandon Jonesba662952021-09-23 21:26:33 +00001183 renders.append(
Austin Engd1dcb502023-08-21 22:03:00 +00001184 FileRender('dawn/native/Features.h',
1185 'src/' + native_dir + '/Features_autogen.h',
1186 frontend_params))
1187 renders.append(
1188 FileRender('dawn/native/Features.inl',
1189 'src/' + native_dir + '/Features_autogen.inl',
1190 frontend_params))
1191 renders.append(
Ben Clayton818001d2022-02-04 17:07:46 +00001192 FileRender('dawn/native/api_absl_format.h',
fujunweif001ef52021-12-23 05:16:04 +00001193 'src/' + native_dir + '/' + api + '_absl_format_autogen.h',
Brandon Jonesba662952021-09-23 21:26:33 +00001194 frontend_params))
1195 renders.append(
Ben Clayton818001d2022-02-04 17:07:46 +00001196 FileRender('dawn/native/api_absl_format.cpp',
fujunweif001ef52021-12-23 05:16:04 +00001197 'src/' + native_dir + '/' + api + '_absl_format_autogen.cpp',
Brandon Jonesba662952021-09-23 21:26:33 +00001198 frontend_params))
Loko Kung8d195d52021-09-28 15:40:01 +00001199 renders.append(
Austin Engbc285fb2022-07-29 00:36:21 +00001200 FileRender(
1201 'dawn/native/api_StreamImpl.cpp', 'src/' + native_dir +
1202 '/' + api + '_StreamImpl_autogen.cpp', frontend_params))
1203 renders.append(
Ben Clayton818001d2022-02-04 17:07:46 +00001204 FileRender('dawn/native/ObjectType.h',
fujunwei2b1dcd92021-12-22 01:05:03 +00001205 'src/' + native_dir + '/ObjectType_autogen.h',
Loko Kung8d195d52021-09-28 15:40:01 +00001206 frontend_params))
1207 renders.append(
Ben Clayton818001d2022-02-04 17:07:46 +00001208 FileRender('dawn/native/ObjectType.cpp',
fujunwei2b1dcd92021-12-22 01:05:03 +00001209 'src/' + native_dir + '/ObjectType_autogen.cpp',
Loko Kung8d195d52021-09-28 15:40:01 +00001210 frontend_params))
Corentin Wallez59e7fad2018-08-16 15:32:35 +02001211
Ben Clayton20cbe6d2022-02-04 12:51:25 +00001212 if 'wire' in targets:
Austin Eng2f218e22021-12-22 19:02:23 +00001213 params_dawn_wire = parse_json(loaded_json,
1214 enabled_tags=['dawn', 'deprecated'],
1215 disabled_tags=['native'])
1216 additional_params = compute_wire_params(params_dawn_wire,
1217 wire_json)
Corentin Wallez59e7fad2018-08-16 15:32:35 +02001218
Corentin Wallez0c38e922019-06-07 08:59:17 +00001219 wire_params = [
Austin Eng2f218e22021-12-22 19:02:23 +00001220 RENDER_PARAMS_BASE, params_dawn_wire, {
fujunwei76bda372021-11-23 08:47:35 +00001221 'as_wireType': lambda type : as_wireType(metadata, type),
Kai Ninomiya01aeca22020-07-15 19:51:17 +00001222 'as_annotated_wireType': \
fujunwei76bda372021-11-23 08:47:35 +00001223 lambda arg: annotated(as_wireType(metadata, arg.type), arg),
Kai Ninomiya01aeca22020-07-15 19:51:17 +00001224 }, additional_params
Corentin Wallez0c38e922019-06-07 08:59:17 +00001225 ]
Kai Ninomiya01aeca22020-07-15 19:51:17 +00001226 renders.append(
Ben Clayton20cbe6d2022-02-04 12:51:25 +00001227 FileRender('dawn/wire/ObjectType.h',
1228 'src/dawn/wire/ObjectType_autogen.h', wire_params))
Austin Eng3120d5e2020-11-11 19:46:18 +00001229 renders.append(
Ben Clayton20cbe6d2022-02-04 12:51:25 +00001230 FileRender('dawn/wire/WireCmd.h',
1231 'src/dawn/wire/WireCmd_autogen.h', wire_params))
Kai Ninomiya01aeca22020-07-15 19:51:17 +00001232 renders.append(
Ben Clayton20cbe6d2022-02-04 12:51:25 +00001233 FileRender('dawn/wire/WireCmd.cpp',
1234 'src/dawn/wire/WireCmd_autogen.cpp', wire_params))
Kai Ninomiya01aeca22020-07-15 19:51:17 +00001235 renders.append(
Ben Clayton20cbe6d2022-02-04 12:51:25 +00001236 FileRender('dawn/wire/client/ApiObjects.h',
1237 'src/dawn/wire/client/ApiObjects_autogen.h',
Kai Ninomiya01aeca22020-07-15 19:51:17 +00001238 wire_params))
1239 renders.append(
Ben Clayton20cbe6d2022-02-04 12:51:25 +00001240 FileRender('dawn/wire/client/ApiProcs.cpp',
1241 'src/dawn/wire/client/ApiProcs_autogen.cpp',
Kai Ninomiya01aeca22020-07-15 19:51:17 +00001242 wire_params))
1243 renders.append(
Ben Clayton20cbe6d2022-02-04 12:51:25 +00001244 FileRender('dawn/wire/client/ClientBase.h',
1245 'src/dawn/wire/client/ClientBase_autogen.h',
Kai Ninomiya01aeca22020-07-15 19:51:17 +00001246 wire_params))
1247 renders.append(
Ben Clayton20cbe6d2022-02-04 12:51:25 +00001248 FileRender('dawn/wire/client/ClientHandlers.cpp',
1249 'src/dawn/wire/client/ClientHandlers_autogen.cpp',
Kai Ninomiya01aeca22020-07-15 19:51:17 +00001250 wire_params))
1251 renders.append(
1252 FileRender(
Ben Clayton20cbe6d2022-02-04 12:51:25 +00001253 'dawn/wire/client/ClientPrototypes.inc',
1254 'src/dawn/wire/client/ClientPrototypes_autogen.inc',
Kai Ninomiya01aeca22020-07-15 19:51:17 +00001255 wire_params))
1256 renders.append(
Ben Clayton20cbe6d2022-02-04 12:51:25 +00001257 FileRender('dawn/wire/server/ServerBase.h',
1258 'src/dawn/wire/server/ServerBase_autogen.h',
Kai Ninomiya01aeca22020-07-15 19:51:17 +00001259 wire_params))
1260 renders.append(
Ben Clayton20cbe6d2022-02-04 12:51:25 +00001261 FileRender('dawn/wire/server/ServerDoers.cpp',
1262 'src/dawn/wire/server/ServerDoers_autogen.cpp',
Kai Ninomiya01aeca22020-07-15 19:51:17 +00001263 wire_params))
1264 renders.append(
Ben Clayton20cbe6d2022-02-04 12:51:25 +00001265 FileRender('dawn/wire/server/ServerHandlers.cpp',
1266 'src/dawn/wire/server/ServerHandlers_autogen.cpp',
Kai Ninomiya01aeca22020-07-15 19:51:17 +00001267 wire_params))
1268 renders.append(
1269 FileRender(
Ben Clayton20cbe6d2022-02-04 12:51:25 +00001270 'dawn/wire/server/ServerPrototypes.inc',
1271 'src/dawn/wire/server/ServerPrototypes_autogen.inc',
Kai Ninomiya01aeca22020-07-15 19:51:17 +00001272 wire_params))
Corentin Wallez59e7fad2018-08-16 15:32:35 +02001273
Brendon Tiszkad0b284b2023-02-08 20:43:18 +00001274 if 'dawn_lpmfuzz_proto' in targets:
1275 params_dawn_wire = parse_json(loaded_json,
1276 enabled_tags=['dawn', 'deprecated'],
1277 disabled_tags=['native'])
Brendon Tiszkaa0456432023-03-23 16:02:20 +00001278 api_and_wire_params = compute_wire_params(params_dawn_wire,
1279 wire_json)
1280
1281 fuzzer_params = compute_lpm_params(api_and_wire_params, lpm_json)
Brendon Tiszkad0b284b2023-02-08 20:43:18 +00001282
1283 lpm_params = [
Brendon Tiszkaa0456432023-03-23 16:02:20 +00001284 RENDER_PARAMS_BASE, params_dawn_wire, {
1285 'as_protobufTypeLPM': as_protobufTypeLPM,
1286 'as_protobufNameLPM': as_protobufNameLPM,
1287 'unreachable': unreachable_code
1288 }, api_and_wire_params, fuzzer_params
Brendon Tiszkad0b284b2023-02-08 20:43:18 +00001289 ]
1290
1291 renders.append(
1292 FileRender('dawn/fuzzers/lpmfuzz/dawn_lpm.proto',
1293 'src/dawn/fuzzers/lpmfuzz/dawn_lpm_autogen.proto',
1294 lpm_params))
1295
Brendon Tiszka1f8413f2023-05-02 21:41:22 +00001296 renders.append(
1297 FileRender(
1298 'dawn/fuzzers/lpmfuzz/dawn_object_types_lpm.proto',
1299 'src/dawn/fuzzers/lpmfuzz/dawn_object_types_lpm_autogen.proto',
1300 lpm_params))
1301
Brendon Tiszkad0b284b2023-02-08 20:43:18 +00001302 if 'dawn_lpmfuzz_cpp' in targets:
1303 params_dawn_wire = parse_json(loaded_json,
1304 enabled_tags=['dawn', 'deprecated'],
1305 disabled_tags=['native'])
Brendon Tiszkaa0456432023-03-23 16:02:20 +00001306 api_and_wire_params = compute_wire_params(params_dawn_wire,
1307 wire_json)
Brendon Tiszkad0b284b2023-02-08 20:43:18 +00001308
Brendon Tiszka1f8413f2023-05-02 21:41:22 +00001309 fuzzer_params = compute_lpm_params(api_and_wire_params, lpm_json)
1310
Brendon Tiszkad0b284b2023-02-08 20:43:18 +00001311 lpm_params = [
Brendon Tiszka27521c62023-05-15 22:22:07 +00001312 RENDER_PARAMS_BASE, params_dawn_wire, {
1313 'as_protobufMemberName': as_protobufMemberNameLPM,
1314 'unreachable_code': unreachable_code
1315 }, api_and_wire_params, fuzzer_params
Brendon Tiszkad0b284b2023-02-08 20:43:18 +00001316 ]
1317
1318 renders.append(
1319 FileRender(
1320 'dawn/fuzzers/lpmfuzz/DawnLPMSerializer.cpp',
1321 'src/dawn/fuzzers/lpmfuzz/DawnLPMSerializer_autogen.cpp',
1322 lpm_params))
1323
1324 renders.append(
1325 FileRender(
1326 'dawn/fuzzers/lpmfuzz/DawnLPMSerializer.h',
1327 'src/dawn/fuzzers/lpmfuzz/DawnLPMSerializer_autogen.h',
1328 lpm_params))
1329
Brendon Tiszkaa0456432023-03-23 16:02:20 +00001330 renders.append(
1331 FileRender(
1332 'dawn/fuzzers/lpmfuzz/DawnLPMConstants.h',
1333 'src/dawn/fuzzers/lpmfuzz/DawnLPMConstants_autogen.h',
1334 lpm_params))
1335
Corentin Wallez0c38e922019-06-07 08:59:17 +00001336 return renders
Corentin Wallez59e7fad2018-08-16 15:32:35 +02001337
Corentin Wallez0c38e922019-06-07 08:59:17 +00001338 def get_dependencies(self, args):
1339 deps = [os.path.abspath(args.dawn_json)]
1340 if args.wire_json != None:
1341 deps += [os.path.abspath(args.wire_json)]
Brendon Tiszkad0b284b2023-02-08 20:43:18 +00001342 if args.lpm_json != None:
1343 deps += [os.path.abspath(args.lpm_json)]
Corentin Wallez0c38e922019-06-07 08:59:17 +00001344 return deps
Corentin Wallezf07e3bd2017-04-20 14:38:20 -04001345
Kai Ninomiya01aeca22020-07-15 19:51:17 +00001346
Corentin Wallezf07e3bd2017-04-20 14:38:20 -04001347if __name__ == '__main__':
Corentin Wallez0c38e922019-06-07 08:59:17 +00001348 sys.exit(run_generator(MultiGeneratorFromDawnJSON()))