blob: e818d2a2e94e4a6247b641f0a536a3946c317d46 [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)
Jiawei Shao6d6b63c2021-12-02 07:29:41 +0000161 self.is_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
Corentin Wallez8f938712019-07-08 19:20:22 +0000184 self.default_value = default_value
Austin Eng6a5418a2019-07-19 16:01:48 +0000185 self.skip_serialize = skip_serialize
Corentin Wallez031fbbb2019-06-11 18:03:05 +0000186
187 def set_handle_type(self, handle_type):
188 assert self.type.dict_name == "ObjectHandle"
189 self.handle_type = handle_type
190
Kai Ninomiya01aeca22020-07-15 19:51:17 +0000191
Kai Ninomiya930e9182021-09-17 19:44:43 +0000192Method = namedtuple('Method',
193 ['name', 'return_type', 'arguments', 'json_data'])
Kai Ninomiya01aeca22020-07-15 19:51:17 +0000194
195
Corentin Wallez031fbbb2019-06-11 18:03:05 +0000196class ObjectType(Type):
Kai Ninomiya930e9182021-09-17 19:44:43 +0000197 def __init__(self, is_enabled, name, json_data):
198 json_data_override = {'methods': []}
199 if 'methods' in json_data:
200 json_data_override['methods'] = [
201 m for m in json_data['methods'] if is_enabled(m)
202 ]
203 Type.__init__(self, name, dict(json_data, **json_data_override))
Corentin Wallez031fbbb2019-06-11 18:03:05 +0000204
Kai Ninomiya01aeca22020-07-15 19:51:17 +0000205
Corentin Wallez031fbbb2019-06-11 18:03:05 +0000206class Record:
207 def __init__(self, name):
208 self.name = Name(name)
209 self.members = []
Austin Eng76a8d0b2020-04-03 17:37:48 +0000210 self.may_have_dawn_object = False
Corentin Wallez031fbbb2019-06-11 18:03:05 +0000211
212 def update_metadata(self):
Austin Eng76a8d0b2020-04-03 17:37:48 +0000213 def may_have_dawn_object(member):
Corentin Wallez031fbbb2019-06-11 18:03:05 +0000214 if isinstance(member.type, ObjectType):
215 return True
216 elif isinstance(member.type, StructureType):
Austin Eng76a8d0b2020-04-03 17:37:48 +0000217 return member.type.may_have_dawn_object
Corentin Wallez031fbbb2019-06-11 18:03:05 +0000218 else:
219 return False
220
Kai Ninomiya01aeca22020-07-15 19:51:17 +0000221 self.may_have_dawn_object = any(
222 may_have_dawn_object(member) for member in self.members)
Austin Eng76a8d0b2020-04-03 17:37:48 +0000223
Kai Ninomiya01aeca22020-07-15 19:51:17 +0000224 # Set may_have_dawn_object to true if the type is chained or
225 # extensible. Chained structs may contain a Dawn object.
Austin Eng76a8d0b2020-04-03 17:37:48 +0000226 if isinstance(self, StructureType):
Kai Ninomiya01aeca22020-07-15 19:51:17 +0000227 self.may_have_dawn_object = (self.may_have_dawn_object
228 or self.chained or self.extensible)
229
Corentin Wallez031fbbb2019-06-11 18:03:05 +0000230
231class StructureType(Record, Type):
Kai Ninomiya930e9182021-09-17 19:44:43 +0000232 def __init__(self, is_enabled, name, json_data):
Corentin Wallez031fbbb2019-06-11 18:03:05 +0000233 Record.__init__(self, name)
Kai Ninomiya930e9182021-09-17 19:44:43 +0000234 json_data_override = {}
235 if 'members' in json_data:
236 json_data_override['members'] = [
237 m for m in json_data['members'] if is_enabled(m)
238 ]
239 Type.__init__(self, name, dict(json_data, **json_data_override))
Corentin Walleza45561b2022-07-14 12:58:25 +0000240 self.chained = json_data.get('chained', None)
241 self.extensible = json_data.get('extensible', None)
Austin Eng0c824052021-09-20 16:07:25 +0000242 if self.chained:
Corentin Walleza45561b2022-07-14 12:58:25 +0000243 assert self.chained == 'in' or self.chained == 'out'
244 assert 'chain roots' in json_data
Austin Eng0c824052021-09-20 16:07:25 +0000245 if self.extensible:
Corentin Walleza45561b2022-07-14 12:58:25 +0000246 assert self.extensible == 'in' or self.extensible == 'out'
Kai Ninomiya01aeca22020-07-15 19:51:17 +0000247 # Chained structs inherit from wgpu::ChainedStruct, which has
248 # nextInChain, so setting both extensible and chained would result in
249 # two nextInChain members.
250 assert not (self.extensible and self.chained)
251
Jiawei Shao1fa386c2021-12-21 04:04:51 +0000252 def update_metadata(self):
253 Record.update_metadata(self)
254
255 if self.may_have_dawn_object:
256 self.is_wire_transparent = False
257 return
258
259 assert not (self.chained or self.extensible)
260
261 def get_is_wire_transparent(member):
262 return member.type.is_wire_transparent and member.annotation == 'value'
263
264 self.is_wire_transparent = all(
265 get_is_wire_transparent(m) for m in self.members)
266
Austin Eng0c824052021-09-20 16:07:25 +0000267 @property
268 def output(self):
269 return self.chained == "out" or self.extensible == "out"
270
Corentin Wallez031fbbb2019-06-11 18:03:05 +0000271
fujunwei4e876902021-11-25 08:44:01 +0000272class ConstantDefinition():
273 def __init__(self, is_enabled, name, json_data):
274 self.type = None
275 self.value = json_data['value']
276 self.json_data = json_data
277 self.name = Name(name)
278
279
fujunwei23f71622021-12-02 07:41:21 +0000280class FunctionDeclaration():
281 def __init__(self, is_enabled, name, json_data):
282 self.return_type = None
283 self.arguments = []
284 self.json_data = json_data
285 self.name = Name(name)
286
287
Corentin Wallez031fbbb2019-06-11 18:03:05 +0000288class Command(Record):
289 def __init__(self, name, members=None):
290 Record.__init__(self, name)
291 self.members = members or []
292 self.derived_object = None
293 self.derived_method = None
294
Kai Ninomiya01aeca22020-07-15 19:51:17 +0000295
Corentin Wallez031fbbb2019-06-11 18:03:05 +0000296def linked_record_members(json_data, types):
297 members = []
298 members_by_name = {}
299 for m in json_data:
Kai Ninomiya01aeca22020-07-15 19:51:17 +0000300 member = RecordMember(Name(m['name']),
301 types[m['type']],
Corentin Wallez8f938712019-07-08 19:20:22 +0000302 m.get('annotation', 'value'),
Kai Ninomiya930e9182021-09-17 19:44:43 +0000303 m,
Corentin Wallez8f938712019-07-08 19:20:22 +0000304 optional=m.get('optional', False),
305 is_return_value=m.get('is_return_value', False),
Austin Eng6a5418a2019-07-19 16:01:48 +0000306 default_value=m.get('default', None),
307 skip_serialize=m.get('skip_serialize', False))
Corentin Wallez031fbbb2019-06-11 18:03:05 +0000308 handle_type = m.get('handle_type')
309 if handle_type:
310 member.set_handle_type(types[handle_type])
311 members.append(member)
312 members_by_name[member.name.canonical_case()] = member
313
314 for (member, m) in zip(members, json_data):
315 if member.annotation != 'value':
316 if not 'length' in m:
317 if member.type.category != 'object':
318 member.length = "constant"
319 member.constant_length = 1
320 else:
Kai Ninomiya01aeca22020-07-15 19:51:17 +0000321 assert False
Corentin Wallez031fbbb2019-06-11 18:03:05 +0000322 elif m['length'] == 'strlen':
323 member.length = 'strlen'
Yan52040532021-12-15 04:08:56 +0000324 elif isinstance(m['length'], int):
325 assert m['length'] > 0
326 member.length = "constant"
327 member.constant_length = m['length']
Corentin Wallez031fbbb2019-06-11 18:03:05 +0000328 else:
329 member.length = members_by_name[m['length']]
330
331 return members
Corentin Walleza6416542018-05-17 16:55:53 -0400332
Kai Ninomiya01aeca22020-07-15 19:51:17 +0000333
Corentin Wallezf07e3bd2017-04-20 14:38:20 -0400334############################################################
335# PARSE
336############################################################
Corentin Wallez4b410a32017-04-20 14:42:36 -0400337
Kai Ninomiya01aeca22020-07-15 19:51:17 +0000338
Corentin Walleze2f94842018-12-05 17:49:04 +0000339def link_object(obj, types):
340 def make_method(json_data):
Corentin Wallez031fbbb2019-06-11 18:03:05 +0000341 arguments = linked_record_members(json_data.get('args', []), types)
Kai Ninomiya01aeca22020-07-15 19:51:17 +0000342 return Method(Name(json_data['name']),
Kai Ninomiya930e9182021-09-17 19:44:43 +0000343 types[json_data.get('returns',
344 'void')], arguments, json_data)
Corentin Walleze2f94842018-12-05 17:49:04 +0000345
Corentin Wallezaca8c4a2019-11-22 14:02:52 +0000346 obj.methods = [make_method(m) for m in obj.json_data.get('methods', [])]
Corentin Wallez97231682019-10-08 07:38:01 +0000347 obj.methods.sort(key=lambda method: method.name.canonical_case())
Corentin Wallezf07e3bd2017-04-20 14:38:20 -0400348
Kai Ninomiya01aeca22020-07-15 19:51:17 +0000349
Corentin Walleza6416542018-05-17 16:55:53 -0400350def link_structure(struct, types):
Corentin Wallez031fbbb2019-06-11 18:03:05 +0000351 struct.members = linked_record_members(struct.json_data['members'], types)
Corentin Walleza45561b2022-07-14 12:58:25 +0000352 struct.chain_roots = [types[root] for root in struct.json_data.get('chain roots', [])]
353 assert all((root.category == 'structure' for root in struct.chain_roots))
Corentin Walleza6416542018-05-17 16:55:53 -0400354
Corentin Wallez540abab2019-11-22 13:18:22 +0000355
fujunwei23f71622021-12-02 07:41:21 +0000356def link_function_pointer(function_pointer, types):
357 link_function(function_pointer, types)
Kai Ninomiya01aeca22020-07-15 19:51:17 +0000358
359
Brandon Jones58a471a2021-02-08 19:48:06 +0000360def link_typedef(typedef, types):
361 typedef.type = types[typedef.json_data['type']]
362
363
fujunwei4e876902021-11-25 08:44:01 +0000364def link_constant(constant, types):
365 constant.type = types[constant.json_data['type']]
366 assert constant.type.name.native
367
368
fujunwei23f71622021-12-02 07:41:21 +0000369def link_function(function, types):
370 function.return_type = types[function.json_data.get('returns', 'void')]
371 function.arguments = linked_record_members(function.json_data['args'],
372 types)
373
374
Kai Ninomiya01aeca22020-07-15 19:51:17 +0000375# Sort structures so that if struct A has struct B as a member, then B is
376# listed before A.
377#
378# This is a form of topological sort where we try to keep the order reasonably
379# similar to the original order (though the sort isn't technically stable).
380#
381# It works by computing for each struct type what is the depth of its DAG of
Kai Ninomiya7d174a12021-09-21 17:36:27 +0000382# dependents, then re-sorting based on that depth using Python's stable sort.
Kai Ninomiya01aeca22020-07-15 19:51:17 +0000383# This makes a toposort because if A depends on B then its depth will be bigger
384# than B's. It is also nice because all nodes with the same depth are kept in
385# the input order.
Corentin Wallez29353d62018-09-18 12:49:22 +0000386def topo_sort_structure(structs):
387 for struct in structs:
388 struct.visited = False
389 struct.subdag_depth = 0
390
391 def compute_depth(struct):
392 if struct.visited:
393 return struct.subdag_depth
394
395 max_dependent_depth = 0
396 for member in struct.members:
Corentin Walleze2f94842018-12-05 17:49:04 +0000397 if member.type.category == 'structure':
Kai Ninomiya01aeca22020-07-15 19:51:17 +0000398 max_dependent_depth = max(max_dependent_depth,
399 compute_depth(member.type) + 1)
Corentin Wallez29353d62018-09-18 12:49:22 +0000400
401 struct.subdag_depth = max_dependent_depth
402 struct.visited = True
403 return struct.subdag_depth
404
405 for struct in structs:
406 compute_depth(struct)
407
408 result = sorted(structs, key=lambda struct: struct.subdag_depth)
409
410 for struct in structs:
411 del struct.visited
412 del struct.subdag_depth
413
414 return result
415
Kai Ninomiya01aeca22020-07-15 19:51:17 +0000416
Austin Eng2f218e22021-12-22 19:02:23 +0000417def parse_json(json, enabled_tags, disabled_tags=None):
418 is_enabled = lambda json_data: item_is_enabled(
419 enabled_tags, json_data) and not item_is_disabled(
420 disabled_tags, json_data)
Corentin Wallezf07e3bd2017-04-20 14:38:20 -0400421 category_to_parser = {
Corentin Wallez031fbbb2019-06-11 18:03:05 +0000422 'bitmask': BitmaskType,
423 'enum': EnumType,
424 'native': NativeType,
fujunwei23f71622021-12-02 07:41:21 +0000425 'function pointer': FunctionPointerType,
Corentin Wallez031fbbb2019-06-11 18:03:05 +0000426 'object': ObjectType,
427 'structure': StructureType,
Brandon Jones58a471a2021-02-08 19:48:06 +0000428 'typedef': TypedefType,
fujunwei4e876902021-11-25 08:44:01 +0000429 'constant': ConstantDefinition,
fujunwei23f71622021-12-02 07:41:21 +0000430 'function': FunctionDeclaration
Corentin Wallezf07e3bd2017-04-20 14:38:20 -0400431 }
432
433 types = {}
434
435 by_category = {}
436 for name in category_to_parser.keys():
437 by_category[name] = []
438
Corentin Walleze2f94842018-12-05 17:49:04 +0000439 for (name, json_data) in json.items():
Austin Eng2f218e22021-12-22 19:02:23 +0000440 if name[0] == '_' or not is_enabled(json_data):
Corentin Wallezf07e3bd2017-04-20 14:38:20 -0400441 continue
Corentin Walleze2f94842018-12-05 17:49:04 +0000442 category = json_data['category']
Kai Ninomiya930e9182021-09-17 19:44:43 +0000443 parsed = category_to_parser[category](is_enabled, name, json_data)
Corentin Wallezf07e3bd2017-04-20 14:38:20 -0400444 by_category[category].append(parsed)
445 types[name] = parsed
446
447 for obj in by_category['object']:
448 link_object(obj, types)
449
Corentin Walleza6416542018-05-17 16:55:53 -0400450 for struct in by_category['structure']:
451 link_structure(struct, types)
452
fujunwei23f71622021-12-02 07:41:21 +0000453 for function_pointer in by_category['function pointer']:
454 link_function_pointer(function_pointer, types)
Corentin Wallez540abab2019-11-22 13:18:22 +0000455
Brandon Jones58a471a2021-02-08 19:48:06 +0000456 for typedef in by_category['typedef']:
457 link_typedef(typedef, types)
458
fujunwei4e876902021-11-25 08:44:01 +0000459 for constant in by_category['constant']:
460 link_constant(constant, types)
461
fujunwei23f71622021-12-02 07:41:21 +0000462 for function in by_category['function']:
463 link_function(function, types)
464
Corentin Wallezf07e3bd2017-04-20 14:38:20 -0400465 for category in by_category.keys():
Kai Ninomiya01aeca22020-07-15 19:51:17 +0000466 by_category[category] = sorted(
467 by_category[category], key=lambda typ: typ.name.canonical_case())
Corentin Wallezf07e3bd2017-04-20 14:38:20 -0400468
Corentin Wallez29353d62018-09-18 12:49:22 +0000469 by_category['structure'] = topo_sort_structure(by_category['structure'])
470
Austin Engc7f416c2019-01-15 20:49:53 +0000471 for struct in by_category['structure']:
472 struct.update_metadata()
473
Kai Ninomiya930e9182021-09-17 19:44:43 +0000474 api_params = {
475 'types': types,
476 'by_category': by_category,
477 'enabled_tags': enabled_tags,
Austin Eng2f218e22021-12-22 19:02:23 +0000478 'disabled_tags': disabled_tags,
Kai Ninomiya930e9182021-09-17 19:44:43 +0000479 }
480 return {
fujunwei76bda372021-11-23 08:47:35 +0000481 'metadata': Metadata(json['_metadata']),
Kai Ninomiya930e9182021-09-17 19:44:43 +0000482 'types': types,
483 'by_category': by_category,
484 'enabled_tags': enabled_tags,
Austin Eng2f218e22021-12-22 19:02:23 +0000485 'disabled_tags': disabled_tags,
Kai Ninomiya930e9182021-09-17 19:44:43 +0000486 'c_methods': lambda typ: c_methods(api_params, typ),
487 'c_methods_sorted_by_name': get_c_methods_sorted_by_name(api_params),
488 }
Kai Ninomiya01aeca22020-07-15 19:51:17 +0000489
Corentin Wallezf07e3bd2017-04-20 14:38:20 -0400490
Corentin Wallez031fbbb2019-06-11 18:03:05 +0000491############################################################
492# WIRE STUFF
493############################################################
494
Kai Ninomiya01aeca22020-07-15 19:51:17 +0000495
Corentin Wallez031fbbb2019-06-11 18:03:05 +0000496# Create wire commands from api methods
497def compute_wire_params(api_params, wire_json):
498 wire_params = api_params.copy()
499 types = wire_params['types']
500
501 commands = []
502 return_commands = []
503
Kai Ninomiya01aeca22020-07-15 19:51:17 +0000504 wire_json['special items']['client_handwritten_commands'] += wire_json[
505 'special items']['client_side_commands']
Corentin Wallez540abab2019-11-22 13:18:22 +0000506
Corentin Wallez031fbbb2019-06-11 18:03:05 +0000507 # Generate commands from object methods
508 for api_object in wire_params['by_category']['object']:
509 for method in api_object.methods:
510 command_name = concat_names(api_object.name, method.name)
511 command_suffix = Name(command_name).CamelCase()
512
Kai Ninomiya01aeca22020-07-15 19:51:17 +0000513 # Only object return values or void are supported.
514 # Other methods must be handwritten.
515 is_object = method.return_type.category == 'object'
516 is_void = method.return_type.name.canonical_case() == 'void'
517 if not (is_object or is_void):
518 assert command_suffix in (
519 wire_json['special items']['client_handwritten_commands'])
Corentin Wallez031fbbb2019-06-11 18:03:05 +0000520 continue
521
Kai Ninomiya01aeca22020-07-15 19:51:17 +0000522 if command_suffix in (
523 wire_json['special items']['client_side_commands']):
Corentin Wallez031fbbb2019-06-11 18:03:05 +0000524 continue
525
526 # Create object method commands by prepending "self"
Kai Ninomiya01aeca22020-07-15 19:51:17 +0000527 members = [
528 RecordMember(Name('self'), types[api_object.dict_name],
Kai Ninomiya930e9182021-09-17 19:44:43 +0000529 'value', {})
Kai Ninomiya01aeca22020-07-15 19:51:17 +0000530 ]
Corentin Wallez031fbbb2019-06-11 18:03:05 +0000531 members += method.arguments
532
Kai Ninomiya01aeca22020-07-15 19:51:17 +0000533 # Client->Server commands that return an object return the
534 # result object handle
Corentin Wallez031fbbb2019-06-11 18:03:05 +0000535 if method.return_type.category == 'object':
Kai Ninomiya01aeca22020-07-15 19:51:17 +0000536 result = RecordMember(Name('result'),
537 types['ObjectHandle'],
Kai Ninomiya930e9182021-09-17 19:44:43 +0000538 'value', {},
Kai Ninomiya01aeca22020-07-15 19:51:17 +0000539 is_return_value=True)
Corentin Wallez031fbbb2019-06-11 18:03:05 +0000540 result.set_handle_type(method.return_type)
541 members.append(result)
542
543 command = Command(command_name, members)
544 command.derived_object = api_object
545 command.derived_method = method
546 commands.append(command)
547
548 for (name, json_data) in wire_json['commands'].items():
549 commands.append(Command(name, linked_record_members(json_data, types)))
550
551 for (name, json_data) in wire_json['return commands'].items():
Kai Ninomiya01aeca22020-07-15 19:51:17 +0000552 return_commands.append(
553 Command(name, linked_record_members(json_data, types)))
Corentin Wallez031fbbb2019-06-11 18:03:05 +0000554
555 wire_params['cmd_records'] = {
556 'command': commands,
557 'return command': return_commands
558 }
559
560 for commands in wire_params['cmd_records'].values():
561 for command in commands:
562 command.update_metadata()
563 commands.sort(key=lambda c: c.name.canonical_case())
564
565 wire_params.update(wire_json.get('special items', {}))
566
567 return wire_params
568
Kai Ninomiya01aeca22020-07-15 19:51:17 +0000569
Corentin Wallezf07e3bd2017-04-20 14:38:20 -0400570#############################################################
Corentin Wallez0c38e922019-06-07 08:59:17 +0000571# Generator
Corentin Wallezf07e3bd2017-04-20 14:38:20 -0400572#############################################################
Corentin Wallezf07e3bd2017-04-20 14:38:20 -0400573
Kai Ninomiya01aeca22020-07-15 19:51:17 +0000574
Corentin Wallezf07e3bd2017-04-20 14:38:20 -0400575def as_varName(*names):
Kai Ninomiya01aeca22020-07-15 19:51:17 +0000576 return names[0].camelCase() + ''.join(
577 [name.CamelCase() for name in names[1:]])
578
Corentin Wallezf07e3bd2017-04-20 14:38:20 -0400579
fujunwei76bda372021-11-23 08:47:35 +0000580def as_cType(c_prefix, name):
Corentin Wallezf07e3bd2017-04-20 14:38:20 -0400581 if name.native:
582 return name.concatcase()
583 else:
fujunwei76bda372021-11-23 08:47:35 +0000584 return c_prefix + name.CamelCase()
Corentin Wallez919812e2019-10-17 08:46:07 +0000585
Kai Ninomiya01aeca22020-07-15 19:51:17 +0000586
Corentin Wallezf07e3bd2017-04-20 14:38:20 -0400587def as_cppType(name):
588 if name.native:
589 return name.concatcase()
590 else:
591 return name.CamelCase()
592
Kai Ninomiya01aeca22020-07-15 19:51:17 +0000593
Kai Ninomiya7b6246a2020-01-28 23:54:38 +0000594def as_jsEnumValue(value):
Kai Ninomiya930e9182021-09-17 19:44:43 +0000595 if 'jsrepr' in value.json_data: return value.json_data['jsrepr']
Kai Ninomiya7b6246a2020-01-28 23:54:38 +0000596 return "'" + value.name.js_enum_case() + "'"
597
Kai Ninomiya01aeca22020-07-15 19:51:17 +0000598
Austin Eng740995c2019-05-15 18:55:22 +0000599def convert_cType_to_cppType(typ, annotation, arg, indent=0):
600 if typ.category == 'native':
601 return arg
602 if annotation == 'value':
603 if typ.category == 'object':
604 return '{}::Acquire({})'.format(as_cppType(typ.name), arg)
605 elif typ.category == 'structure':
606 converted_members = [
607 convert_cType_to_cppType(
608 member.type, member.annotation,
Kai Ninomiya01aeca22020-07-15 19:51:17 +0000609 '{}.{}'.format(arg, as_varName(member.name)), indent + 1)
610 for member in typ.members
611 ]
Austin Eng740995c2019-05-15 18:55:22 +0000612
Kai Ninomiya01aeca22020-07-15 19:51:17 +0000613 converted_members = [(' ' * 4) + m for m in converted_members]
Austin Eng740995c2019-05-15 18:55:22 +0000614 converted_members = ',\n'.join(converted_members)
615
616 return as_cppType(typ.name) + ' {\n' + converted_members + '\n}'
fujunweid3cac112021-12-14 02:20:15 +0000617 elif typ.category == 'function pointer':
618 return 'reinterpret_cast<{}>({})'.format(as_cppType(typ.name), arg)
Austin Eng740995c2019-05-15 18:55:22 +0000619 else:
620 return 'static_cast<{}>({})'.format(as_cppType(typ.name), arg)
621 else:
Kai Ninomiya01aeca22020-07-15 19:51:17 +0000622 return 'reinterpret_cast<{} {}>({})'.format(as_cppType(typ.name),
623 annotation, arg)
624
Austin Eng740995c2019-05-15 18:55:22 +0000625
Corentin Wallezf07e3bd2017-04-20 14:38:20 -0400626def decorate(name, typ, arg):
627 if arg.annotation == 'value':
628 return typ + ' ' + name
Austin Eng740995c2019-05-15 18:55:22 +0000629 elif arg.annotation == '*':
630 return typ + ' * ' + name
Corentin Wallezf07e3bd2017-04-20 14:38:20 -0400631 elif arg.annotation == 'const*':
632 return typ + ' const * ' + name
Austin Eng2f218e22021-12-22 19:02:23 +0000633 elif arg.annotation == 'const*const*':
634 return 'const ' + typ + '* const * ' + name
Corentin Wallezf07e3bd2017-04-20 14:38:20 -0400635 else:
Kai Ninomiya01aeca22020-07-15 19:51:17 +0000636 assert False
637
Corentin Wallezf07e3bd2017-04-20 14:38:20 -0400638
639def annotated(typ, arg):
640 name = as_varName(arg.name)
641 return decorate(name, typ, arg)
642
Kai Ninomiya01aeca22020-07-15 19:51:17 +0000643
Kai Ninomiya930e9182021-09-17 19:44:43 +0000644def item_is_enabled(enabled_tags, json_data):
645 tags = json_data.get('tags')
646 if tags is None: return True
647 return any(tag in enabled_tags for tag in tags)
648
649
Austin Eng2f218e22021-12-22 19:02:23 +0000650def item_is_disabled(disabled_tags, json_data):
651 if disabled_tags is None: return False
652 tags = json_data.get('tags')
653 if tags is None: return False
654
655 return any(tag in disabled_tags for tag in tags)
656
657
Corentin Wallezf07e3bd2017-04-20 14:38:20 -0400658def as_cppEnum(value_name):
Kai Ninomiya01aeca22020-07-15 19:51:17 +0000659 assert not value_name.native
Corentin Wallezf07e3bd2017-04-20 14:38:20 -0400660 if value_name.concatcase()[0].isdigit():
661 return "e" + value_name.CamelCase()
662 return value_name.CamelCase()
663
Kai Ninomiya01aeca22020-07-15 19:51:17 +0000664
Corentin Wallezf07e3bd2017-04-20 14:38:20 -0400665def as_MethodSuffix(type_name, method_name):
Kai Ninomiya01aeca22020-07-15 19:51:17 +0000666 assert not type_name.native and not method_name.native
Corentin Wallezf07e3bd2017-04-20 14:38:20 -0400667 return type_name.CamelCase() + method_name.CamelCase()
668
Kai Ninomiya01aeca22020-07-15 19:51:17 +0000669
fujunwei76bda372021-11-23 08:47:35 +0000670def as_frontendType(metadata, typ):
Corentin Wallezf07e3bd2017-04-20 14:38:20 -0400671 if typ.category == 'object':
Corentin Wallez4f5fc2d2019-04-01 21:48:38 +0000672 return typ.name.CamelCase() + 'Base*'
Corentin Wallezfe253f12018-08-01 15:12:10 +0200673 elif typ.category in ['bitmask', 'enum']:
fujunwei76bda372021-11-23 08:47:35 +0000674 return metadata.namespace + '::' + typ.name.CamelCase()
Corentin Wallezfe253f12018-08-01 15:12:10 +0200675 elif typ.category == 'structure':
676 return as_cppType(typ.name)
Corentin Wallezf07e3bd2017-04-20 14:38:20 -0400677 else:
fujunwei76bda372021-11-23 08:47:35 +0000678 return as_cType(metadata.c_prefix, typ.name)
Corentin Wallezf07e3bd2017-04-20 14:38:20 -0400679
Kai Ninomiya01aeca22020-07-15 19:51:17 +0000680
fujunwei76bda372021-11-23 08:47:35 +0000681def as_wireType(metadata, typ):
Austin Engcb0cb652019-08-27 21:41:56 +0000682 if typ.category == 'object':
683 return typ.name.CamelCase() + '*'
Brandon Jones6f2bbe92021-04-05 23:34:17 +0000684 elif typ.category in ['bitmask', 'enum', 'structure']:
fujunwei76bda372021-11-23 08:47:35 +0000685 return metadata.c_prefix + typ.name.CamelCase()
Austin Engcb0cb652019-08-27 21:41:56 +0000686 else:
687 return as_cppType(typ.name)
688
Kai Ninomiya01aeca22020-07-15 19:51:17 +0000689
Loko Kung4d835252022-03-19 00:21:48 +0000690def as_formatType(typ):
691 # Unsigned integral types
692 if typ.json_data['type'] in ['bool', 'uint32_t', 'uint64_t']:
693 return 'u'
694
695 # Defaults everything else to strings.
696 return 's'
697
698
Kai Ninomiya930e9182021-09-17 19:44:43 +0000699def c_methods(params, typ):
Corentin Wallezaca8c4a2019-11-22 14:02:52 +0000700 return typ.methods + [
Kai Ninomiya930e9182021-09-17 19:44:43 +0000701 x for x in [
702 Method(Name('reference'), params['types']['void'], [],
703 {'tags': ['dawn', 'emscripten']}),
704 Method(Name('release'), params['types']['void'], [],
705 {'tags': ['dawn', 'emscripten']}),
706 ] if item_is_enabled(params['enabled_tags'], x.json_data)
Austin Eng2f218e22021-12-22 19:02:23 +0000707 and not item_is_disabled(params['disabled_tags'], x.json_data)
Corentin Wallez4b410a32017-04-20 14:42:36 -0400708 ]
709
Kai Ninomiya01aeca22020-07-15 19:51:17 +0000710
Corentin Wallezaca8c4a2019-11-22 14:02:52 +0000711def get_c_methods_sorted_by_name(api_params):
Corentin Wallezc57b1802019-10-15 12:08:48 +0000712 unsorted = [(as_MethodSuffix(typ.name, method.name), typ, method) \
713 for typ in api_params['by_category']['object'] \
Kai Ninomiya930e9182021-09-17 19:44:43 +0000714 for method in c_methods(api_params, typ) ]
Corentin Wallezc57b1802019-10-15 12:08:48 +0000715 return [(typ, method) for (_, typ, method) in sorted(unsorted)]
716
Kai Ninomiya01aeca22020-07-15 19:51:17 +0000717
Corentin Wallez540abab2019-11-22 13:18:22 +0000718def has_callback_arguments(method):
fujunwei23f71622021-12-02 07:41:21 +0000719 return any(arg.type.category == 'function pointer' for arg in method.arguments)
Corentin Wallez540abab2019-11-22 13:18:22 +0000720
Kai Ninomiya01aeca22020-07-15 19:51:17 +0000721
fujunwei76bda372021-11-23 08:47:35 +0000722def make_base_render_params(metadata):
723 c_prefix = metadata.c_prefix
724
725 def as_cTypeEnumSpecialCase(typ):
726 if typ.category == 'bitmask':
727 return as_cType(c_prefix, typ.name) + 'Flags'
728 return as_cType(c_prefix, typ.name)
729
730 def as_cEnum(type_name, value_name):
731 assert not type_name.native and not value_name.native
732 return c_prefix + type_name.CamelCase() + '_' + value_name.CamelCase()
733
734 def as_cMethod(type_name, method_name):
fujunwei23f71622021-12-02 07:41:21 +0000735 c_method = c_prefix.lower()
736 if type_name != None:
737 assert not type_name.native
738 c_method += type_name.CamelCase()
739 assert not method_name.native
740 c_method += method_name.CamelCase()
741 return c_method
fujunwei76bda372021-11-23 08:47:35 +0000742
743 def as_cProc(type_name, method_name):
fujunwei23f71622021-12-02 07:41:21 +0000744 c_proc = c_prefix + 'Proc'
745 if type_name != None:
746 assert not type_name.native
747 c_proc += type_name.CamelCase()
748 assert not method_name.native
749 c_proc += method_name.CamelCase()
750 return c_proc
fujunwei76bda372021-11-23 08:47:35 +0000751
752 return {
753 'Name': lambda name: Name(name),
754 'as_annotated_cType': \
755 lambda arg: annotated(as_cTypeEnumSpecialCase(arg.type), arg),
756 'as_annotated_cppType': \
757 lambda arg: annotated(as_cppType(arg.type.name), arg),
758 'as_cEnum': as_cEnum,
759 'as_cppEnum': as_cppEnum,
760 'as_cMethod': as_cMethod,
761 'as_MethodSuffix': as_MethodSuffix,
762 'as_cProc': as_cProc,
763 'as_cType': lambda name: as_cType(c_prefix, name),
764 'as_cppType': as_cppType,
765 'as_jsEnumValue': as_jsEnumValue,
766 'convert_cType_to_cppType': convert_cType_to_cppType,
767 'as_varName': as_varName,
Loko Kung4d835252022-03-19 00:21:48 +0000768 'decorate': decorate,
769 'as_formatType': as_formatType
fujunwei76bda372021-11-23 08:47:35 +0000770 }
771
772
Corentin Wallez0c38e922019-06-07 08:59:17 +0000773class MultiGeneratorFromDawnJSON(Generator):
774 def get_description(self):
775 return 'Generates code for various target from Dawn.json.'
Corentin Wallezf07e3bd2017-04-20 14:38:20 -0400776
Corentin Wallez0c38e922019-06-07 08:59:17 +0000777 def add_commandline_arguments(self, parser):
Kai Ninomiya01aeca22020-07-15 19:51:17 +0000778 allowed_targets = [
Ben Clayton35940f92022-02-04 17:15:16 +0000779 'dawn_headers', 'cpp_headers', 'cpp', 'proc', 'mock_api', 'wire',
780 'native_utils'
Kai Ninomiya01aeca22020-07-15 19:51:17 +0000781 ]
Corentin Wallezf07e3bd2017-04-20 14:38:20 -0400782
Kai Ninomiya01aeca22020-07-15 19:51:17 +0000783 parser.add_argument('--dawn-json',
784 required=True,
785 type=str,
786 help='The DAWN JSON definition to use.')
787 parser.add_argument('--wire-json',
788 default=None,
789 type=str,
790 help='The DAWN WIRE JSON definition to use.')
791 parser.add_argument(
792 '--targets',
793 required=True,
794 type=str,
795 help=
796 'Comma-separated subset of targets to output. Available targets: '
797 + ', '.join(allowed_targets))
Corentin Wallez0c38e922019-06-07 08:59:17 +0000798 def get_file_renders(self, args):
799 with open(args.dawn_json) as f:
800 loaded_json = json.loads(f.read())
Corentin Wallezf07e3bd2017-04-20 14:38:20 -0400801
Corentin Wallez0c38e922019-06-07 08:59:17 +0000802 targets = args.targets.split(',')
Corentin Wallez4b410a32017-04-20 14:42:36 -0400803
Corentin Wallez0c38e922019-06-07 08:59:17 +0000804 wire_json = None
805 if args.wire_json:
806 with open(args.wire_json) as f:
807 wire_json = json.loads(f.read())
Corentin Wallezf07e3bd2017-04-20 14:38:20 -0400808
Kai Ninomiya930e9182021-09-17 19:44:43 +0000809 renders = []
810
Kai Ninomiya930e9182021-09-17 19:44:43 +0000811 params_dawn = parse_json(loaded_json,
812 enabled_tags=['dawn', 'native', 'deprecated'])
fujunwei76bda372021-11-23 08:47:35 +0000813 metadata = params_dawn['metadata']
814 RENDER_PARAMS_BASE = make_base_render_params(metadata)
Corentin Wallez79a62bf2017-05-24 16:04:55 +0200815
fujunweic7d4f2c2021-12-07 00:46:35 +0000816 api = metadata.api.lower()
fujunweia8405742021-12-10 01:35:19 +0000817 prefix = metadata.proc_table_prefix.lower()
Ben Clayton35940f92022-02-04 17:15:16 +0000818 if 'headers' in targets:
Kai Ninomiya01aeca22020-07-15 19:51:17 +0000819 renders.append(
Ben Clayton9fb7a512022-02-04 18:18:18 +0000820 FileRender('api.h', 'include/dawn/' + api + '.h',
Kai Ninomiya930e9182021-09-17 19:44:43 +0000821 [RENDER_PARAMS_BASE, params_dawn]))
Kai Ninomiya01aeca22020-07-15 19:51:17 +0000822 renders.append(
823 FileRender('dawn_proc_table.h',
Ben Clayton9fb7a512022-02-04 18:18:18 +0000824 'include/dawn/' + prefix + '_proc_table.h',
Kai Ninomiya930e9182021-09-17 19:44:43 +0000825 [RENDER_PARAMS_BASE, params_dawn]))
Corentin Wallezf07e3bd2017-04-20 14:38:20 -0400826
Ben Clayton35940f92022-02-04 17:15:16 +0000827 if 'cpp_headers' in targets:
Kai Ninomiya01aeca22020-07-15 19:51:17 +0000828 renders.append(
Ben Clayton9fb7a512022-02-04 18:18:18 +0000829 FileRender('api_cpp.h', 'include/dawn/' + api + '_cpp.h',
Kai Ninomiya930e9182021-09-17 19:44:43 +0000830 [RENDER_PARAMS_BASE, params_dawn]))
Austin Engcc071e42019-10-16 10:26:01 +0000831
Austin Enga9e39e12021-06-01 18:49:12 +0000832 renders.append(
fujunweic7d4f2c2021-12-07 00:46:35 +0000833 FileRender('api_cpp_print.h',
Ben Clayton9fb7a512022-02-04 18:18:18 +0000834 'include/dawn/' + api + '_cpp_print.h',
Kai Ninomiya930e9182021-09-17 19:44:43 +0000835 [RENDER_PARAMS_BASE, params_dawn]))
Austin Enga9e39e12021-06-01 18:49:12 +0000836
Ben Clayton35940f92022-02-04 17:15:16 +0000837 if 'proc' in targets:
Kai Ninomiya01aeca22020-07-15 19:51:17 +0000838 renders.append(
fujunweia8405742021-12-10 01:35:19 +0000839 FileRender('dawn_proc.c', 'src/dawn/' + prefix + '_proc.c',
Kai Ninomiya930e9182021-09-17 19:44:43 +0000840 [RENDER_PARAMS_BASE, params_dawn]))
Austin Eng16e01af2020-10-06 16:13:42 +0000841 renders.append(
842 FileRender('dawn_thread_dispatch_proc.cpp',
fujunweia8405742021-12-10 01:35:19 +0000843 'src/dawn/' + prefix + '_thread_dispatch_proc.cpp',
Kai Ninomiya930e9182021-09-17 19:44:43 +0000844 [RENDER_PARAMS_BASE, params_dawn]))
Corentin Wallez96496822019-10-15 11:44:38 +0000845
Austin Eng63f65462021-12-09 20:03:48 +0000846 if 'webgpu_dawn_native_proc' in targets:
847 renders.append(
Ben Clayton818001d2022-02-04 17:07:46 +0000848 FileRender('dawn/native/api_dawn_native_proc.cpp',
849 'src/dawn/native/webgpu_dawn_native_proc.cpp',
Austin Eng63f65462021-12-09 20:03:48 +0000850 [RENDER_PARAMS_BASE, params_dawn]))
851
Ben Clayton35940f92022-02-04 17:15:16 +0000852 if 'cpp' in targets:
Kai Ninomiya01aeca22020-07-15 19:51:17 +0000853 renders.append(
fujunweid3cac112021-12-14 02:20:15 +0000854 FileRender('api_cpp.cpp', 'src/dawn/' + api + '_cpp.cpp',
Kai Ninomiya930e9182021-09-17 19:44:43 +0000855 [RENDER_PARAMS_BASE, params_dawn]))
856
857 if 'webgpu_headers' in targets:
858 params_upstream = parse_json(loaded_json,
Shrek Shao1554a7d2022-03-08 20:56:10 +0000859 enabled_tags=['upstream', 'native'],
860 disabled_tags=['dawn'])
Kai Ninomiya930e9182021-09-17 19:44:43 +0000861 renders.append(
fujunweic7d4f2c2021-12-07 00:46:35 +0000862 FileRender('api.h', 'webgpu-headers/' + api + '.h',
Kai Ninomiya930e9182021-09-17 19:44:43 +0000863 [RENDER_PARAMS_BASE, params_upstream]))
Corentin Wallez59e7fad2018-08-16 15:32:35 +0200864
Kai Ninomiya7b6246a2020-01-28 23:54:38 +0000865 if 'emscripten_bits' in targets:
Shrek Shaoee50bc02022-02-08 20:21:40 +0000866 params_emscripten = parse_json(loaded_json,
867 enabled_tags=['emscripten'])
Kai Ninomiya930e9182021-09-17 19:44:43 +0000868 renders.append(
fujunweic7d4f2c2021-12-07 00:46:35 +0000869 FileRender('api.h', 'emscripten-bits/' + api + '.h',
Kai Ninomiya930e9182021-09-17 19:44:43 +0000870 [RENDER_PARAMS_BASE, params_emscripten]))
871 renders.append(
fujunweic7d4f2c2021-12-07 00:46:35 +0000872 FileRender('api_cpp.h', 'emscripten-bits/' + api + '_cpp.h',
Kai Ninomiya930e9182021-09-17 19:44:43 +0000873 [RENDER_PARAMS_BASE, params_emscripten]))
874 renders.append(
fujunweid3cac112021-12-14 02:20:15 +0000875 FileRender('api_cpp.cpp', 'emscripten-bits/' + api + '_cpp.cpp',
Kai Ninomiya930e9182021-09-17 19:44:43 +0000876 [RENDER_PARAMS_BASE, params_emscripten]))
Kai Ninomiya01aeca22020-07-15 19:51:17 +0000877 renders.append(
fujunwei16ae3b82021-12-15 04:35:26 +0000878 FileRender('api_struct_info.json',
879 'emscripten-bits/' + api + '_struct_info.json',
Kai Ninomiya930e9182021-09-17 19:44:43 +0000880 [RENDER_PARAMS_BASE, params_emscripten]))
Kai Ninomiya01aeca22020-07-15 19:51:17 +0000881 renders.append(
fujunwei16ae3b82021-12-15 04:35:26 +0000882 FileRender('library_api_enum_tables.js',
883 'emscripten-bits/library_' + api + '_enum_tables.js',
Kai Ninomiya930e9182021-09-17 19:44:43 +0000884 [RENDER_PARAMS_BASE, params_emscripten]))
Kai Ninomiya7b6246a2020-01-28 23:54:38 +0000885
fujunwei16ae3b82021-12-15 04:35:26 +0000886 if 'mock_api' in targets:
Corentin Wallez540abab2019-11-22 13:18:22 +0000887 mock_params = [
Kai Ninomiya930e9182021-09-17 19:44:43 +0000888 RENDER_PARAMS_BASE, params_dawn, {
Corentin Wallez540abab2019-11-22 13:18:22 +0000889 'has_callback_arguments': has_callback_arguments
890 }
891 ]
Kai Ninomiya01aeca22020-07-15 19:51:17 +0000892 renders.append(
fujunwei16ae3b82021-12-15 04:35:26 +0000893 FileRender('mock_api.h', 'src/dawn/mock_' + api + '.h',
Kai Ninomiya01aeca22020-07-15 19:51:17 +0000894 mock_params))
895 renders.append(
fujunwei16ae3b82021-12-15 04:35:26 +0000896 FileRender('mock_api.cpp', 'src/dawn/mock_' + api + '.cpp',
Kai Ninomiya01aeca22020-07-15 19:51:17 +0000897 mock_params))
Corentin Wallez59e7fad2018-08-16 15:32:35 +0200898
Ben Clayton818001d2022-02-04 17:07:46 +0000899 if 'native_utils' in targets:
Corentin Wallez0c38e922019-06-07 08:59:17 +0000900 frontend_params = [
Kai Ninomiya930e9182021-09-17 19:44:43 +0000901 RENDER_PARAMS_BASE,
902 params_dawn,
Corentin Wallez0c38e922019-06-07 08:59:17 +0000903 {
Kai Ninomiya01aeca22020-07-15 19:51:17 +0000904 # TODO: as_frontendType and co. take a Type, not a Name :(
fujunwei76bda372021-11-23 08:47:35 +0000905 'as_frontendType': lambda typ: as_frontendType(metadata, typ),
Kai Ninomiya01aeca22020-07-15 19:51:17 +0000906 'as_annotated_frontendType': \
fujunwei76bda372021-11-23 08:47:35 +0000907 lambda arg: annotated(as_frontendType(metadata, arg.type), arg),
Corentin Wallez0c38e922019-06-07 08:59:17 +0000908 }
909 ]
Corentin Wallez59e7fad2018-08-16 15:32:35 +0200910
fujunweia2241d42021-12-16 04:54:38 +0000911 impl_dir = metadata.impl_dir + '/' if metadata.impl_dir else ''
Ben Clayton818001d2022-02-04 17:07:46 +0000912 native_dir = impl_dir + Name(metadata.native_namespace).Dirs()
fujunwei7f3f8ac2021-12-21 03:27:34 +0000913 namespace = metadata.namespace
Kai Ninomiya01aeca22020-07-15 19:51:17 +0000914 renders.append(
Ben Clayton818001d2022-02-04 17:07:46 +0000915 FileRender('dawn/native/ValidationUtils.h',
fujunweia2241d42021-12-16 04:54:38 +0000916 'src/' + native_dir + '/ValidationUtils_autogen.h',
Kai Ninomiya01aeca22020-07-15 19:51:17 +0000917 frontend_params))
918 renders.append(
Ben Clayton818001d2022-02-04 17:07:46 +0000919 FileRender('dawn/native/ValidationUtils.cpp',
fujunweia2241d42021-12-16 04:54:38 +0000920 'src/' + native_dir + '/ValidationUtils_autogen.cpp',
Kai Ninomiya01aeca22020-07-15 19:51:17 +0000921 frontend_params))
922 renders.append(
Ben Clayton818001d2022-02-04 17:07:46 +0000923 FileRender('dawn/native/dawn_platform.h',
fujunweifc38f7d2021-12-17 00:46:08 +0000924 'src/' + native_dir + '/' + prefix + '_platform_autogen.h',
Austin Eng3faa4782021-10-27 19:07:37 +0000925 frontend_params))
926 renders.append(
Ben Clayton818001d2022-02-04 17:07:46 +0000927 FileRender('dawn/native/api_structs.h',
fujunwei7f3f8ac2021-12-21 03:27:34 +0000928 'src/' + native_dir + '/' + namespace + '_structs_autogen.h',
Kai Ninomiya01aeca22020-07-15 19:51:17 +0000929 frontend_params))
930 renders.append(
Ben Clayton818001d2022-02-04 17:07:46 +0000931 FileRender('dawn/native/api_structs.cpp',
fujunwei7f3f8ac2021-12-21 03:27:34 +0000932 'src/' + native_dir + '/' + namespace + '_structs_autogen.cpp',
Kai Ninomiya01aeca22020-07-15 19:51:17 +0000933 frontend_params))
934 renders.append(
Ben Clayton818001d2022-02-04 17:07:46 +0000935 FileRender('dawn/native/ProcTable.cpp',
Ningxin Hu7e5930b2021-12-22 06:12:13 +0000936 'src/' + native_dir + '/ProcTable.cpp', frontend_params))
Brian Ho5346e772021-04-22 17:49:42 +0000937 renders.append(
Ben Clayton818001d2022-02-04 17:07:46 +0000938 FileRender('dawn/native/ChainUtils.h',
fujunwei2b1dcd92021-12-22 01:05:03 +0000939 'src/' + native_dir + '/ChainUtils_autogen.h',
Brian Ho5346e772021-04-22 17:49:42 +0000940 frontend_params))
941 renders.append(
Ben Clayton818001d2022-02-04 17:07:46 +0000942 FileRender('dawn/native/ChainUtils.cpp',
fujunwei2b1dcd92021-12-22 01:05:03 +0000943 'src/' + native_dir + '/ChainUtils_autogen.cpp',
Brian Ho5346e772021-04-22 17:49:42 +0000944 frontend_params))
Brandon Jonesba662952021-09-23 21:26:33 +0000945 renders.append(
Ben Clayton818001d2022-02-04 17:07:46 +0000946 FileRender('dawn/native/api_absl_format.h',
fujunweif001ef52021-12-23 05:16:04 +0000947 'src/' + native_dir + '/' + api + '_absl_format_autogen.h',
Brandon Jonesba662952021-09-23 21:26:33 +0000948 frontend_params))
949 renders.append(
Ben Clayton818001d2022-02-04 17:07:46 +0000950 FileRender('dawn/native/api_absl_format.cpp',
fujunweif001ef52021-12-23 05:16:04 +0000951 'src/' + native_dir + '/' + api + '_absl_format_autogen.cpp',
Brandon Jonesba662952021-09-23 21:26:33 +0000952 frontend_params))
Loko Kung8d195d52021-09-28 15:40:01 +0000953 renders.append(
Austin Engbc285fb2022-07-29 00:36:21 +0000954 FileRender(
955 'dawn/native/api_StreamImpl.cpp', 'src/' + native_dir +
956 '/' + api + '_StreamImpl_autogen.cpp', frontend_params))
957 renders.append(
Ben Clayton818001d2022-02-04 17:07:46 +0000958 FileRender('dawn/native/ObjectType.h',
fujunwei2b1dcd92021-12-22 01:05:03 +0000959 'src/' + native_dir + '/ObjectType_autogen.h',
Loko Kung8d195d52021-09-28 15:40:01 +0000960 frontend_params))
961 renders.append(
Ben Clayton818001d2022-02-04 17:07:46 +0000962 FileRender('dawn/native/ObjectType.cpp',
fujunwei2b1dcd92021-12-22 01:05:03 +0000963 'src/' + native_dir + '/ObjectType_autogen.cpp',
Loko Kung8d195d52021-09-28 15:40:01 +0000964 frontend_params))
Corentin Wallez59e7fad2018-08-16 15:32:35 +0200965
Ben Clayton20cbe6d2022-02-04 12:51:25 +0000966 if 'wire' in targets:
Austin Eng2f218e22021-12-22 19:02:23 +0000967 params_dawn_wire = parse_json(loaded_json,
968 enabled_tags=['dawn', 'deprecated'],
969 disabled_tags=['native'])
970 additional_params = compute_wire_params(params_dawn_wire,
971 wire_json)
Corentin Wallez59e7fad2018-08-16 15:32:35 +0200972
Corentin Wallez0c38e922019-06-07 08:59:17 +0000973 wire_params = [
Austin Eng2f218e22021-12-22 19:02:23 +0000974 RENDER_PARAMS_BASE, params_dawn_wire, {
fujunwei76bda372021-11-23 08:47:35 +0000975 'as_wireType': lambda type : as_wireType(metadata, type),
Kai Ninomiya01aeca22020-07-15 19:51:17 +0000976 'as_annotated_wireType': \
fujunwei76bda372021-11-23 08:47:35 +0000977 lambda arg: annotated(as_wireType(metadata, arg.type), arg),
Kai Ninomiya01aeca22020-07-15 19:51:17 +0000978 }, additional_params
Corentin Wallez0c38e922019-06-07 08:59:17 +0000979 ]
Kai Ninomiya01aeca22020-07-15 19:51:17 +0000980 renders.append(
Ben Clayton20cbe6d2022-02-04 12:51:25 +0000981 FileRender('dawn/wire/ObjectType.h',
982 'src/dawn/wire/ObjectType_autogen.h', wire_params))
Austin Eng3120d5e2020-11-11 19:46:18 +0000983 renders.append(
Ben Clayton20cbe6d2022-02-04 12:51:25 +0000984 FileRender('dawn/wire/WireCmd.h',
985 'src/dawn/wire/WireCmd_autogen.h', wire_params))
Kai Ninomiya01aeca22020-07-15 19:51:17 +0000986 renders.append(
Ben Clayton20cbe6d2022-02-04 12:51:25 +0000987 FileRender('dawn/wire/WireCmd.cpp',
988 'src/dawn/wire/WireCmd_autogen.cpp', wire_params))
Kai Ninomiya01aeca22020-07-15 19:51:17 +0000989 renders.append(
Ben Clayton20cbe6d2022-02-04 12:51:25 +0000990 FileRender('dawn/wire/client/ApiObjects.h',
991 'src/dawn/wire/client/ApiObjects_autogen.h',
Kai Ninomiya01aeca22020-07-15 19:51:17 +0000992 wire_params))
993 renders.append(
Ben Clayton20cbe6d2022-02-04 12:51:25 +0000994 FileRender('dawn/wire/client/ApiProcs.cpp',
995 'src/dawn/wire/client/ApiProcs_autogen.cpp',
Kai Ninomiya01aeca22020-07-15 19:51:17 +0000996 wire_params))
997 renders.append(
Ben Clayton20cbe6d2022-02-04 12:51:25 +0000998 FileRender('dawn/wire/client/ClientBase.h',
999 'src/dawn/wire/client/ClientBase_autogen.h',
Kai Ninomiya01aeca22020-07-15 19:51:17 +00001000 wire_params))
1001 renders.append(
Ben Clayton20cbe6d2022-02-04 12:51:25 +00001002 FileRender('dawn/wire/client/ClientHandlers.cpp',
1003 'src/dawn/wire/client/ClientHandlers_autogen.cpp',
Kai Ninomiya01aeca22020-07-15 19:51:17 +00001004 wire_params))
1005 renders.append(
1006 FileRender(
Ben Clayton20cbe6d2022-02-04 12:51:25 +00001007 'dawn/wire/client/ClientPrototypes.inc',
1008 'src/dawn/wire/client/ClientPrototypes_autogen.inc',
Kai Ninomiya01aeca22020-07-15 19:51:17 +00001009 wire_params))
1010 renders.append(
Ben Clayton20cbe6d2022-02-04 12:51:25 +00001011 FileRender('dawn/wire/server/ServerBase.h',
1012 'src/dawn/wire/server/ServerBase_autogen.h',
Kai Ninomiya01aeca22020-07-15 19:51:17 +00001013 wire_params))
1014 renders.append(
Ben Clayton20cbe6d2022-02-04 12:51:25 +00001015 FileRender('dawn/wire/server/ServerDoers.cpp',
1016 'src/dawn/wire/server/ServerDoers_autogen.cpp',
Kai Ninomiya01aeca22020-07-15 19:51:17 +00001017 wire_params))
1018 renders.append(
Ben Clayton20cbe6d2022-02-04 12:51:25 +00001019 FileRender('dawn/wire/server/ServerHandlers.cpp',
1020 'src/dawn/wire/server/ServerHandlers_autogen.cpp',
Kai Ninomiya01aeca22020-07-15 19:51:17 +00001021 wire_params))
1022 renders.append(
1023 FileRender(
Ben Clayton20cbe6d2022-02-04 12:51:25 +00001024 'dawn/wire/server/ServerPrototypes.inc',
1025 'src/dawn/wire/server/ServerPrototypes_autogen.inc',
Kai Ninomiya01aeca22020-07-15 19:51:17 +00001026 wire_params))
Corentin Wallez59e7fad2018-08-16 15:32:35 +02001027
Corentin Wallez0c38e922019-06-07 08:59:17 +00001028 return renders
Corentin Wallez59e7fad2018-08-16 15:32:35 +02001029
Corentin Wallez0c38e922019-06-07 08:59:17 +00001030 def get_dependencies(self, args):
1031 deps = [os.path.abspath(args.dawn_json)]
1032 if args.wire_json != None:
1033 deps += [os.path.abspath(args.wire_json)]
1034 return deps
Corentin Wallezf07e3bd2017-04-20 14:38:20 -04001035
Kai Ninomiya01aeca22020-07-15 19:51:17 +00001036
Corentin Wallezf07e3bd2017-04-20 14:38:20 -04001037if __name__ == '__main__':
Corentin Wallez0c38e922019-06-07 08:59:17 +00001038 sys.exit(run_generator(MultiGeneratorFromDawnJSON()))