#!/usr/bin/env python3
# Copyright 2017 The Dawn & Tint Authors
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are met:
#
# 1. Redistributions of source code must retain the above copyright notice, this
#    list of conditions and the following disclaimer.
#
# 2. Redistributions in binary form must reproduce the above copyright notice,
#    this list of conditions and the following disclaimer in the documentation
#    and/or other materials provided with the distribution.
#
# 3. Neither the name of the copyright holder nor the names of its
#    contributors may be used to endorse or promote products derived from
#    this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

import json, os, sys
from collections import namedtuple, defaultdict
from copy import deepcopy

from generator_lib import Generator, run_generator, FileRender, GeneratorOutput
from webgpu_json_utility import build_doc_map, load_json_data

############################################################
# OBJECT MODEL
############################################################


class Metadata:
    def __init__(self, metadata):
        self.api = metadata['api']
        self.namespace = metadata['namespace']
        self.c_prefix = metadata.get('c_prefix', self.namespace.upper())
        self.proc_table_prefix = metadata['proc_table_prefix']
        self.impl_dir = metadata.get('impl_dir', '')
        self.native_namespace = metadata['native_namespace']
        self.copyright_year = metadata.get('copyright_year', None)

class Name:
    def __init__(self, name, native=False):
        self.native = native
        self.name = name
        if native:
            self.chunks = [name]
        else:
            self.chunks = name.split(' ')

    def __lt__(self, other):
        return self.concatcase().lower() < other.concatcase().lower()

    def get(self):
        return self.name

    def CamelChunk(self, chunk):
        return chunk[0].upper() + chunk[1:]

    def canonical_case(self):
        return ' '.join(self.chunks)

    def concatcase(self):
        return ''.join(self.chunks)

    def camelCase(self):
        return self.chunks[0] + ''.join(
            [self.CamelChunk(chunk) for chunk in self.chunks[1:]])

    def CamelCase(self):
        return ''.join([self.CamelChunk(chunk) for chunk in self.chunks])

    def SNAKE_CASE(self):
        return '_'.join([chunk.upper() for chunk in self.chunks])

    def snake_case(self):
        return '_'.join(self.chunks)

    def namespace_case(self):
        return '::'.join(self.chunks)

    def Dirs(self):
        return '/'.join(self.chunks)

    def js_enum_case(self):
        result = self.chunks[0].lower()
        for chunk in self.chunks[1:]:
            if not result[-1].isdigit():
                result += '-'
            result += chunk.lower()
        return result

def concat_names(*names):
    return ' '.join([name.canonical_case() for name in names])


def validate_and_get_tags(json_data):
    allowed_tags = {
        'dawn',
        'emscripten',
        'native',
        'compat',
        'deprecated',
        'art',
    }

    tags = json_data.get('tags')
    if tags != None:
        for tag in tags:
            assert tag in allowed_tags, f'unrecognized tag "{tag}"'
    return tags


class Type:
    def __init__(self, name, json_data, native=False):
        self.json_data = json_data
        self.dict_name = name
        self.name = Name(name, native=native)
        self.category = json_data['category']
        self.is_nullable_pointer = json_data.get('is nullable pointer',
                                                 self.category == 'object')
        self.is_wire_transparent = False

    def __lt__(self, other):
        return self.name < other.name


EnumValue = namedtuple('EnumValue', ['name', 'value', 'valid', 'json_data'])


class EnumType(Type):
    def __init__(self, is_enabled, name, json_data):
        Type.__init__(self, name, json_data)

        self.values = []
        self.hasUndefined = False
        self.contiguous = True
        self.startValue = None
        lastValue = None
        for m in self.json_data['values']:
            if not is_enabled(m):
                continue
            value = m['value']
            value_name = m['name']
            tags = validate_and_get_tags(m)
            if tags == None:
                tags = []

            prefix = 0
            if 'compat' in tags:
                assert prefix == 0
                prefix = 0x0002_0000

            if 'dawn' in tags:
                # Dawn-only or Dawn+Emscripten
                assert prefix == 0
                prefix = 0x0005_0000
            elif 'emscripten' in tags:
                # Emscripten-only
                assert prefix == 0
                prefix = 0x0004_0000

            if prefix == 0 and 'native' in tags:
                prefix = 0x0001_0000

            if 'deprecated' not in tags:
                # Emscripten implements some Dawn extensions, and some upstream things that
                # aren't in Dawn yet.
                if 'emscripten' in tags and 'dawn' not in tags:
                    assert value_name.startswith('emscripten'), name
                else:
                    assert not value_name.startswith('emscripten'), name

            value += prefix

            if value_name == "undefined":
                self.hasUndefined = True
            if lastValue == None:
                self.startValue = value
            elif value != lastValue + 1:
                self.contiguous = False
            lastValue = value
            self.values.append(
                EnumValue(Name(value_name), value, m.get('valid', True), m))

        # Assert that all values except those with "enum_value_conflict": true are unique in enums
        all_values = set()
        for value in self.values:
            if value.value in all_values:
                #TODO(42241174) remove this condition once wgpu refactoring is complete.
                if not value.json_data.get('enum_value_conflict', False):
                    raise Exception(
                        "Duplicate value {} for '{}' in enum '{}'".format(
                            hex(value.value), value.name.get(), name))
            all_values.add(value.value)
        self.is_wire_transparent = True


BitmaskValue = namedtuple('BitmaskValue', ['name', 'value', 'json_data'])


class BitmaskType(Type):
    def __init__(self, is_enabled, name, json_data):
        Type.__init__(self, name, json_data)
        self.values = [
            BitmaskValue(Name(m['name']), m['value'], m)
            for m in self.json_data['values'] if is_enabled(m)
        ]
        self.full_mask = 0
        for value in self.values:
            self.full_mask = self.full_mask | value.value
        self.is_wire_transparent = True


class CallbackFunctionType(Type):

    def __init__(self, is_enabled, name, json_data):
        Type.__init__(self, name, json_data)
        self.returns = None
        self.arguments = []


class FunctionPointerType(Type):
    def __init__(self, is_enabled, name, json_data):
        Type.__init__(self, name, json_data)
        self.returns = None
        self.arguments = []


class TypedefType(Type):
    def __init__(self, is_enabled, name, json_data):
        Type.__init__(self, name, json_data)
        self.type = None


class NativeType(Type):
    def __init__(self, is_enabled, name, json_data):
        Type.__init__(self, name, json_data, native=True)
        self.is_wire_transparent = json_data.get('wire transparent', True)


# Method/function argument, method/function return value, or struct member.
class AnnotatedTypedMember:

    def __init__(self, typ, annotation, optional, json_data):
        self.type = typ
        self.annotation = annotation
        self.optional = optional
        self.json_data = json_data


# Methods and structures are both "records", so record members correspond to
# method arguments or structure members.
class RecordMember(AnnotatedTypedMember):

    def __init__(self,
                 name,
                 typ,
                 annotation,
                 json_data,
                 optional=False,
                 array_element_optional=False,
                 is_return_value=False,
                 default_value=None,
                 skip_serialize=False):
        super().__init__(typ, annotation, optional, json_data)
        self.name = name
        self.length = None
        self.optional = optional
        self.array_element_optional = array_element_optional
        if array_element_optional:
            assert annotation == 'const*', 'array_element_optional can only be used on array types'
        self.is_return_value = is_return_value
        self.handle_type = None
        self.id_type = None
        self.default_value = default_value
        self.skip_serialize = skip_serialize

    def set_handle_type(self, handle_type):
        assert self.type.dict_name == "ObjectHandle"
        self.handle_type = handle_type

    def set_id_type(self, id_type):
        assert self.type.dict_name == "ObjectId"
        self.id_type = id_type

    @property
    def requires_struct_defaulting(self):
        if self.annotation != "value":
            return False

        if self.type.category == "structure":
            return self.type.any_member_requires_struct_defaulting
        elif self.type.category == "enum":
            return (self.type.hasUndefined
                    and self.default_value not in [None, "undefined"])
        else:
            return False


class Method():

    def __init__(self, name, returns, arguments, autolock, json_data):
        self.name = name
        self.returns = returns
        self.arguments = arguments
        self.autolock = autolock
        self.json_data = json_data


class ObjectType(Type):
    def __init__(self, is_enabled, name, json_data):
        json_data_override = {'methods': []}
        if 'methods' in json_data:
            json_data_override['methods'] = [
                m for m in json_data['methods'] if is_enabled(m)
            ]
        Type.__init__(self, name, dict(json_data, **json_data_override))


class Record:
    def __init__(self, name):
        self.name = Name(name)
        self.members = []
        self.may_have_dawn_object = False

    def update_metadata(self):
        def may_have_dawn_object(member):
            if isinstance(member.type, ObjectType):
                return True
            elif isinstance(member.type, StructureType):
                return member.type.may_have_dawn_object
            else:
                return False

        self.may_have_dawn_object = any(
            may_have_dawn_object(member) for member in self.members)

        # Set may_have_dawn_object to true if the type is chained or
        # extensible. Chained structs may contain a Dawn object.
        if isinstance(self, StructureType):
            self.may_have_dawn_object = (self.may_have_dawn_object
                                         or self.chained or self.extensible)


class StructureType(Record, Type):
    def __init__(self, is_enabled, name, json_data):
        tags = validate_and_get_tags(json_data)
        if tags == ['emscripten']:
            if name != 'INTERNAL_HAVE_EMDAWNWEBGPU_HEADER':
                assert name.startswith('emscripten'), name
        else:
            assert not name.startswith('emscripten'), name

        Record.__init__(self, name)
        json_data_override = {}
        if 'members' in json_data:
            json_data_override['members'] = [
                m for m in json_data['members'] if is_enabled(m)
            ]
        Type.__init__(self, name, dict(json_data, **json_data_override))
        self.out = json_data.get('out', False)
        self.chained = json_data.get('chained', None)
        self.extensible = json_data.get('extensible', None)
        if self.chained:
            assert self.chained == 'in' or self.chained == 'out'
            assert 'chain roots' in json_data
            self.chain_roots = []
        if self.extensible:
            assert self.extensible == 'in' or self.extensible == 'out'
        # Chained structs inherit from wgpu::ChainedStruct, which has
        # nextInChain, so setting both extensible and chained would result in
        # two nextInChain members.
        assert not (self.extensible and self.chained)
        self.extensions = []

    def update_metadata(self):
        Record.update_metadata(self)

        if self.may_have_dawn_object:
            self.is_wire_transparent = False
            return

        assert not (self.chained or self.extensible)

        def get_is_wire_transparent(member):
            return member.type.is_wire_transparent and member.annotation == 'value'

        self.is_wire_transparent = all(
            get_is_wire_transparent(m) for m in self.members)

    @property
    def output(self):
        # self.out is a temporary way to express that this is an output structure
        # without also making it extensible. See
        # https://dawn-review.googlesource.com/c/dawn/+/212174/comment/2271690b_1fd82ea9/
        return self.chained == "out" or self.extensible == "out" or self.out

    @property
    def has_free_members_function(self):
        if not self.output:
            return False
        for m in self.members:
            if m.annotation != 'value' \
                or m.type.name.canonical_case() == 'string view':
                return True
        return False

    @property
    def any_member_requires_struct_defaulting(self):
        return any(member.requires_struct_defaulting
                   for member in self.members)


class CallbackInfoType(StructureType):
    def __init__(self, is_enabled, name, json_data):
        StructureType.__init__(self, is_enabled, name, json_data)
        self.extensible = 'in'


class ConstantDefinition():
    def __init__(self, is_enabled, name, json_data):
        self.type = None
        self.value = json_data['value']
        self.cpp_value = json_data.get('cpp_value', None)
        self.json_data = json_data
        self.name = Name(name)


class FunctionDeclaration():
    def __init__(self, is_enabled, name, json_data, no_cpp=False):
        self.returns = None
        self.arguments = []
        self.json_data = json_data
        self.name = Name(name)
        self.no_cpp = no_cpp


class Command(Record):
    def __init__(self, name, members=None):
        Record.__init__(self, name)
        self.members = members or []
        self.derived_object = None
        self.derived_method = None


def linked_record_members(json_data, types):
    members = []
    members_by_name = {}
    for m in json_data:
        member = RecordMember(Name(m['name']),
                              types[m['type']],
                              m.get('annotation', 'value'),
                              m,
                              optional=m.get('optional', False),
                              array_element_optional=m.get(
                                  'array_element_optional', False),
                              is_return_value=m.get('is_return_value', False),
                              default_value=m.get('default', None),
                              skip_serialize=m.get('skip_serialize', False))
        handle_type = m.get('handle_type')
        if handle_type:
            member.set_handle_type(types[handle_type])
        id_type = m.get('id_type')
        if id_type:
            member.set_id_type(types[id_type])
        members.append(member)
        members_by_name[member.name.canonical_case()] = member

    for (member, m) in zip(members, json_data):
        if member.annotation != 'value':
            if not 'length' in m:
                if member.type.category != 'object':
                    member.length = "constant"
                    member.constant_length = 1
                else:
                    assert False
            elif isinstance(m['length'], int):
                assert m['length'] > 0
                member.length = "constant"
                member.constant_length = m['length']
            else:
                member.length = members_by_name[m['length']]

    return members


############################################################
# PARSE
############################################################


def link_object(obj, types):
    # Disable method's autolock if obj's "no autolock" = True
    obj_scoped_autolock_enabled = not obj.json_data.get('no autolock', False)

    def make_method(json_data):
        autolock_enabled = obj_scoped_autolock_enabled and not json_data.get(
            'no autolock', False)
        # link_function sets 'returns' and 'arguments'
        method = Method(Name(json_data['name']), None, None, autolock_enabled,
                        json_data)
        link_function(method, types)
        return method

    obj.methods = [make_method(m) for m in obj.json_data.get('methods', [])]
    obj.methods.sort(key=lambda method: method.name)

def link_structure(struct, types):
    struct.members = linked_record_members(struct.json_data['members'], types)
    for root in struct.json_data.get('chain roots', []):
        struct.chain_roots.append(types[root])
        types[root].extensions.append(struct)
    struct.chain_roots = [types[root] for root in struct.json_data.get('chain roots', [])]
    assert all((root.category == 'structure' for root in struct.chain_roots))


def link_function_pointer(function_pointer, types):
    link_function(function_pointer, types)


def link_typedef(typedef, types):
    typedef.type = types[typedef.json_data['type']]


def link_constant(constant, types):
    constant.type = types[constant.json_data['type']]
    assert constant.type.name.native


def link_function(function, types):
    # "returns" may be either a bare type name or a AnnotatedTypedMember-like.
    returns = function.json_data.get('returns')
    assert returns != 'void', '"returns": "void" should be omitted instead'
    if returns:
        if type(returns) == str:
            returns = {'type': returns}
        function.returns = AnnotatedTypedMember(
            types[returns['type']], returns.get('annotation', 'value'),
            returns.get('optional', False), returns)

    function.arguments = linked_record_members(
        function.json_data.get('args', []), types)

# Sort structures so that if struct A has struct B as a member, then B is
# listed before A.
#
# This is a form of topological sort where we try to keep the order reasonably
# similar to the original order (though the sort isn't technically stable).
#
# It works by computing for each struct type what is the depth of its DAG of
# dependents, then re-sorting based on that depth using Python's stable sort.
# This makes a toposort because if A depends on B then its depth will be bigger
# than B's. It is also nice because all nodes with the same depth are kept in
# the input order.
def topo_sort_structure(structs):
    for struct in structs:
        struct.visited = False
        struct.subdag_depth = 0
        # String view is special cased to -1 because we purposely fully declare
        # it before all other structs.
        if struct.name.get() == "string view":
            struct.subdag_depth = -1
            struct.visited = True

    def compute_depth(struct):
        if struct.visited:
            return struct.subdag_depth

        max_dependent_depth = 0
        for member in struct.members:
            if member.type.category == 'structure':
                max_dependent_depth = max(max_dependent_depth,
                                          compute_depth(member.type) + 1)
        for extension in struct.extensions:
            max_dependent_depth = max(max_dependent_depth,
                                      compute_depth(extension) + 1)

        struct.subdag_depth = max_dependent_depth
        struct.visited = True
        return struct.subdag_depth

    for struct in structs:
        compute_depth(struct)

    result = sorted(structs, key=lambda struct: struct.subdag_depth)

    for struct in structs:
        del struct.visited
        del struct.subdag_depth

    return result


def parse_json(json, enabled_tags, disabled_tags=None):
    is_enabled = lambda json_data: item_is_enabled(
        enabled_tags, json_data) and not item_is_disabled(
            disabled_tags, json_data)
    category_to_parser = {
        'bitmask': BitmaskType,
        'callback function': CallbackFunctionType,
        'callback info': CallbackInfoType,
        'enum': EnumType,
        'native': NativeType,
        'function pointer': FunctionPointerType,
        'object': ObjectType,
        'structure': StructureType,
        'typedef': TypedefType,
        'constant': ConstantDefinition,
        'function': FunctionDeclaration
    }

    types = {}

    by_category = {}
    for name in category_to_parser.keys():
        by_category[name] = []

    for (name, json_data) in json.items():
        if name[0] == '_' or not is_enabled(json_data):
            continue
        category = json_data['category']
        parsed = category_to_parser[category](is_enabled, name, json_data)
        by_category[category].append(parsed)
        types[name] = parsed

    for obj in by_category['object']:
        link_object(obj, types)

    for struct in by_category['structure']:
        link_structure(struct, types)

    for callback_info in by_category['callback info']:
        link_structure(callback_info, types)

    for callback_function in by_category['callback function']:
        link_function_pointer(callback_function, types)

    for function_pointer in by_category['function pointer']:
        link_function_pointer(function_pointer, types)

    for typedef in by_category['typedef']:
        link_typedef(typedef, types)

    for constant in by_category['constant']:
        link_constant(constant, types)

    for function in by_category['function']:
        link_function(function, types)

    # Sort everything by name
    for category in by_category.keys():
        by_category[category] = sorted(by_category[category],
                                       key=lambda typ: typ.name)
    # Then sort GetProcAddress last
    by_category['function'].sort(
        key=lambda f: f.name.get() == 'get proc address')

    by_category['structure'] = topo_sort_structure(by_category['structure'])

    for struct in by_category['structure']:
        struct.update_metadata()

    api_params = {
        'types': types,
        'by_category': by_category,
        'enabled_tags': enabled_tags,
        'disabled_tags': disabled_tags,
    }
    return {
        'metadata': Metadata(json['_metadata']),
        'types': types,
        'by_category': by_category,
        'enabled_tags': enabled_tags,
        'disabled_tags': disabled_tags,
        'c_methods': lambda typ: c_methods(api_params, typ),
        'c_methods_sorted_by_parent':
        get_c_methods_sorted_by_parent(api_params),
        'c_methods_sorted_by_name': get_c_methods_sorted_by_name(api_params),
    }


############################################################
# WIRE STUFF
############################################################


# Create wire commands from api methods
def compute_wire_params(api_params, wire_json):
    wire_params = api_params.copy()
    types = wire_params['types']

    commands = []
    return_commands = []
    special_commands = []

    wire_json['special items']['client_handwritten_commands'] += wire_json[
        'special items']['client_side_commands']

    # Generate commands from object methods
    for api_object in wire_params['by_category']['object']:
        # Reference counting functions are generated separately, so label them as "handwritten".
        wire_json['special items']['client_handwritten_commands'] += [
            api_object.name.CamelCase() + 'AddRef',
            api_object.name.CamelCase() + 'Release'
        ]

        for method in api_object.methods:
            command_name = concat_names(api_object.name, method.name)
            command_suffix = Name(command_name).CamelCase()

            # Only object return values or void are supported.
            # Other methods must be handwritten.
            is_object = method.returns and method.returns.type.category == 'object'
            is_void = method.returns == None
            if not (is_object or is_void):
                assert command_suffix in (
                    wire_json['special items']['client_handwritten_commands']
                ), command_suffix
                continue

            if command_suffix in (
                    wire_json['special items']['client_side_commands']):
                continue

            # Create object method commands by prepending "self"
            members = [
                RecordMember(Name('self'), types[api_object.dict_name],
                             'value', {})
            ]
            members += method.arguments

            # Client->Server commands that return an object return the
            # result object handle
            if method.returns and method.returns.type.category == 'object':
                result = RecordMember(Name('result'),
                                      types['ObjectHandle'],
                                      'value', {},
                                      is_return_value=True)
                result.set_handle_type(method.returns.type)
                members.append(result)

            command = Command(command_name, members)
            command.derived_object = api_object
            command.derived_method = method
            commands.append(command)

    # Generate commands from structure methods. Notes that currently this is only FreeMembers.
    for api_struct in wire_params['by_category']['structure']:
        wire_json['special items']['client_handwritten_commands'] += [
            api_struct.name.CamelCase() + 'FreeMembers'
        ]

    for (name, json_data) in wire_json['commands'].items():
        commands.append(Command(name, linked_record_members(json_data, types)))

    for (name, json_data) in wire_json['return commands'].items():
        return_commands.append(
            Command(name, linked_record_members(json_data, types)))

    for (name, json_data) in wire_json['special commands'].items():
        special_commands.append(
            Command(name, linked_record_members(json_data, types)))

    wire_params['cmd_records'] = {
        'command': commands,
        'return command': return_commands,
        'special command': special_commands
    }

    for commands in wire_params['cmd_records'].values():
        for command in commands:
            command.update_metadata()
        commands.sort(key=lambda c: c.name.canonical_case())

    wire_params.update(wire_json.get('special items', {}))

    return wire_params


############################################################
# KOTLIN STUFF
############################################################


def compute_kotlin_params(loaded_json, kotlin_json, webgpu_json_data=None):
    params_kotlin = parse_json(loaded_json, enabled_tags=['art'])
    params_kotlin['kotlin_package'] = kotlin_json['kotlin_package']
    params_kotlin['jni_primitives'] = kotlin_json['jni_primitives']
    params_kotlin['jni_signatures'] = kotlin_json['jni_signatures']
    kt_file_path = params_kotlin['kotlin_package'].replace('.', '/')
    customize_api = kotlin_json["customize_api"]
    customize_objects = customize_api["objects"]
    customize_structures = customize_api["structures"]
    customize_enums = customize_api["enums"]

    def kotlin_record_members(members):
        # Members are sorted in the following order.
        # 1. members with no default value (except callbacks).
        # 2. members with default values.
        # 3. callbacks.
        for member in sorted(kotlin_record_members_unsorted(members),
                             key=lambda arg: kotlin_default(arg) is not None):
            yield member

        # Callbacks always go at the end.
        for member in members:
            if member.type.category == 'callback info':
                for callback_info_member in member.type.members:
                    if callback_info_member.type.category == 'callback function':
                        # We give the callback function a new name based on the callback info.
                        name = member.name.get().removesuffix(' info')
                        function_member = deepcopy(callback_info_member)
                        function_member.name = Name(name)
                        yield function_member
                    continue

    def kotlin_record_members_unsorted(members):
        for member in members:
            # length parameters are omitted because Kotlin containers have 'length'.
            if member in [m.length for m in members]:
                continue

            # userdata parameter omitted because Kotlin clients can achieve the same with closures.
            if member.name.get() == 'userdata':
                continue

            # Dawn sometimes uses 'annotation = *' for output parameters, for example to return
            # arrays. We convert the return type and strip out the parameters.
            if member.annotation == '*' and member.length == 'constant':
                continue

            # We replace the callback info with an executor here.
            if member.type.category == 'callback info':
                name = member.name.get().removesuffix(' info')
                yield RecordMember(
                    Name(name + ' executor'),
                    Type('java.util.concurrent.Executor',
                         {'category': 'kotlin type'}), None, {})
                continue

            yield member


    # Calculate if we should, and can, provide a Kotlin default value for a given argument.
    # This will affect its order in the method parameter and structure field lists.
    def kotlin_default(arg):
        # Optional and non-optional container parameters are defaulted to empty containers to match
        # the behavior of the JavaScript API.
        if arg.length and arg.length != 'constant' and arg.type.name.get(
        ) != 'void':
            if arg.type.category in [
                    'callback function', 'callback info', 'function pointer',
                    'object', 'structure'
            ]:
                return 'arrayOf()'
            return 'intArrayOf()'

        # All other optional types default to 'null'.
        if arg.optional:
            return 'null'

        # Non-optional structures are defaulted to a defaulted structure if we can construct one.
        # This is to match the behavior of the JavaScript API which lets clients pass undefined
        # structure values even for non-optional fields.
        if arg.type.category in [
                'structure', 'callback info'
        ] and arg.type.name.get() != 'string view' and all(
                kotlin_default(member) is not None
                for member in arg.type.members):
            constructor_args = []
            # default_value = zero is a special defaulting variation from C we have to emulate.
            if arg.default_value == 'zero':
                constructor_args = [
                    f"{member.name.camelCase()} = {member.type.name.CamelCase()}.{as_ktName(value.name.CamelCase())}"
                    for member in kotlin_record_members(arg.type.members)
                    if member.type.category in ['bitmask', 'enum']
                    for value in member.type.values if value.value == 0
                ]
            return f"{arg.type.name.CamelCase()}({', '.join(constructor_args)})"

        # For bitmasks/enums we insert the full type of the default. No default value doesn't mean
        # no default in the bindings, because it should match the bitmask/enum labeled 'undefined'.
        if arg.type.category in ['bitmask', 'enum']:
            for value in arg.type.values:
                if value.name.name == (arg.default_value or 'undefined'):
                    return f"{arg.type.name.CamelCase()}.{as_ktName(value.name.CamelCase())}"
            return arg.default_value

        # Everything remaining requires a default value in the dawn.json.
        if arg.default_value in [None, 'nullptr']:
            return None

        if arg.type.category == 'native':
            # Is this a Dawn named constant that can be matched with the global definition?
            constant = find_by_name(by_category["constant"], arg.default_value)
            if constant:
                return 'Constants.' + as_ktName(constant.name.SNAKE_CASE())

            # Convert double/floats to the Kotlin format.
            if arg.type.name.get() in ['double', 'float']:
                return "%.1ff" % float(arg.default_value.rstrip('fF'))

            # Java doesn't have unsigned 32 bit / 64 bit variables so the cleanest workaround is
            # to insert the bitwise equivalent of a signed number.
            if arg.type.name.get() in ['int', 'int32_t', 'uint32_t'
                                       ] and arg.default_value == '0xFFFFFFFF':
                return '-0x7FFFFFFF'
            if arg.type.name.get() in [
                    'int64_t', 'uint64_t', 'size_t'
            ] and arg.default_value == '0xFFFFFFFFFFFFFFFF':
                return '-0x7FFFFFFFFFFFFFFF'

            # In all remaining cases the default as specified in dawn.json will work verbatim in
            # Kotlin.
            return arg.default_value

        unreachable_code(
            f"no logic to default '{arg.type.name.get()}' in category '{arg.type.category}'"
        )
        return None

    def kotlin_return(method):
        for argument in method.arguments:
            if argument.annotation == '*':
                # TODO(b/352048981): Use handwritten methods for container returns to avoid the need
                # for special casing logic.
                if method.returns and method.returns.type.name.get(
                ) == 'size_t':
                    # Convert the output parameter to a Kotlin return container.
                    container_type = deepcopy(argument)
                    container_type.length = 'size_t'
                    return container_type
                if ((method.returns == None
                     or method.returns.type.name.get() == 'status')
                        and argument.type.category == 'structure'):
                    return argument

        # If the function should return an omitted structure, we return nothing instead.
        if method.returns and method.returns.type.category == 'structure' and not include_structure(
                method.returns.type):
            return None

        # Return values are not treated as optional to keep the Kotlin API simple.
        # Methods are expected to return an object if declared. If they can't, dawn may raise an
        # error (converted to a Kotlin exception); otherwise JNI will throw NullPointerException.
        # In either case the optional type is redundant.
        return AnnotatedTypedMember(
            method.returns.type, method.returns.annotation, False,
            method.json_data) if method.returns else None

    def include_method(obj, method):
        if method.returns and method.returns.type.category == 'function pointer':
            # Kotlin doesn't support returning functions.
            return False

        if obj is None:
            return True

        # Is the method marked omitted in dawn_kotlin.json?
        return customize_objects.get(obj.name.get(),
                                     {}).get("methods", {}).get(
                                         method.name.get(),
                                         {}).get('omitted') is not True

    def include_structure(structure):
        if structure.name.canonical_case() == "string view":
            return False
        # Is the structure marked omitted in dawn_kotlin.json?
        return customize_structures.get(structure.name.get(),
                                        {}).get('omitted') is not True

    def include_enum(enum):
        return customize_enums.get(enum.name.get(),
                                   {}).get('omitted') is not True

    def jni_name(type):
        if type.category == 'kotlin type':
            # Standard library Kotlin class (with namespace) just needs converting.
            return type.name.get().replace('.', '/')
        return kt_file_path + '/' + type.name.CamelCase()

    # A structure may need to know which other structures listed it as a chain root, e.g.
    # to know whether to mark the generated class 'open'.
    chain_children = defaultdict(list)
    by_category = params_kotlin['by_category']
    for structure in by_category['structure']:
        for chain_root in structure.chain_roots:
            chain_children[chain_root.name.get()].append(structure)

    kdocs_params = {
        'language': 'kotlin',
        'kdocs_blocklist': kotlin_json['kdocs_blocklist'],
        'kdocs_replacements': kotlin_json['kdocs_replacements'],
    }
    params_kotlin['kdocs'] = build_doc_map(by_category=by_category,
                                           json_data=webgpu_json_data,
                                           params=kdocs_params)
    params_kotlin['chain_children'] = chain_children
    params_kotlin['kotlin_default'] = kotlin_default
    params_kotlin['kotlin_return'] = kotlin_return
    params_kotlin['include_method'] = include_method
    params_kotlin['include_structure'] = include_structure
    params_kotlin['include_enum'] = include_enum
    params_kotlin['kotlin_record_members'] = kotlin_record_members
    params_kotlin['jni_name'] = jni_name
    params_kotlin['has_kotlin_classes'] = by_category['callback function'] + [
        enum for enum in by_category['enum'] if include_enum(enum)
    ] + by_category['function pointer'] + by_category['object'] + [
        structure for structure in by_category['structure']
        if include_structure(structure)
    ]

    return params_kotlin


#############################################################
# Generator
#############################################################


def as_varName(*names):
    return names[0].camelCase() + ''.join(
        [name.CamelCase() for name in names[1:]])


def as_cType(c_prefix, name):
    # Special case for 'bool' because it has a typedef for compatibility.
    if name.native and name.get() != 'bool':
        return name.concatcase()
    else:
        return c_prefix + name.CamelCase()

def as_cppType(name):
    # Special case for 'bool' because it has a typedef for compatibility.
    if name.native and name.get() != 'bool':
        return name.concatcase()
    else:
        return name.CamelCase()


def as_ktName(name):
    return '_' + name if '0' <= name[0] <= '9' else name


def as_jsEnumValue(value):
    if 'jsrepr' in value.json_data: return value.json_data['jsrepr']
    return "'" + value.name.js_enum_case() + "'"


def has_wasmType(return_type, args):
    return all(map(lambda x: len(as_wasmType(x)) == 1, [return_type] + args))


# Returns a single character wasm type (v/p/i/j/f/d) if valid, a "(longer string)" if not
def as_wasmType(x):
    if x is None:
        return 'v'  # void return type

    if isinstance(x, AnnotatedTypedMember):
        if x.annotation == 'value':
            x = x.type
        elif '*' in x.annotation:
            return 'p'
        else:
            x = x.type

    if isinstance(x, Type):
        if x.category == 'enum':
            return 'i'
        elif x.category == 'bitmask':
            return 'j'
        elif x.category in ['object', 'function pointer']:
            return 'p'
        elif x.category == 'native':
            return x.json_data.get('wasm type', f'({x.name.name})')
        elif x.category in ['structure', 'callback info']:
            return f'({x.name.name})'  # Invalid
        else:
            assert False, 'Type -> ' + x.category


def convert_cType_to_cppType(typ, annotation, arg, indent=0):
    if typ.category == 'native':
        return arg
    if annotation == 'value':
        if typ.category == 'object':
            return '{}::Acquire({})'.format(as_cppType(typ.name), arg)
        elif typ.category == 'structure':
            converted_members = [
                convert_cType_to_cppType(
                    member.type, member.annotation,
                    '{}.{}'.format(arg, as_varName(member.name)), indent + 1)
                for member in typ.members
            ]

            converted_members = [(' ' * 4) + m for m in converted_members]
            converted_members = ',\n'.join(converted_members)

            return as_cppType(typ.name) + ' {\n' + converted_members + '\n}'
        elif typ.category == 'function pointer':
            return 'reinterpret_cast<{}>({})'.format(as_cppType(typ.name), arg)
        else:
            return 'static_cast<{}>({})'.format(as_cppType(typ.name), arg)
    else:
        return 'reinterpret_cast<{} {}>({})'.format(as_cppType(typ.name),
                                                    annotation, arg)


def decorate(typ, arg, *, with_nullability):
    s = typ
    if arg.annotation != 'value' or arg.type.is_nullable_pointer:
        if arg.annotation == '*':
            s = typ + ' *'
        elif arg.annotation == 'const*':
            s = typ + ' const *'
        elif arg.annotation == 'const*const*':
            s = 'const ' + typ + '* const *'
        if with_nullability:
            nullability = 'WGPU_NULLABLE ' if arg.optional else ''
            s = nullability + s
    return s


def annotate(typ, arg, *, make_const_member=False, with_nullability=False):
    result = decorate(typ, arg, with_nullability=with_nullability)
    if isinstance(arg, RecordMember):
        if make_const_member:
            result += ' const'
        result += ' ' + as_varName(arg.name)
    return result


def item_is_enabled(enabled_tags, json_data):
    tags = validate_and_get_tags(json_data)
    if tags is None: return True
    return any(tag in enabled_tags for tag in tags)


def item_is_disabled(disabled_tags, json_data):
    if disabled_tags is None: return False
    tags = validate_and_get_tags(json_data)
    if tags is None: return False

    return any(tag in disabled_tags for tag in tags)


def as_cppEnum(value_name):
    assert not value_name.native
    if value_name.concatcase()[0].isdigit():
        return "e" + value_name.CamelCase()
    return value_name.CamelCase()


def as_MethodSuffix(type_name, method_name):
    assert not type_name.native and not method_name.native
    return type_name.CamelCase() + method_name.CamelCase()


def as_CppMethodSuffix(type_name, method_name):
    assert not type_name.native and not method_name.native
    original_method_name_str = method_name.CamelCase()
    if method_name.chunks[-1] == 'f':
        return type_name.CamelCase() + original_method_name_str[:-1]
    return type_name.CamelCase() + original_method_name_str


def as_frontendType(metadata, typ):
    if typ.category == 'object':
        return typ.name.CamelCase() + 'Base*'
    elif typ.category in ['bitmask', 'enum'] or typ.name.get() == 'bool':
        return metadata.namespace + '::' + typ.name.CamelCase()
    elif typ.category == 'structure':
        return as_cppType(typ.name)
    else:
        return as_cType(metadata.c_prefix, typ.name)


def as_wireType(metadata, typ):
    if typ.category == 'object':
        return typ.name.CamelCase() + '*'
    elif typ.category in ['bitmask', 'enum', 'structure']:
        return metadata.c_prefix + typ.name.CamelCase()
    else:
        return as_cppType(typ.name)


def c_methods(params, typ):
    if typ.category == 'object':
        return typ.methods + [
            Method(Name('add ref'), None, [], False, {}),
            Method(Name('release'), None, [], False, {}),
        ]
    elif typ.category == 'structure':
        if typ.has_free_members_function:
            return [Method(Name('free members'), None, [], False, {})]
        return []
    else:
        assert False, "c_methods only valid on objects and structure"


def get_c_methods_sorted_by_parent(api_params):
    return sorted([(typ, c_methods(api_params, typ))
                   for typ in (api_params['by_category']['object'] +
                               api_params['by_category']['structure'])
                   if len(c_methods(api_params, typ)) > 0])


def get_c_methods_sorted_by_name(api_params):
    unsorted = [(as_MethodSuffix(typ.name, method.name), typ, method) \
    for (typ, methods) in get_c_methods_sorted_by_parent(api_params) \
    for method in methods]
    return [(typ, method) for (_, typ, method) in sorted(unsorted)]


def find_by_name(members, name):
    for member in members:
        if member.name.get() == name:
            return member
    return None


def has_callback_arguments(method):
    return any(arg.type.category == 'function pointer' for arg in method.arguments)


# TODO: crbug.com/dawn/2509 - Remove this helper when once we deprecate older APIs.
def has_callback_info(method):
    return method.returns.type.name.get() == 'future' and any(
        arg.name.get() == 'callback info'
        and arg.type.category != 'callback info' for arg in method.arguments)


def has_callbackInfoStruct(method):
    return any(arg.type.category == 'callback info'
               for arg in method.arguments)


def is_wire_serializable(type):
    # Function pointers, callback functions, and "void *" types (i.e. userdata) cannot
    # be serialized.
    return (type.category != 'function pointer'
            and type.category != 'callback info'
            and type.category != 'callback function'
            and type.name.get() != 'void *')


def is_enum_value_proxy(value):
    return ('deprecated' in value.json_data.get('tags', [])
            and value.json_data.get('enum_value_conflict', False))


def unreachable_code(msg="unreachable_code"):
    assert False, msg


def make_base_render_params(metadata):
    c_prefix = metadata.c_prefix

    def as_cTypeEnumSpecialCase(typ):
        return as_cType(c_prefix, typ.name)

    def as_cEnum(type_name, value_name):
        assert not type_name.native and not value_name.native
        return c_prefix + type_name.CamelCase() + '_' + value_name.CamelCase()

    def as_cMethodNamespaced(type_name, method_name, namespace=None):
        c_method = c_prefix.lower()
        if namespace is not None:
            c_method += namespace.CamelCase()
        if type_name is not None:
            assert not type_name.native
            c_method += type_name.CamelCase()
        assert not method_name.native
        c_method += method_name.CamelCase()
        return c_method

    def as_cMethod(type_name, method_name):
        return as_cMethodNamespaced(type_name, method_name)

    def as_cProc(type_name, method_name):
        c_proc = c_prefix + 'Proc'
        if type_name != None:
            assert not type_name.native
            c_proc += type_name.CamelCase()
        assert not method_name.native
        c_proc += method_name.CamelCase()
        return c_proc

    return {
            'Name': lambda name: Name(name),
            'as_nullability_annotated_cType': \
                lambda arg: 'void' if arg is None else annotate(as_cTypeEnumSpecialCase(arg.type), arg, with_nullability=True),
            'as_annotated_cType': \
                lambda arg: 'void' if arg is None else annotate(as_cTypeEnumSpecialCase(arg.type), arg),
            'as_annotated_cppType': \
                lambda arg, make_const_member=False: 'void' if arg is None else annotate(as_cppType(arg.type.name), arg, make_const_member=make_const_member),
            'as_cEnum': as_cEnum,
            'as_cppEnum': as_cppEnum,
            'as_cMethod': as_cMethod,
            'as_cMethodNamespaced': as_cMethodNamespaced,
            'as_MethodSuffix': as_MethodSuffix,
            'as_CppMethodSuffix': as_CppMethodSuffix,
            'as_cProc': as_cProc,
            'as_cType': lambda name: as_cType(c_prefix, name),
            'as_cppType': as_cppType,
            'as_jsEnumValue': as_jsEnumValue,
            'has_wasmType': has_wasmType,
            'as_wasmType': as_wasmType,
            'convert_cType_to_cppType': convert_cType_to_cppType,
            'as_varName': as_varName,
            'decorate': lambda typ, arg: decorate(typ, arg, with_nullability=False),
            'as_ktName': as_ktName,
            'has_callbackInfoStruct': has_callbackInfoStruct,
            'find_by_name': find_by_name,
            'print': print,
            'unreachable_code': unreachable_code,
            'is_enum_value_proxy': is_enum_value_proxy,
        }


class MultiGeneratorFromDawnJSON(Generator):
    def get_description(self):
        return 'Generates code for various target from Dawn.json.'

    def add_commandline_arguments(self, parser):
        allowed_targets = [
            'dawn_headers', 'cpp_headers', 'cpp', 'proc', 'mock_api', 'wire',
            'native_utils', 'kotlin'
        ]

        parser.add_argument('--dawn-json',
                            required=True,
                            type=str,
                            help='The DAWN JSON definition to use.')
        parser.add_argument('--wire-json',
                            default=None,
                            type=str,
                            help='The DAWN WIRE JSON definition to use.')
        parser.add_argument('--kotlin-json',
                            default=None,
                            type=str,
                            help='The KOTLIN JSON definition to use.')
        parser.add_argument('--webgpu-json',
                            default=None,
                            type=str,
                            help='The WebGPU API documentation to use.')
        parser.add_argument(
            '--targets',
            required=True,
            type=str,
            help=
            'Comma-separated subset of targets to output. Available targets: '
            + ', '.join(allowed_targets))

    def get_outputs(self, args):
        with open(args.dawn_json) as f:
            loaded_json = json.loads(f.read())

        targets = args.targets.split(',')

        wire_json = None
        if args.wire_json:
            with open(args.wire_json) as f:
                wire_json = json.loads(f.read())

        kotlin_json = None
        if args.kotlin_json:
            with open(args.kotlin_json) as f:
                kotlin_json = json.loads(f.read())

        webgpu_json_data = None
        if args.webgpu_json:
            webgpu_json_data = load_json_data(args.webgpu_json)

        renders = []
        imported_templates = []

        params_dawn = parse_json(
            loaded_json,
            enabled_tags=['compat', 'dawn', 'native', 'deprecated'])

        params_all = parse_json(loaded_json,
                                enabled_tags=[
                                    'compat', 'dawn', 'emscripten', 'native',
                                    'deprecated'
                                ])

        metadata = params_dawn['metadata']
        RENDER_PARAMS_BASE = make_base_render_params(metadata)

        api = metadata.api.lower()
        prefix = metadata.proc_table_prefix.lower()
        if 'headers' in targets:
            imported_templates.append('BSD_LICENSE')
            renders.append(
                FileRender('api.h', 'include/dawn/' + api + '.h',
                           [RENDER_PARAMS_BASE, params_all]))
            renders.append(
                FileRender('dawn/wire/client/api.h',
                           'include/dawn/wire/client/' + api + '.h',
                           [RENDER_PARAMS_BASE, params_dawn]))
            renders.append(
                FileRender('dawn_proc_table.h',
                           'include/dawn/' + prefix + '_proc_table.h',
                           [RENDER_PARAMS_BASE, params_dawn]))

        if 'cpp_headers' in targets:
            imported_templates += [
                "dawn/cpp_macros.tmpl",
            ]

            renders.append(
                FileRender('api_cpp.h', 'include/dawn/' + api + '_cpp.h', [
                    RENDER_PARAMS_BASE, params_all, {
                        'c_header': api + '/' + api + '.h',
                        'c_namespace': None,
                    }
                ]))

            renders.append(
                FileRender(
                    'api_cpp.h', 'include/dawn/wire/client/' + api + '_cpp.h',
                    [
                        RENDER_PARAMS_BASE, params_dawn, {
                            'c_header': 'dawn/wire/client/' + api + '.h',
                            'c_namespace': Name('dawn wire client'),
                        }
                    ]))

            renders.append(
                FileRender('api_cpp_print.h',
                           'include/dawn/' + api + '_cpp_print.h', [
                               RENDER_PARAMS_BASE, params_dawn, {
                                   'cpp_header': api + '/' + api + '_cpp.h',
                                   'c_namespace': None,
                               }
                           ]))

            renders.append(
                FileRender(
                    'api_cpp_print.h',
                    'include/dawn/wire/client/' + api + '_cpp_print.h', [
                        RENDER_PARAMS_BASE, params_dawn, {
                            'cpp_header': 'dawn/wire/client/' + api + '_cpp.h',
                            'c_namespace': Name('dawn wire client'),
                        }
                    ]))

            renders.append(
                FileRender('api_cpp_chained_struct.h',
                           'include/webgpu/' + api + '_cpp_chained_struct.h',
                           [RENDER_PARAMS_BASE, params_dawn]))

        if 'proc' in targets:
            renders.append(
                FileRender('dawn_proc.cpp', 'src/dawn/' + prefix + '_proc.cpp',
                           [RENDER_PARAMS_BASE, params_dawn]))
            renders.append(
                FileRender('dawn_thread_dispatch_proc.cpp',
                           'src/dawn/' + prefix + '_thread_dispatch_proc.cpp',
                           [RENDER_PARAMS_BASE, params_dawn]))

        if 'webgpu_dawn_native_proc' in targets:
            renders.append(
                FileRender('dawn/native/api_dawn_native_proc.cpp',
                           'src/dawn/native/webgpu_dawn_native_proc.cpp',
                           [RENDER_PARAMS_BASE, params_dawn]))

        if 'webgpu_headers' in targets:
            params_upstream = parse_json(loaded_json,
                                         enabled_tags=['native'],
                                         disabled_tags=['dawn'])
            imported_templates.append('BSD_LICENSE')
            renders.append(
                FileRender('api.h', 'webgpu-headers/' + api + '.h',
                           [RENDER_PARAMS_BASE, params_upstream]))

        if 'emdawnwebgpu_headers' in targets:
            imported_templates += [
                "dawn/cpp_macros.tmpl",
            ]

            assert api == 'webgpu'
            params_emscripten = parse_json(
                loaded_json, enabled_tags=['compat', 'emscripten'])
            # system/include/webgpu
            imported_templates.append('BSD_LICENSE')
            renders.append(
                FileRender('api.h', 'src/emdawnwebgpu/include/webgpu/webgpu.h',
                           [RENDER_PARAMS_BASE, params_emscripten]))
            renders.append(
                FileRender('api_cpp.h',
                           'src/emdawnwebgpu/include/webgpu/webgpu_cpp.h', [
                               RENDER_PARAMS_BASE, params_emscripten, {
                                   'c_header': api + '/' + api + '.h',
                                   'c_namespace': None,
                               }
                           ]))
            renders.append(
                FileRender(
                    'api_cpp_chained_struct.h',
                    'src/emdawnwebgpu/include/webgpu/webgpu_cpp_chained_struct.h',
                    [RENDER_PARAMS_BASE, params_emscripten]))
            renders.append(
                FileRender('api_cpp_print.h',
                           'src/emdawnwebgpu/include/dawn/webgpu_cpp_print.h',
                           [
                               RENDER_PARAMS_BASE, params_emscripten, {
                                   'cpp_header': api + '/' + api + '_cpp.h',
                                   'c_namespace': None,
                               }
                           ]))

        if 'emdawnwebgpu_js' in targets:
            assert api == 'webgpu'
            params_emscripten = parse_json(
                loaded_json, enabled_tags=['compat', 'emscripten'])
            renders.append(
                FileRender('emdawnwebgpu/struct_info_webgpu.json',
                           'src/emdawnwebgpu/struct_info_webgpu.json',
                           [RENDER_PARAMS_BASE, params_emscripten]))
            renders.append(
                FileRender('emdawnwebgpu/library_webgpu_enum_tables.js',
                           'src/emdawnwebgpu/library_webgpu_enum_tables.js',
                           [RENDER_PARAMS_BASE, params_emscripten]))
            renders.append(
                FileRender(
                    'emdawnwebgpu/library_webgpu_generated_sig_info.js',
                    'src/emdawnwebgpu/library_webgpu_generated_sig_info.js',
                    [RENDER_PARAMS_BASE, params_emscripten]))

        if 'emdawnwebgpu_link_test_cpp' in targets:
            assert api == 'webgpu'
            params_emscripten = parse_json(
                loaded_json, enabled_tags=['compat', 'emscripten'])
            renders.append(
                FileRender('emdawnwebgpu/LinkTest.cpp',
                           'src/emdawnwebgpu/LinkTest.cpp',
                           [RENDER_PARAMS_BASE, params_emscripten]))

        if 'mock_api' in targets:
            mock_params = [
                RENDER_PARAMS_BASE, params_dawn, {
                    'has_callback_arguments': has_callback_arguments,
                    "has_callback_info": has_callback_info
                }
            ]
            renders.append(
                FileRender('mock_api.h', 'src/dawn/mock_' + api + '.h',
                           mock_params))
            renders.append(
                FileRender('mock_api.cpp', 'src/dawn/mock_' + api + '.cpp',
                           mock_params))

        if 'native_utils' in targets:
            frontend_params = [
                RENDER_PARAMS_BASE,
                params_dawn,
                {
                    # TODO: as_frontendType and co. take a Type, not a Name :(
                    'as_frontendType': lambda typ: as_frontendType(metadata, typ),
                    'as_annotated_frontendType': \
                        lambda arg: annotate(as_frontendType(metadata, arg.type), arg),
                }
            ]

            imported_templates += [
                "dawn/cpp_macros.tmpl",
            ]

            impl_dir = metadata.impl_dir + '/' if metadata.impl_dir else ''
            native_dir = impl_dir + Name(metadata.native_namespace).Dirs()
            namespace = metadata.namespace
            renders.append(
                FileRender('dawn/native/ValidationUtils.h',
                           'src/' + native_dir + '/ValidationUtils_autogen.h',
                           frontend_params))
            renders.append(
                FileRender('dawn/native/ValidationUtils.cpp',
                           'src/' + native_dir + '/ValidationUtils_autogen.cpp',
                           frontend_params))
            renders.append(
                FileRender('dawn/native/dawn_platform.h',
                           'src/' + native_dir + '/' + prefix + '_platform_autogen.h',
                           frontend_params))
            renders.append(
                FileRender('dawn/native/api_structs.h',
                           'src/' + native_dir + '/' + namespace + '_structs_autogen.h',
                           frontend_params))
            renders.append(
                FileRender('dawn/native/api_structs.cpp',
                           'src/' + native_dir + '/' + namespace + '_structs_autogen.cpp',
                           frontend_params))
            renders.append(
                FileRender('dawn/native/ProcTable.cpp',
                           'src/' + native_dir + '/ProcTable.cpp', frontend_params))
            renders.append(
                FileRender('dawn/native/ChainUtils.h',
                           'src/' + native_dir + '/ChainUtils_autogen.h',
                           frontend_params))
            renders.append(
                FileRender('dawn/native/ChainUtils.cpp',
                           'src/' + native_dir + '/ChainUtils_autogen.cpp',
                           frontend_params))
            renders.append(
                FileRender('dawn/native/Features.h',
                           'src/' + native_dir + '/Features_autogen.h',
                           frontend_params))
            renders.append(
                FileRender('dawn/native/Features.inl',
                           'src/' + native_dir + '/Features_autogen.inl',
                           frontend_params))
            renders.append(
                FileRender('dawn/native/api_absl_format.h',
                           'src/' + native_dir + '/' + api + '_absl_format_autogen.h',
                           frontend_params))
            renders.append(
                FileRender('dawn/native/api_absl_format.cpp',
                           'src/' + native_dir + '/' + api + '_absl_format_autogen.cpp',
                           frontend_params))
            renders.append(
                FileRender(
                    'dawn/native/api_StreamImpl.cpp', 'src/' + native_dir +
                    '/' + api + '_StreamImpl_autogen.cpp', frontend_params))
            renders.append(
                FileRender('dawn/native/ObjectType.h',
                           'src/' + native_dir + '/ObjectType_autogen.h',
                           frontend_params))
            renders.append(
                FileRender('dawn/native/ObjectType.cpp',
                           'src/' + native_dir + '/ObjectType_autogen.cpp',
                           frontend_params))

        if 'dawn_utils' in targets:
            # Generate ComboLimits without any extensions so it works on
            # all targets (and doesn't chain any experimental stuff like
            # extensions that are output only and produce warnings on input).
            params = parse_json(loaded_json, enabled_tags=['compat'])
            renders.append(
                FileRender('dawn/utils/ComboLimits.h',
                           'src/dawn/utils/ComboLimits.h',
                           [RENDER_PARAMS_BASE, params]))
            renders.append(
                FileRender('dawn/utils/ComboLimits.cpp',
                           'src/dawn/utils/ComboLimits.cpp',
                           [RENDER_PARAMS_BASE, params]))

        if 'wire' in targets:
            params_dawn_wire = parse_json(
                loaded_json,
                enabled_tags=['compat', 'dawn', 'deprecated'],
                disabled_tags=['native'])
            additional_params = compute_wire_params(params_dawn_wire,
                                                    wire_json)

            wire_params = [
                RENDER_PARAMS_BASE, params_dawn_wire, {
                    'as_wireType': lambda type : as_wireType(metadata, type),
                    'as_annotated_wireType': \
                        lambda arg: annotate(as_wireType(metadata, arg.type), arg),
                    'is_wire_serializable': lambda type : is_wire_serializable(type),
                }, additional_params
            ]
            renders.append(
                FileRender('dawn/wire/ObjectType.h',
                           'src/dawn/wire/ObjectType_autogen.h', wire_params))
            renders.append(
                FileRender('dawn/wire/WireCmd.h',
                           'src/dawn/wire/WireCmd_autogen.h', wire_params))
            renders.append(
                FileRender('dawn/wire/WireCmd.cpp',
                           'src/dawn/wire/WireCmd_autogen.cpp', wire_params))
            renders.append(
                FileRender('dawn/wire/client/ApiObjects.h',
                           'src/dawn/wire/client/ApiObjects_autogen.h',
                           wire_params))
            renders.append(
                FileRender('dawn/wire/client/ApiProcs.cpp',
                           'src/dawn/wire/client/ApiProcs_autogen.cpp',
                           wire_params))
            renders.append(
                FileRender('dawn/wire/client/ClientBase.h',
                           'src/dawn/wire/client/ClientBase_autogen.h',
                           wire_params))
            renders.append(
                FileRender('dawn/wire/client/ClientHandlers.cpp',
                           'src/dawn/wire/client/ClientHandlers_autogen.cpp',
                           wire_params))
            renders.append(
                FileRender(
                    'dawn/wire/client/ClientPrototypes.inc',
                    'src/dawn/wire/client/ClientPrototypes_autogen.inc',
                    wire_params))
            renders.append(
                FileRender('dawn/wire/server/ServerBase.h',
                           'src/dawn/wire/server/ServerBase_autogen.h',
                           wire_params))
            renders.append(
                FileRender('dawn/wire/server/ServerDoers.cpp',
                           'src/dawn/wire/server/ServerDoers_autogen.cpp',
                           wire_params))
            renders.append(
                FileRender('dawn/wire/server/ServerHandlers.cpp',
                           'src/dawn/wire/server/ServerHandlers_autogen.cpp',
                           wire_params))
            renders.append(
                FileRender(
                    'dawn/wire/server/ServerPrototypes.inc',
                    'src/dawn/wire/server/ServerPrototypes_autogen.inc',
                    wire_params))
            renders.append(
                FileRender('dawn/wire/server/WGPUTraits.h',
                           'src/dawn/wire/server/WGPUTraits_autogen.h',
                           wire_params))

        if 'kotlin' in targets:
            params_kotlin = compute_kotlin_params(loaded_json, kotlin_json,
                                                  webgpu_json_data)
            kt_file_path = params_kotlin['kotlin_package'].replace('.', '/')
            jni_name = params_kotlin['jni_name']

            imported_templates += [
                "art/api_kotlin_types.kt",
            ]

            by_category = params_kotlin['by_category']
            for structure in by_category['structure']:
                if params_kotlin['include_structure'](structure):
                    renders.append(
                        FileRender('art/api_kotlin_structure.kt',
                                   'java/' + jni_name(structure) + '.kt', [
                                       RENDER_PARAMS_BASE, params_kotlin, {
                                           'structure': structure
                                       }
                                   ]))
            for obj in by_category['object']:
                renders.append(
                    FileRender(
                        'art/api_kotlin_object.kt',
                        'java/' + jni_name(obj) + '.kt',
                        [RENDER_PARAMS_BASE, params_kotlin, {
                            'obj': obj
                        }]))
            for function_pointer in (by_category['function pointer'] +
                                     by_category['callback function']):
                renders.append(
                    FileRender('art/api_kotlin_function_pointer.kt',
                               'java/' + jni_name(function_pointer) + '.kt', [
                                   RENDER_PARAMS_BASE, params_kotlin, {
                                       'function_pointer': function_pointer
                                   }
                               ]))
            renders.append(
                FileRender('art/api_kotlin_functions.kt',
                           'java/' + kt_file_path + '/Functions.kt',
                           [RENDER_PARAMS_BASE, params_kotlin]))
            renders.append(
                FileRender('art/api_kotlin_async_helpers.kt',
                           'java/' + kt_file_path + '/AsyncHelpers.kt',
                           [RENDER_PARAMS_BASE, params_kotlin]))

            for enum in (params_kotlin['by_category']['bitmask'] +
                         params_kotlin['by_category']['enum']):
                if params_kotlin['include_enum'](enum):
                    renders.append(
                        FileRender('art/api_kotlin_enum.kt',
                                   'java/' + jni_name(enum) + '.kt', [
                                       RENDER_PARAMS_BASE, params_kotlin, {
                                           'enum': enum
                                       }
                                   ]))

            renders.append(
                FileRender('art/api_kotlin_constants.kt',
                           'java/' + kt_file_path + '/Constants.kt',
                           [RENDER_PARAMS_BASE, params_kotlin]))

        if "jni" in targets:
            params_kotlin = compute_kotlin_params(loaded_json, kotlin_json,
                                                  webgpu_json_data)

            imported_templates += [
                "art/api_jni_types.cpp",
                "art/kotlin_record_conversion.cpp",
            ]

            renders.append(
                FileRender('art/structures.h', 'cpp/structures.h',
                           [RENDER_PARAMS_BASE, params_kotlin]))
            renders.append(
                FileRender('art/structures.cpp', 'cpp/structures.cpp',
                           [RENDER_PARAMS_BASE, params_kotlin]))
            renders.append(
                FileRender('art/methods.cpp', 'cpp/methods.cpp',
                           [RENDER_PARAMS_BASE, params_kotlin]))
            renders.append(
                FileRender('art/JNIClasses.h', 'cpp/JNIClasses.h',
                           [RENDER_PARAMS_BASE, params_kotlin]))
            renders.append(
                FileRender('art/JNIClasses.cpp', 'cpp/JNIClasses.cpp',
                           [RENDER_PARAMS_BASE, params_kotlin]))
        return GeneratorOutput(renders=renders,
                               imported_templates=imported_templates)

    def get_dependencies(self, args):
        deps = [os.path.abspath(args.dawn_json)]
        if args.wire_json != None:
            deps += [os.path.abspath(args.wire_json)]
        if args.kotlin_json != None:
            deps += [os.path.abspath(args.kotlin_json)]
        return deps


if __name__ == '__main__':
    sys.exit(run_generator(MultiGeneratorFromDawnJSON()))
