# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at https://mozilla.org/MPL/2.0/.

# Common codegen classes.

# fmt: off

from __future__ import annotations

from WebIDL import IDLUnionType
from WebIDL import IDLSequenceType
from collections import defaultdict
from itertools import groupby
from typing import cast, Optional, Any, Generic, TypeVar, TypeGuard
from collections.abc import Generator, Callable, Iterator, Iterable
from abc import abstractmethod

import operator
import os
import re
from re import Match
import string
import textwrap
import functools

from WebIDL import (
    BuiltinTypes,
    IDLArgument,
    IDLBuiltinType,
    IDLCallback,
    IDLDefaultDictionaryValue,
    IDLDictionary,
    IDLEmptySequenceValue,
    IDLInterface,
    IDLInterfaceMember,
    IDLNullableType,
    IDLNullValue,
    IDLObject,
    IDLPromiseType,
    IDLType,
    IDLTypedef,
    IDLTypedefType,
    IDLUndefinedValue,
    IDLWrapperType,
    IDLRecordType,
    IDLAttribute,
    IDLConst,
    IDLInterfaceOrNamespace,
    IDLValue,
    IDLMethod,
    IDLEnum,
    IDLCallbackType,
    IDLUnresolvedIdentifier,
    IDLMaplikeOrSetlikeOrIterableBase,
    IDLConstructor,
)

from configuration import (
    Configuration,
    Descriptor,
    DescriptorProvider,
    MakeNativeName,
    MemberIsLegacyUnforgeable,
    assert_type,
    getModuleFromObject,
    getTypesFromCallback,
    getTypesFromDescriptor,
    getTypesFromDictionary,
    iteratorNativeType,
)

AUTOGENERATED_WARNING_COMMENT = "/* THIS FILE IS AUTOGENERATED - DO NOT EDIT */\n\n"
ALLOWED_WARNING_LIST = [
    'non_camel_case_types',
    'non_upper_case_globals',
    'unsafe_op_in_unsafe_fn',
    'unused_imports',
    'unused_variables',
    'unused_assignments',
    'unused_mut',
    'clippy::approx_constant',
    'clippy::enum_variant_names',
    'clippy::let_unit_value',
    'clippy::needless_return',
    'clippy::too_many_arguments',
    'clippy::unnecessary_cast',
    'clippy::upper_case_acronyms'
]
ALLOWED_WARNINGS = f"#![allow({','.join(ALLOWED_WARNING_LIST)})]\n\n"

FINALIZE_HOOK_NAME = '_finalize'
TRACE_HOOK_NAME = '_trace'
CONSTRUCT_HOOK_NAME = '_constructor'
HASINSTANCE_HOOK_NAME = '_hasInstance'

RUST_KEYWORDS = {
    "abstract",
    "alignof",
    "as",
    "async",
    "await",
    "become",
    "box",
    "break",
    "const",
    "continue",
    "crate",
    "do",
    "dyn",
    "else",
    "enum",
    "extern",
    "false",
    "final",
    "fn",
    "for",
    "gen",
    "if",
    "impl",
    "in",
    "let",
    "loop",
    "macro",
    "match",
    "mod",
    "move",
    "mut",
    "offsetof",
    "override",
    "priv",
    "proc",
    "pub",
    "pure",
    "ref",
    "return",
    "static",
    "self",
    "sizeof",
    "struct",
    "super",
    "true",
    "trait",
    "try",
    "type",
    "typeof",
    "unsafe",
    "unsized",
    "use",
    "virtual",
    "where",
    "while",
    "yield",
}

def isIDLType(obj: IDLObject) -> TypeGuard[IDLType]:
    if obj.isType():
        assert isinstance(obj, IDLType)
        return True
    return False

def genericsForType(t: IDLObject) -> tuple[str, str]:
    if containsDomInterface(t):
        return ("<D: DomTypes>", "<D>")
    return ("", "")


def isDomInterface(t: IDLObject, logging: bool = False) -> bool:
    while isinstance(t, IDLNullableType) or isinstance(t, IDLWrapperType):
        t = t.inner
    if isinstance(t, IDLInterface):
        return True
    assert isinstance(t, IDLType)
    if t.isCallback() or t.isPromise():
        return True
    return t.isInterface() and (t.isSpiderMonkeyInterface() and not t.isBufferSource())


def containsDomInterface(t: IDLObject, logging: bool = False) -> bool:
    if isinstance(t, IDLArgument):
        t = t.type
    if isinstance(t, IDLTypedefType):
        t = t.inner
    while isinstance(t, IDLNullableType) or isinstance(t, IDLWrapperType):
        t = t.inner
    if t.isEnum():
        return False
    if t.isUnion():
        # pyrefly: ignore  # missing-attribute
        return any(map(lambda x: containsDomInterface(x), t.flatMemberTypes))
    if t.isDictionary():
        # pyrefly: ignore  # missing-attribute, bad-argument-type
        return any(map(lambda x: containsDomInterface(x), t.members)) or (t.parent and containsDomInterface(t.parent))
    if isDomInterface(t):
        return True
    assert isinstance(t, IDLType)
    if t.isSequence():
        assert isinstance(t, IDLSequenceType)
        return containsDomInterface(t.inner)
    return False


def toStringBool(arg: bool) -> str:
    return str(not not arg).lower()


def toBindingNamespace(arg: str) -> str:
    """
    Namespaces are *_Bindings

    actual path is `codegen::Bindings::{toBindingModuleFile(name)}::{toBindingNamespace(name)}`
    """
    return re.sub("((_workers)?$)", "_Binding\\1", MakeNativeName(arg))


def toBindingModuleFile(arg: str) -> str:
    """
    Module files are *Bindings

    actual path is `codegen::Bindings::{toBindingModuleFile(name)}::{toBindingNamespace(name)}`
    """
    return re.sub("((_workers)?$)", "Binding\\1", MakeNativeName(arg))


def toBindingModuleFileFromDescriptor(desc: Descriptor) -> str:
    isSuperModule = desc.maybeGetSuperModule()
    if isSuperModule is not None:
        return toBindingModuleFile(isSuperModule)
    else:
        return toBindingModuleFile(desc.name)


def stripTrailingWhitespace(text: str) -> str:
    tail = '\n' if text.endswith('\n') else ''
    lines = text.splitlines()
    for i in range(len(lines)):
        lines[i] = lines[i].rstrip()
    joined_lines = '\n'.join(lines)
    return f"{joined_lines}{tail}"


def innerContainerType(type: IDLType) -> IDLType:
    assert type.isSequence() or type.isRecord()
    assert isinstance(type, (IDLSequenceType, IDLRecordType, IDLNullableType))
    return type.inner.inner if type.nullable() else type.inner


def wrapInNativeContainerType(type: IDLType, inner: CGThing) -> CGThing:
    if type.isSequence():
        return CGWrapper(inner, pre="Vec<", post=">")
    elif type.isRecord():
        if type.nullable():
            assert isinstance(type, IDLNullableType)
            key = type.inner.keyType
        else:
            assert isinstance(type, IDLRecordType)
            key = type.keyType
        return CGRecord(key, inner)
    else:
        raise TypeError(f"Unexpected container type {type}")


builtinNames = {
    IDLType.Tags.bool: 'bool',
    IDLType.Tags.int8: 'i8',
    IDLType.Tags.int16: 'i16',
    IDLType.Tags.int32: 'i32',
    IDLType.Tags.int64: 'i64',
    IDLType.Tags.uint8: 'u8',
    IDLType.Tags.uint16: 'u16',
    IDLType.Tags.uint32: 'u32',
    IDLType.Tags.uint64: 'u64',
    IDLType.Tags.unrestricted_float: 'f32',
    IDLType.Tags.float: 'Finite<f32>',
    IDLType.Tags.unrestricted_double: 'f64',
    IDLType.Tags.double: 'Finite<f64>',
    IDLType.Tags.int8array: 'Int8Array',
    IDLType.Tags.uint8array: 'Uint8Array',
    IDLType.Tags.int16array: 'Int16Array',
    IDLType.Tags.uint16array: 'Uint16Array',
    IDLType.Tags.int32array: 'Int32Array',
    IDLType.Tags.uint32array: 'Uint32Array',
    IDLType.Tags.float32array: 'Float32Array',
    IDLType.Tags.float64array: 'Float64Array',
    IDLType.Tags.arrayBuffer: 'ArrayBuffer',
    IDLType.Tags.arrayBufferView: 'ArrayBufferView',
    IDLType.Tags.uint8clampedarray: 'Uint8ClampedArray',
}

numericTags = [
    IDLType.Tags.int8, IDLType.Tags.uint8,
    IDLType.Tags.int16, IDLType.Tags.uint16,
    IDLType.Tags.int32, IDLType.Tags.uint32,
    IDLType.Tags.int64, IDLType.Tags.uint64,
    IDLType.Tags.unrestricted_float,
    IDLType.Tags.unrestricted_double
]


# We'll want to insert the indent at the beginnings of lines, but we
# don't want to indent empty lines.  So only indent lines that have a
# non-newline character on them.
lineStartDetector = re.compile("^(?=[^\n#])", re.MULTILINE)


def indent(s: str, indentLevel: int = 2) -> str:
    """
    Indent C++ code.

    Weird secret feature: this doesn't indent lines that start with # (such as
    #include lines or #ifdef/#endif).
    """
    if s == "":
        return s
    return re.sub(lineStartDetector, indentLevel * " ", s)

@functools.cache
def dedent(s: str) -> str:
    """
    Remove all leading whitespace from s, and remove a blank line
    at the beginning.
    """
    if s.startswith('\n'):
        s = s[1:]
    return textwrap.dedent(s)


# This works by transforming the fill()-template to an equivalent
# string.Template.
fill_multiline_substitution_re = re.compile(r"( *)\$\*{(\w+)}(\n)?")


@functools.cache
def compile_fill_template(template: str) -> tuple[string.Template, list[tuple[str, str, int]]]:
    """
    Helper function for fill().  Given the template string passed to fill(),
    do the reusable part of template processing and return a pair (t,
    argModList) that can be used every time fill() is called with that
    template argument.

    argsModList is list of tuples that represent modifications to be
    made to args.  Each modification has, in order: i) the arg name,
    ii) the modified name, iii) the indent depth.
    """
    t = dedent(template)
    assert t.endswith("\n") or "\n" not in t
    argModList = []

    def replace(match: Match[str]) -> str:
        """
        Replaces a line like '  $*{xyz}\n' with '${xyz_n}',
        where n is the indent depth, and add a corresponding entry to
        argModList.

        Note that this needs to close over argModList, so it has to be
        defined inside compile_fill_template().
        """
        indentation, name, nl = match.groups()
        depth = len(indentation)

        # Check that $*{xyz} appears by itself on a line.
        prev = match.string[:match.start()]
        if (prev and not prev.endswith("\n")) or nl is None:
            raise ValueError(f"Invalid fill() template: $*{name} must appear by itself on a line")

        # Now replace this whole line of template with the indented equivalent.
        modified_name = f"{name}_{depth}"
        argModList.append((name, modified_name, depth))
        return f"${{{modified_name}}}"

    t = re.sub(fill_multiline_substitution_re, replace, t)
    return (string.Template(t), argModList)


def fill(template: str, **args: str) -> str:
    """
    Convenience function for filling in a multiline template.

    `fill(template, name1=v1, name2=v2)` is a lot like
    `string.Template(template).substitute({"name1": v1, "name2": v2})`.

    However, it's shorter, and has a few nice features:

      * If `template` is indented, fill() automatically dedents it!
        This makes code using fill() with Python's multiline strings
        much nicer to look at.

      * If `template` starts with a blank line, fill() strips it off.
        (Again, convenient with multiline strings.)

      * fill() recognizes a special kind of substitution
        of the form `$*{name}`.

        Use this to paste in, and automatically indent, multiple lines.
        (Mnemonic: The `*` is for "multiple lines").

        A `$*` substitution must appear by itself on a line, with optional
        preceding indentation (spaces only). The whole line is replaced by the
        corresponding keyword argument, indented appropriately.  If the
        argument is an empty string, no output is generated, not even a blank
        line.
    """

    t, argModList = compile_fill_template(template)
    # Now apply argModList to args
    for (name, modified_name, depth) in argModList:
        if not (args[name] == "" or args[name].endswith("\n")):
            raise ValueError(f"Argument {name} with value {args[name]} is missing a newline")
        args[modified_name] = indent(args[name], depth)

    return t.substitute(args)


class CGThing():
    """
    Abstract base class for things that spit out code.
    """
    def __init__(self) -> None:
        pass  # Nothing for now

    @abstractmethod
    def define(self) -> str:
        """Produce code for a Rust file."""
        raise NotImplementedError


class CGMethodCall(CGThing):
    """
    A class to generate selection of a method signature from a set of
    signatures and generation of a call to that signature.
    """
    cgRoot: CGThing
    def __init__(self, argsPre: list[str], nativeMethodName: str, static: bool, descriptor: Descriptor, method: IDLMethod) -> None:
        CGThing.__init__(self)

        methodName = f'\\"{descriptor.interface.identifier.name}.{method.identifier.name}\\"'

        def requiredArgCount(signature: tuple[IDLType, list[IDLArgument]]) -> int:
            arguments = signature[1]
            if len(arguments) == 0:
                return 0
            requiredArgs = len(arguments)
            while requiredArgs and arguments[requiredArgs - 1].optional:
                requiredArgs -= 1
            return requiredArgs

        signatures = method.signatures()

        def getPerSignatureCall(signature: tuple[IDLType, list[IDLArgument | FakeArgument]], argConversionStartsAt: int = 0) -> CGThing:
            signatureIndex = signatures.index(signature)
            return CGPerSignatureCall(signature[0], argsPre, signature[1],
                                      f"{nativeMethodName}{'_' * signatureIndex}",
                                      static, descriptor,
                                      method, argConversionStartsAt)

        if len(signatures) == 1:
            # Special case: we can just do a per-signature method call
            # here for our one signature and not worry about switching
            # on anything.
            signature = signatures[0]
            self.cgRoot = CGList([getPerSignatureCall(signature)])
            requiredArgs = requiredArgCount(signature)

            if requiredArgs > 0:
                code = (
                    f"if argc < {requiredArgs} {{\n"
                    f"    throw_type_error(*cx, \"Not enough arguments to {methodName}.\");\n"
                    "    return false;\n"
                    "}")
                self.cgRoot.prepend(
                    CGWrapper(CGGeneric(code), pre="\n", post="\n"))

            return

        # Need to find the right overload
        maxArgCount = method.maxArgCount
        allowedArgCounts = method.allowedArgCounts

        argCountCases = []
        for argCount in allowedArgCounts:
            possibleSignatures = method.signaturesForArgCount(argCount)
            if len(possibleSignatures) == 1:
                # easy case!
                signature = possibleSignatures[0]
                argCountCases.append(CGCase(str(argCount), getPerSignatureCall(signature)))
                continue

            distinguishingIndex = method.distinguishingIndexForArgCount(argCount)

            # We can't handle unions of non-object values at the distinguishing index.
            for (returnType, args) in possibleSignatures:
                type = args[distinguishingIndex].type
                if type.isUnion():
                    if type.nullable():
                        type = type.inner
                    for type in type.flatMemberTypes:
                        if not (type.isObject() or type.isNonCallbackInterface()):
                            raise TypeError("No support for unions with non-object variants "
                                            f"as distinguishing arguments yet: {args[distinguishingIndex].location}",
                                            )

            # Convert all our arguments up to the distinguishing index.
            # Doesn't matter which of the possible signatures we use, since
            # they all have the same types up to that point; just use
            # possibleSignatures[0]
            caseBody: list[CGThing] = [
                CGArgumentConverter(possibleSignatures[0][1][i],
                                    i, "args", "argc", descriptor)
                for i in range(0, distinguishingIndex)]

            # Select the right overload from our set.
            distinguishingArg = f"HandleValue::from_raw(args.get({distinguishingIndex}))"

            def pickFirstSignature(condition: str | None, filterLambda: Callable[[Any], bool]) -> bool:
                sigs = list(filter(filterLambda, possibleSignatures))
                assert len(sigs) < 2
                if len(sigs) > 0:
                    call = getPerSignatureCall(sigs[0], distinguishingIndex)
                    if condition is None:
                        caseBody.append(call)
                    else:
                        caseBody.append(CGGeneric(f"if {condition} {{"))
                        caseBody.append(CGIndenter(call))
                        caseBody.append(CGGeneric("}"))
                    return True
                return False

            # First check for null or undefined
            pickFirstSignature(f"{distinguishingArg}.get().is_null_or_undefined()",
                               lambda s: (s[1][distinguishingIndex].type.nullable()
                                          or s[1][distinguishingIndex].type.isDictionary()))

            # Now check for distinguishingArg being an object that implements a
            # non-callback interface.  That includes typed arrays and
            # arraybuffers.
            interfacesSigs = [
                s for s in possibleSignatures
                if (s[1][distinguishingIndex].type.isObject()
                    or s[1][distinguishingIndex].type.isUnion()
                    or s[1][distinguishingIndex].type.isNonCallbackInterface())]
            # There might be more than one of these; we need to check
            # which ones we unwrap to.

            if len(interfacesSigs) > 0:
                # The spec says that we should check for "platform objects
                # implementing an interface", but it's enough to guard on these
                # being an object.  The code for unwrapping non-callback
                # interfaces and typed arrays will just bail out and move on to
                # the next overload if the object fails to unwrap correctly.  We
                # could even not do the isObject() check up front here, but in
                # cases where we have multiple object overloads it makes sense
                # to do it only once instead of for each overload.  That will
                # also allow the unwrapping test to skip having to do codegen
                # for the null-or-undefined case, which we already handled
                # above.
                caseBody.append(CGGeneric(f"if {distinguishingArg}.get().is_object() {{"))
                for idx, sig in enumerate(interfacesSigs):
                    caseBody.append(CGIndenter(CGGeneric("'_block: {")))
                    type = sig[1][distinguishingIndex].type

                    # The argument at index distinguishingIndex can't possibly
                    # be unset here, because we've already checked that argc is
                    # large enough that we can examine this argument.
                    info = getJSToNativeConversionInfo(
                        type, descriptor, failureCode="break '_block;", isDefinitelyObject=True)
                    template = info.template
                    declType = info.declType

                    testCode = instantiateJSToNativeConversionTemplate(
                        template,
                        {"val": distinguishingArg},
                        declType,
                        f"arg{distinguishingIndex}",
                        needsAutoRoot=type_needs_auto_root(type))

                    # Indent by 4, since we need to indent further than our "do" statement
                    caseBody.append(CGIndenter(testCode, 4))
                    # If we got this far, we know we unwrapped to the right
                    # interface, so just do the call.  Start conversion with
                    # distinguishingIndex + 1, since we already converted
                    # distinguishingIndex.
                    caseBody.append(CGIndenter(
                        getPerSignatureCall(sig, distinguishingIndex + 1), 4))
                    caseBody.append(CGIndenter(CGGeneric("}")))

                caseBody.append(CGGeneric("}"))

            # XXXbz Now we're supposed to check for distinguishingArg being
            # an array or a platform object that supports indexed
            # properties... skip that last for now.  It's a bit of a pain.
            pickFirstSignature(f"{distinguishingArg}.get().is_object() && is_array_like::<D>(*cx, {distinguishingArg})",
                               lambda s:
                                   (s[1][distinguishingIndex].type.isSequence()
                                    or s[1][distinguishingIndex].type.isObject()))

            # Check for vanilla JS objects
            # XXXbz Do we need to worry about security wrappers?
            pickFirstSignature(f"{distinguishingArg}.get().is_object()",
                               lambda s: (s[1][distinguishingIndex].type.isCallback()
                                          or s[1][distinguishingIndex].type.isCallbackInterface()
                                          or s[1][distinguishingIndex].type.isDictionary()
                                          or s[1][distinguishingIndex].type.isObject()))

            # The remaining cases are mutually exclusive.  The
            # pickFirstSignature calls are what change caseBody
            # Check for strings or enums
            if pickFirstSignature(None,
                                  lambda s: (s[1][distinguishingIndex].type.isString()
                                             or s[1][distinguishingIndex].type.isEnum())):
                pass
            # Check for primitives
            elif pickFirstSignature(None,
                                    lambda s: s[1][distinguishingIndex].type.isPrimitive()):
                pass
            # Check for "any"
            elif pickFirstSignature(None,
                                    lambda s: s[1][distinguishingIndex].type.isAny()):
                pass
            else:
                # Just throw; we have no idea what we're supposed to
                # do with this.
                caseBody.append(CGGeneric("throw_type_error(*cx, \"Could not convert JavaScript argument\");\n"
                                          "return false;"))

            argCountCases.append(CGCase(str(argCount),
                                        CGList(caseBody, "\n")))

        overloadCGThings: list[CGThing] = []
        overloadCGThings.append(
            CGGeneric(f"let argcount = cmp::min(argc, {maxArgCount});"))
        overloadCGThings.append(
            CGSwitch("argcount",
                     argCountCases,
                     CGGeneric(f"throw_type_error(*cx, \"Not enough arguments to {methodName}.\");\n"
                               "return false;")))
        # XXXjdm Avoid unreachable statement warnings
        # overloadCGThings.append(
        #     CGGeneric('panic!("We have an always-returning default case");\n'
        #               'return false;'))
        self.cgRoot = CGWrapper(CGList(overloadCGThings, "\n"),
                                pre="\n")

    def define(self) -> str:
        return self.cgRoot.define()


def dictionaryHasSequenceMember(dictionary: IDLDictionary) -> bool:
    return (any(typeIsSequenceOrHasSequenceMember(m.type) for m in
                dictionary.members)
            or (dictionary.parent
                # pyrefly: ignore  # bad-argument-type
                and dictionaryHasSequenceMember(dictionary.parent)))


def typeIsSequenceOrHasSequenceMember(type: IDLType) -> bool:
    if type.nullable():
        assert isinstance(type, IDLNullableType)
        type = type.inner
    if type.isSequence():
        return True
    if type.isDictionary():
        # pyrefly: ignore  # missing-attribute
        return dictionaryHasSequenceMember(type.inner)
    if type.isUnion():
        assert isinstance(type, IDLUnionType)
        assert type.flatMemberTypes is not None
        return any(typeIsSequenceOrHasSequenceMember(m.type) for m in
                   type.flatMemberTypes)
    return False


def union_native_type(t: IDLType) -> str:
    name = t.unroll().name
    generic = "<D>" if containsDomInterface(t) else ""
    return f'GenericUnionTypes::{name}{generic}'


# Unfortunately, .capitalize() on a string will lowercase things inside the
# string, which we do not want.
def firstCap(string: str) -> str:
    return f"{string[0].upper()}{string[1:]}"


class JSToNativeConversionInfo():
    """
    An object representing information about a JS-to-native conversion.
    """
    def __init__(self, template: str | CGThing, default: str | None = None, declType: CGThing | None = None) -> None:
        """
        template: A string representing the conversion code.  This will have
                  template substitution performed on it as follows:

          ${val} is a handle to the JS::Value in question

        default: A string or None representing rust code for default value(if any).

        declType: A CGThing representing the native C++ type we're converting
                  to.  This is allowed to be None if the conversion code is
                  supposed to be used as-is.
        """
        assert isinstance(template, str)
        assert declType is None or isinstance(declType, CGThing)
        self.template = template
        self.default = default
        self.declType = declType


def getJSToNativeConversionInfo(type: IDLType, descriptorProvider: DescriptorProvider, failureCode: str | None = None,
                                isDefinitelyObject: bool = False,
                                isMember: bool | str = False,
                                isArgument: bool = False,
                                isAutoRooted: bool = False,
                                invalidEnumValueFatal: bool = True,
                                defaultValue: IDLValue | None = None,
                                exceptionCode: str | None = None,
                                allowTreatNonObjectAsNull: bool = False,
                                sourceDescription: str = "value") -> JSToNativeConversionInfo:
    """
    Get a template for converting a JS value to a native object based on the
    given type and descriptor.  If failureCode is given, then we're actually
    testing whether we can convert the argument to the desired type.  That
    means that failures to convert due to the JS value being the wrong type of
    value need to use failureCode instead of throwing exceptions.  Failures to
    convert that are due to JS exceptions (from toString or valueOf methods) or
    out of memory conditions need to throw exceptions no matter what
    failureCode is.

    If isDefinitelyObject is True, that means we know the value
    isObject() and we have no need to recheck that.

    isMember is `False`, "Dictionary", "Union" or "Variadic", and affects
    whether this function returns code suitable for an on-stack rooted binding
    or suitable for storing in an appropriate larger structure.

    invalidEnumValueFatal controls whether an invalid enum value conversion
    attempt will throw (if true) or simply return without doing anything (if
    false).

    If defaultValue is not None, it's the IDL default value for this conversion

    If allowTreatNonObjectAsNull is true, then [TreatNonObjectAsNull]
    extended attributes on nullable callback functions will be honored.

    The return value from this function is an object of JSToNativeConversionInfo consisting of four things:

    1)  A string representing the conversion code.  This will have template
        substitution performed on it as follows:

          ${val} replaced by an expression for the JS::Value in question

    2)  A string or None representing Rust code for the default value (if any).

    3)  A CGThing representing the native C++ type we're converting to
        (declType).  This is allowed to be None if the conversion code is
        supposed to be used as-is.

    4)  A boolean indicating whether the caller has to root the result.

    """
    # We should not have a defaultValue if we know we're an object
    assert not isDefinitelyObject or defaultValue is None

    isEnforceRange = type.hasEnforceRange()
    isClamp = type.hasClamp()
    if type.legacyNullToEmptyString:
        treatNullAs = "EmptyString"
    else:
        treatNullAs = "Default"

    # If exceptionCode is not set, we'll just rethrow the exception we got.
    # Note that we can't just set failureCode to exceptionCode, because setting
    # failureCode will prevent pending exceptions from being set in cases when
    # they really should be!
    if exceptionCode is None:
        exceptionCode = "return false;\n"

    if failureCode is None:
        failOrPropagate = f"throw_type_error(*cx, &error);\n{exceptionCode}"
    else:
        failOrPropagate = failureCode

    def handleOptional(template: str, declType: CGThing | None, default: str | None) -> JSToNativeConversionInfo:
        assert (defaultValue is None) == (default is None)
        return JSToNativeConversionInfo(template, default, declType)

    # Helper functions for dealing with failures due to the JS value being the
    # wrong type of value.
    def onFailureNotAnObject(failureCode: str | None) -> CGThing:
        return CGWrapper(
            CGGeneric(
                failureCode
                or (f'throw_type_error(*cx, "{firstCap(sourceDescription)} is not an object.");\n'
                    f'{exceptionCode}')),
            post="\n")

    def onFailureNotCallable(failureCode: str | None) -> CGGeneric:
        return CGGeneric(
            failureCode
            or (f'throw_type_error(*cx, \"{firstCap(sourceDescription)} is not callable.\");\n'
                f'{exceptionCode}'))

    # A helper function for handling default values.
    def handleDefault(nullValue: str) -> str | None:
        if defaultValue is None:
            return None

        if isinstance(defaultValue, IDLNullValue):
            assert type.nullable()
            return nullValue
        elif isinstance(defaultValue, IDLDefaultDictionaryValue):
            assert type.isDictionary()
            return nullValue
        elif isinstance(defaultValue, IDLEmptySequenceValue):
            assert type.isSequence()
            return "Vec::new()"

        raise TypeError("Can't handle non-null, non-empty sequence or non-empty dictionary default value here")

    # A helper function for wrapping up the template body for
    # possibly-nullable objecty stuff
    def wrapObjectTemplate(templateBody: str, nullValue: str, isDefinitelyObject: bool, type: IDLType,
                           failureCode: str | None = None) -> str:
        if not isDefinitelyObject:
            # Handle the non-object cases by wrapping up the whole
            # thing in an if cascade.
            templateBody = (
                "if ${val}.get().is_object() {\n"
                f"{CGIndenter(CGGeneric(templateBody)).define()}\n")
            if type.nullable():
                templateBody += (
                    "} else if ${val}.get().is_null_or_undefined() {\n"
                    f"    {nullValue}\n")
            templateBody += (
                "} else {\n"
                f"{CGIndenter(onFailureNotAnObject(failureCode)).define()}"
                "}")
        return templateBody

    # A helper function for types that implement FromJSValConvertible trait
    def fromJSValTemplate(config: str, errorHandler: str, exceptionCode: str) -> str:
        return f"""match FromJSValConvertible::from_jsval(*cx, ${{val}}, {config}) {{
    Ok(ConversionResult::Success(value)) => value,
    Ok(ConversionResult::Failure(error)) => {{
        {errorHandler}
    }}
    _ => {{
        {exceptionCode}
    }},
}}
"""

    assert not (isEnforceRange and isClamp)  # These are mutually exclusive

    if type.isSequence() or type.isRecord():
        innerInfo = getJSToNativeConversionInfo(innerContainerType(type),
                                                descriptorProvider,
                                                isMember="Sequence",
                                                isAutoRooted=isAutoRooted)
        assert innerInfo.declType is not None
        declType = wrapInNativeContainerType(type, innerInfo.declType)
        config = getConversionConfigForType(type, innerContainerType(type).hasEnforceRange(), isClamp, treatNullAs)

        if type.nullable():
            declType = CGWrapper(declType, pre="Option<", post=" >")

        templateBody = fromJSValTemplate(config, failOrPropagate, exceptionCode)

        return handleOptional(templateBody, declType, handleDefault("None"))

    if type.isUnion():
        declType = CGGeneric(union_native_type(type))
        if type.nullable():
            declType = CGWrapper(declType, pre="Option<", post=" >")
        assert isinstance(type, (IDLUnionType, IDLNullableType))

        templateBody = fromJSValTemplate("()", failOrPropagate, exceptionCode)

        flatMemberTypes = type.unroll().flatMemberTypes
        assert flatMemberTypes is not None

        dictionaries = [
            memberType
            for memberType in flatMemberTypes
            if memberType.isDictionary()
        ]
        if (defaultValue
                and not isinstance(defaultValue, IDLNullValue)
                and not isinstance(defaultValue, IDLDefaultDictionaryValue)):
            tag = defaultValue.type.tag()
            if tag is IDLType.Tags.bool:
                boolean = "true" if defaultValue.value else "false"
                default = f"{union_native_type(type)}::Boolean({boolean})"
            elif tag is IDLType.Tags.usvstring:
                default = f'{union_native_type(type)}::USVString(USVString("{defaultValue.value}".to_owned()))'
            elif defaultValue.type.isEnum():
                enum = defaultValue.type.inner.identifier.name
                default = f"{union_native_type(type)}::{enum}({enum}::{getEnumValueName(defaultValue.value)})"
            else:
                raise NotImplementedError("We don't currently support default values that aren't \
                                          null, boolean or default dictionary")
        elif dictionaries:
            if defaultValue:
                assert isinstance(defaultValue, IDLDefaultDictionaryValue)
                dictionary, = dictionaries
                default = (
                    f"{union_native_type(type)}::{dictionary.name}("
                    f"{CGDictionary.makeModuleName(dictionary.inner)}::"
                    f"{CGDictionary.makeDictionaryName(dictionary.inner)}::empty())"
                )
            else:
                default = None
        else:
            default = handleDefault("None")

        return handleOptional(templateBody, declType, default)

    if type.isPromise():
        assert not type.nullable()
        # Per spec, what we're supposed to do is take the original
        # Promise.resolve and call it with the original Promise as this
        # value to make a Promise out of whatever value we actually have
        # here.  The question is which global we should use.  There are
        # a couple cases to consider:
        #
        # 1) Normal call to API with a Promise argument.  This is a case the
        #    spec covers, and we should be using the current Realm's
        #    Promise.  That means the current realm.
        # 2) Promise return value from a callback or callback interface.
        #    This is in theory a case the spec covers but in practice it
        #    really doesn't define behavior here because it doesn't define
        #    what Realm we're in after the callback returns, which is when
        #    the argument conversion happens.  We will use the current
        #    realm, which is the realm of the callable (which
        #    may itself be a cross-realm wrapper itself), which makes
        #    as much sense as anything else. In practice, such an API would
        #    once again be providing a Promise to signal completion of an
        #    operation, which would then not be exposed to anyone other than
        #    our own implementation code.
        templateBody = fromJSValTemplate("()", failOrPropagate, exceptionCode)

        if isArgument:
            declType = CGGeneric("&D::Promise")
        else:
            declType = CGGeneric("Rc<D::Promise>")
        return handleOptional(templateBody, declType, handleDefault("None"))

    if type.isGeckoInterface():
        assert not isEnforceRange and not isClamp

        descriptor = descriptorProvider.getDescriptor(type.unroll().inner.identifier.name) # pyrefly: ignore  # missing-attribute

        if descriptor.interface.isCallback():
            name = descriptor.nativeType
            declType = CGWrapper(CGGeneric(f"{name}<D>"), pre="Rc<", post=">")
            template = f"{name}::new(cx, ${{val}}.get().to_object())"
            if type.nullable():
                declType = CGWrapper(declType, pre="Option<", post=">")
                template = wrapObjectTemplate(f"Some({template})", "None",
                                              isDefinitelyObject, type,
                                              failureCode)

            return handleOptional(template, declType, handleDefault("None"))

        conversionFunction = "root_from_handlevalue"
        descriptorType = descriptor.returnType
        if isMember == "Variadic":
            conversionFunction = "native_from_handlevalue"
            descriptorType = descriptor.nativeType
        elif isArgument:
            descriptorType = descriptor.argumentType
        elif descriptor.interface.identifier.name == "WindowProxy":
            conversionFunction = "windowproxy_from_handlevalue::<D>"

        if failureCode is None:
            unwrapFailureCode = (
                f'throw_type_error(*cx, "{sourceDescription} does not '
                f'implement interface {descriptor.interface.identifier.name}.");\n'
                f'{exceptionCode}')
        else:
            unwrapFailureCode = failureCode

        templateBody = fill(
            """
            match ${function}($${val}, *cx) {
                Ok(val) => val,
                Err(()) => {
                    $*{failureCode}
                }
            }
            """,
            failureCode=unwrapFailureCode + "\n",
            function=conversionFunction)

        declType = CGGeneric(descriptorType)
        if type.nullable():
            templateBody = f"Some({templateBody})"
            declType = CGWrapper(declType, pre="Option<", post=">")

        templateBody = wrapObjectTemplate(templateBody, "None",
                                          isDefinitelyObject, type, failureCode)

        return handleOptional(templateBody, declType, handleDefault("None"))

    if is_typed_array(type):
        if failureCode is None:
            unwrapFailureCode = (
                f'throw_type_error(*cx, "{sourceDescription} is not a typed array.");\n'
                f'{exceptionCode}'
            )
        else:
            unwrapFailureCode = failureCode

        typeName = type.unroll().name  # unroll because it may be nullable

        is_union_member = (isMember == "Union")

        if is_union_member:
            typeName = f"Heap{typeName}"
            map_call = ".map(RootedTraceableBox::new)"
        else:
            map_call = ""

        templateBody = fill(
            f"""
            match typedarray::${{ty}}::from($${{val}}.get().to_object()){map_call} {{
                Ok(val) => val,
                Err(()) => {{
                    $*{{failureCode}}
                }}
            }}
            """,
            ty=typeName,
            failureCode=f"{unwrapFailureCode}\n",
        )

        declType = CGGeneric(f"typedarray::{typeName}")
        if is_union_member:
            declType = CGWrapper(declType, pre="RootedTraceableBox<", post=">")

        if type.nullable():
            templateBody = f"Some({templateBody})"
            declType = CGWrapper(declType, pre="Option<", post=">")

        templateBody = wrapObjectTemplate(
            templateBody,
            "None",
            isDefinitelyObject,
            type,
            failureCode,
        )

        return handleOptional(templateBody, declType, handleDefault("None"))

    elif type.isSpiderMonkeyInterface():
        raise TypeError("Can't handle SpiderMonkey interface arguments other than typed arrays yet")

    if type.isDOMString():
        nullBehavior = getConversionConfigForType(type, isEnforceRange, isClamp, treatNullAs)

        conversionCode = fromJSValTemplate(nullBehavior, failOrPropagate, exceptionCode)

        if defaultValue is None:
            default = None
        elif isinstance(defaultValue, IDLNullValue):
            assert type.nullable()
            default = "None"
        else:
            assert defaultValue.type.tag() == IDLType.Tags.domstring
            default = f'DOMString::from("{defaultValue.value}")'
            if type.nullable():
                default = f"Some({default})"

        declType = "DOMString"
        if type.nullable():
            declType = f"Option<{declType}>"

        return handleOptional(conversionCode, CGGeneric(declType), default)

    if type.isUSVString():
        assert not isEnforceRange and not isClamp

        conversionCode = fromJSValTemplate("()", failOrPropagate, exceptionCode)

        if defaultValue is None:
            default = None
        elif isinstance(defaultValue, IDLNullValue):
            assert type.nullable()
            default = "None"
        else:
            assert defaultValue.type.tag() in (IDLType.Tags.domstring, IDLType.Tags.usvstring)
            default = f'USVString("{defaultValue.value}".to_owned())'
            if type.nullable():
                default = f"Some({default})"

        declType = "USVString"
        if type.nullable():
            declType = f"Option<{declType}>"

        return handleOptional(conversionCode, CGGeneric(declType), default)

    if type.isByteString():
        assert not isEnforceRange and not isClamp

        conversionCode = fromJSValTemplate("()", failOrPropagate, exceptionCode)

        if defaultValue is None:
            default = None
        elif isinstance(defaultValue, IDLNullValue):
            assert type.nullable()
            default = "None"
        else:
            assert defaultValue.type.tag() in (IDLType.Tags.domstring, IDLType.Tags.bytestring)
            default = f'ByteString::new(b"{defaultValue.value}".to_vec())'
            if type.nullable():
                default = f"Some({default})"

        declType = "ByteString"
        if type.nullable():
            declType = f"Option<{declType}>"

        return handleOptional(conversionCode, CGGeneric(declType), default)

    if type.isEnum():
        assert not isEnforceRange and not isClamp

        if type.nullable():
            raise TypeError("We don't support nullable enumerated arguments "
                            "yet")
        # pyrefly: ignore  # missing-attribute
        enum = type.inner.identifier.name
        if invalidEnumValueFatal:
            handleInvalidEnumValueCode = failureCode or f"throw_type_error(*cx, &error); {exceptionCode}"
        else:
            handleInvalidEnumValueCode = "return true;"

        template = fromJSValTemplate("()", handleInvalidEnumValueCode, exceptionCode)

        if defaultValue is not None:
            assert defaultValue.type.tag() == IDLType.Tags.domstring
            default = f"{enum}::{getEnumValueName(defaultValue.value)}"
        else:
            default = None

        return handleOptional(template, CGGeneric(enum), default)

    if type.isCallback():
        assert not isEnforceRange and not isClamp
        assert not type.treatNonCallableAsNull()
        assert not type.treatNonObjectAsNull() or type.nullable()
        assert not type.treatNonObjectAsNull() or not type.treatNonCallableAsNull()

        # pyrefly: ignore  # missing-attribute
        callback = type.unroll().callback
        declType = CGGeneric(f"{callback.identifier.name}<D>")
        finalDeclType = CGTemplatedType("Rc", declType)

        conversion = CGCallbackTempRoot(declType.define())

        if type.nullable():
            declType = CGTemplatedType("Option", declType)
            finalDeclType = CGTemplatedType("Option", finalDeclType)
            conversion = CGWrapper(conversion, pre="Some(", post=")")

        if allowTreatNonObjectAsNull and type.treatNonObjectAsNull():
            if not isDefinitelyObject:
                haveObject = "${val}.get().is_object()"
                template = CGIfElseWrapper(haveObject,
                                           conversion,
                                           CGGeneric("None")).define()
            else:
                template = conversion
        else:
            template = CGIfElseWrapper("IsCallable(${val}.get().to_object())",
                                       conversion,
                                       onFailureNotCallable(failureCode)).define()
            template = wrapObjectTemplate(
                template,
                "None",
                isDefinitelyObject,
                type,
                failureCode)

        if defaultValue is not None:
            assert allowTreatNonObjectAsNull
            assert type.treatNonObjectAsNull()
            assert type.nullable()
            assert isinstance(defaultValue, IDLNullValue)
            default = "None"
        else:
            default = None

        return JSToNativeConversionInfo(template, default, finalDeclType)

    if type.isAny():
        assert not isEnforceRange and not isClamp
        assert isMember != "Union"

        if isMember in ("Dictionary", "Sequence") or isAutoRooted:
            templateBody = "${val}.get()"

            if defaultValue is None:
                default = None
            elif isinstance(defaultValue, IDLNullValue):
                default = "NullValue()"
            elif isinstance(defaultValue, IDLUndefinedValue):
                default = "UndefinedValue()"
            else:
                raise TypeError("Can't handle non-null, non-undefined default value here")

            if not isAutoRooted:
                templateBody = f"RootedTraceableBox::from_box(Heap::boxed({templateBody}))"
                if default is not None:
                    default = f"RootedTraceableBox::from_box(Heap::boxed({default}))"
                declType = CGGeneric("RootedTraceableBox<Heap<JSVal>>")
            # AutoRooter can trace properly inner raw GC thing pointers
            else:
                declType = CGGeneric("JSVal")

            return handleOptional(templateBody, declType, default)

        declType = CGGeneric("HandleValue")

        if defaultValue is None:
            default = None
        elif isinstance(defaultValue, IDLNullValue):
            default = "HandleValue::null()"
        elif isinstance(defaultValue, IDLUndefinedValue):
            default = "HandleValue::undefined()"
        else:
            raise TypeError("Can't handle non-null, non-undefined default value here")

        return handleOptional("${val}", declType, default)

    if type.isObject():
        assert not isEnforceRange and not isClamp

        templateBody = "${val}.get().to_object()"
        default = "ptr::null_mut()"

        if isMember in ("Dictionary", "Union", "Sequence") and not isAutoRooted:
            templateBody = f"RootedTraceableBox::from_box(Heap::boxed({templateBody}))"
            default = "RootedTraceableBox::new(Heap::default())"
            declType = CGGeneric("RootedTraceableBox<Heap<*mut JSObject>>")
        else:
            # TODO: Need to root somehow
            # https://github.com/servo/servo/issues/6382
            declType = CGGeneric("*mut JSObject")

        templateBody = wrapObjectTemplate(templateBody, default,
                                          isDefinitelyObject, type, failureCode)

        return handleOptional(templateBody, declType,
                              handleDefault(default))

    if type.isDictionary():
        # There are no nullable dictionaries
        assert not type.nullable() or (isMember and isMember != "Dictionary")

        # pyrefly: ignore  # missing-attribute
        typeName = f"{CGDictionary.makeModuleName(type.inner)}::{CGDictionary.makeDictionaryName(type.inner)}"
        if containsDomInterface(type):
            typeName += "<D>"
        declType = CGGeneric(typeName)
        empty = f"{typeName.replace('<D>', '')}::empty()"

        if type_needs_tracing(type):
            declType = CGTemplatedType("RootedTraceableBox", declType)

        template = fromJSValTemplate("()", failOrPropagate, exceptionCode)

        return handleOptional(template, declType, handleDefault(empty))

    if type.isUndefined():
        # This one only happens for return values, and its easy: Just
        # ignore the jsval.
        return JSToNativeConversionInfo("", None, None)

    if not type.isPrimitive():
        raise TypeError(f"Need conversion for argument type '{type}'")

    conversionBehavior = getConversionConfigForType(type, isEnforceRange, isClamp, treatNullAs)

    if failureCode is None:
        failureCode = 'return false'

    declType = CGGeneric(builtinNames[type.tag()])
    if type.nullable():
        declType = CGWrapper(declType, pre="Option<", post=">")

    template = fromJSValTemplate(conversionBehavior, failOrPropagate, exceptionCode)

    if defaultValue is not None:
        if isinstance(defaultValue, IDLNullValue):
            assert type.nullable()
            defaultStr = "None"
        else:
            tag = defaultValue.type.tag()
            if tag in [IDLType.Tags.float, IDLType.Tags.double]:
                defaultStr = f"Finite::wrap({defaultValue.value})"
            elif tag in numericTags:
                defaultStr = str(defaultValue.value)
            else:
                assert tag == IDLType.Tags.bool
                defaultStr = toStringBool(defaultValue.value)

            if type.nullable():
                defaultStr = f"Some({defaultStr})"
    else:
        defaultStr = None

    return handleOptional(template, declType, defaultStr)


def instantiateJSToNativeConversionTemplate(templateBody: str, replacements: dict[str, Any],
                                            declType: CGThing | None, declName: str,
                                            needsAutoRoot: bool = False) -> CGThing:
    """
    Take the templateBody and declType as returned by
    getJSToNativeConversionInfo, a set of replacements as required by the
    strings in such a templateBody, and a declName, and generate code to
    convert into a stack Rust binding with that name.
    """
    result = CGList([], "\n")

    conversion = CGGeneric(string.Template(templateBody).substitute(replacements))

    if declType is not None:
        newDecl = [
            CGGeneric("let "),
            CGGeneric(declName),
            CGGeneric(": "),
            declType,
            CGGeneric(" = "),
            conversion,
            CGGeneric(";"),
        ]
        result.append(CGList(newDecl))
    else:
        result.append(conversion)

    if needsAutoRoot:
        result.append(CGGeneric(f"auto_root!(in(*cx) let {declName} = {declName});"))
    # Add an empty CGGeneric to get an extra newline after the argument
    # conversion.
    result.append(CGGeneric(""))

    return result


def convertConstIDLValueToJSVal(value: IDLValue) -> str | None:
    if isinstance(value, IDLNullValue):
        return "ConstantVal::NullVal"
    tag = value.type.tag()
    if tag in [IDLType.Tags.int8, IDLType.Tags.uint8, IDLType.Tags.int16,
               IDLType.Tags.uint16, IDLType.Tags.int32]:
        return f"ConstantVal::Int({value.value})"
    if tag == IDLType.Tags.uint32:
        return f"ConstantVal::Uint({value.value})"
    if tag in [IDLType.Tags.int64, IDLType.Tags.uint64]:
        return f"ConstantVal::Double({value.value} as f64)"
    if tag == IDLType.Tags.bool:
        return "ConstantVal::Bool(true)" if value.value else "ConstantVal::BoolVal(false)"
    if tag in [IDLType.Tags.unrestricted_float, IDLType.Tags.float,
               IDLType.Tags.unrestricted_double, IDLType.Tags.double]:
        return f"ConstantVal::Double({value.value} as f64)"
    raise TypeError(f"Const value of unhandled type: {value.type}")


class CGArgumentConverter(CGThing):
    """
    A class that takes an IDL argument object, its index in the
    argument list, and the argv and argc strings and generates code to
    unwrap the argument to the right native type.
    """
    converter: CGThing
    def __init__(self, argument: IDLArgument | FakeArgument, index: int, args: str, argc: str, descriptorProvider: DescriptorProvider,
                 invalidEnumValueFatal: bool=True) -> None:
        CGThing.__init__(self)
        assert not argument.defaultValue or argument.optional

        replacementVariables = {
            "val": f"HandleValue::from_raw({args}.get({index}))",
        }

        info = getJSToNativeConversionInfo(
            argument.type,
            descriptorProvider,
            invalidEnumValueFatal=invalidEnumValueFatal,
            defaultValue=argument.defaultValue,
            isMember="Variadic" if argument.variadic else False,
            isAutoRooted=type_needs_auto_root(argument.type),
            allowTreatNonObjectAsNull=argument.allowTreatNonCallableAsNull())
        template = info.template
        default = info.default
        declType = info.declType

        if not argument.variadic:
            if argument.optional:
                condition = f"{args}.get({index}).is_undefined()"
                if argument.defaultValue:
                    assert default
                    template = CGIfElseWrapper(condition,
                                               CGGeneric(default),
                                               CGGeneric(template)).define()
                else:
                    assert not default
                    assert declType is not None
                    declType = CGWrapper(declType, pre="Option<", post=">")
                    template = CGIfElseWrapper(condition,
                                               CGGeneric("None"),
                                               CGGeneric(f"Some({template})")).define()
            else:
                assert not default

            arg = f"arg{index}"

            self.converter = instantiateJSToNativeConversionTemplate(
                template, replacementVariables, declType, arg,
                needsAutoRoot=type_needs_auto_root(argument.type))

        else:
            assert argument.optional
            variadicConversion = {
                "val": f"HandleValue::from_raw({args}.get(variadicArg))",
            }
            innerConverter = [instantiateJSToNativeConversionTemplate(
                template, variadicConversion, declType, "slot")]

            arg = f"arg{index}"
            if argument.type.isGeckoInterface():
                init = f"rooted_vec!(let mut {arg})"
                innerConverter.append(CGGeneric(f"{arg}.push(Dom::from_ref(&*slot));"))
            else:
                init = f"let mut {arg} = vec![]"
                innerConverter.append(CGGeneric(f"{arg}.push(slot);"))
            inner = CGIndenter(CGList(innerConverter, "\n"), 8).define()

            sub = "" if index == 0 else f"- {index}"

            self.converter = CGGeneric(f"""
{init};
if {argc} > {index} {{
    {arg}.reserve({argc} as usize{sub});
    for variadicArg in {index}..{argc} {{
{inner}
    }}
}}""")

    def define(self) -> str:
        return self.converter.define()


def wrapForType(jsvalRef: str, result: str = 'result', successCode: str = 'true', pre: str = '') -> str:
    """
    Reflect a Rust value into JS.

      * 'jsvalRef': a MutableHandleValue in which to store the result
                    of the conversion;
      * 'result': the name of the variable in which the Rust value is stored;
      * 'successCode': the code to run once we have done the conversion.
      * 'pre': code to run before the conversion if rooting is necessary
    """
    wrap = f"{pre}\n({result}).to_jsval(*cx, {jsvalRef});"
    if successCode:
        wrap += f"\n{successCode}"
    return wrap


def typeNeedsCx(type: IDLType | None, retVal: bool = False) -> bool:
    if type is None:
        return False
    if type.nullable():
        assert isinstance(type, IDLNullableType)
        type = type.inner
    if type.isSequence():
        assert isinstance(type, IDLSequenceType)
        type = type.inner
    if type.isUnion():
        assert isinstance(type, IDLUnionType)
        flatMemberTypes = type.unroll().flatMemberTypes
        assert flatMemberTypes is not None

        return any(typeNeedsCx(t) for t in flatMemberTypes)
    if retVal and type.isSpiderMonkeyInterface():
        return True
    return type.isAny() or type.isObject()


def returnTypeNeedsOutparam(type: IDLType | None) -> bool:
    if type is None:
        return False
    if type.nullable():
        assert isinstance(type, IDLNullableType)
        type = type.inner
    return type.isAny()


def outparamTypeFromReturnType(type: IDLType) -> str:
    if type.isAny():
        return "MutableHandleValue"
    raise TypeError(f"Don't know how to handle {type} as an outparam")


# Returns a conversion behavior suitable for a type
def getConversionConfigForType(type: IDLType, isEnforceRange: bool, isClamp: bool, treatNullAs: str) -> str:
    if type.isSequence() or type.isRecord():
        return getConversionConfigForType(innerContainerType(type), isEnforceRange, isClamp, treatNullAs)
    if type.isDOMString():
        assert not isEnforceRange and not isClamp

        treatAs = {
            "Default": "StringificationBehavior::Default",
            "EmptyString": "StringificationBehavior::Empty",
        }
        if treatNullAs not in treatAs:
            raise TypeError(f"We don't support [TreatNullAs={treatNullAs}]")
        if type.nullable():
            # Note: the actual behavior passed here doesn't matter for nullable
            # strings.
            return "StringificationBehavior::Default"
        else:
            return treatAs[treatNullAs]
    if type.isPrimitive() and type.isInteger():
        if isEnforceRange:
            return "ConversionBehavior::EnforceRange"
        elif isClamp:
            return "ConversionBehavior::Clamp"
        else:
            return "ConversionBehavior::Default"
    assert not isEnforceRange and not isClamp
    return "()"


def builtin_return_type(returnType: IDLType) -> CGThing:
    result = CGGeneric(builtinNames[returnType.tag()])
    if returnType.nullable():
        result = CGWrapper(result, pre="Option<", post=">")
    return result


# Returns a CGThing containing the type of the return value.
def getRetvalDeclarationForType(returnType: IDLType | None, descriptorProvider: DescriptorProvider) -> CGThing:
    if returnType is None or returnType.isUndefined():
        # Nothing to declare
        return CGGeneric("()")
    if returnType.isPrimitive() and returnType.tag() in builtinNames:
        return builtin_return_type(returnType)
    if is_typed_array(returnType) and returnType.tag() in builtinNames:
        return builtin_return_type(returnType)
    if returnType.isDOMString():
        result = CGGeneric("DOMString")
        if returnType.nullable():
            result = CGWrapper(result, pre="Option<", post=">")
        return result
    if returnType.isUSVString():
        result = CGGeneric("USVString")
        if returnType.nullable():
            result = CGWrapper(result, pre="Option<", post=">")
        return result
    if returnType.isByteString():
        result = CGGeneric("ByteString")
        if returnType.nullable():
            result = CGWrapper(result, pre="Option<", post=">")
        return result
    if returnType.isEnum():
        # pyrefly: ignore  # missing-attribute
        result = CGGeneric(returnType.unroll().inner.identifier.name)
        if returnType.nullable():
            result = CGWrapper(result, pre="Option<", post=">")
        return result
    if returnType.isPromise():
        assert not returnType.nullable()
        return CGGeneric("Rc<D::Promise>")
    if returnType.isGeckoInterface():
        descriptor = descriptorProvider.getDescriptor(
            # pyrefly: ignore  # missing-attribute
            returnType.unroll().inner.identifier.name)
        result = CGGeneric(descriptor.returnType)
        if returnType.nullable():
            result = CGWrapper(result, pre="Option<", post=">")
        return result
    if returnType.isCallback():
        # pyrefly: ignore  # missing-attribute
        callback = returnType.unroll().callback
        result = CGGeneric(f'Rc<{getModuleFromObject(callback)}::{callback.identifier.name}<D>>')
        if returnType.nullable():
            result = CGWrapper(result, pre="Option<", post=">")
        return result
    if returnType.isUnion():
        result = CGGeneric(union_native_type(returnType))
        if returnType.nullable():
            result = CGWrapper(result, pre="Option<", post=">")
        return result
    if returnType.isAny():
        return CGGeneric("JSVal")
    if returnType.isObject() or returnType.isSpiderMonkeyInterface():
        result = CGGeneric("NonNull<JSObject>")
        if returnType.nullable():
            result = CGWrapper(result, pre="Option<", post=">")
        return result
    if returnType.isSequence() or returnType.isRecord():
        result = getRetvalDeclarationForType(innerContainerType(returnType), descriptorProvider)
        result = wrapInNativeContainerType(returnType, result)
        if returnType.nullable():
            result = CGWrapper(result, pre="Option<", post=">")
        return result
    if returnType.isDictionary():
        nullable = returnType.nullable()
        # pyrefly: ignore  # missing-attribute
        dictName = returnType.inner.name if nullable else returnType.name
        generic = "<D>" if containsDomInterface(returnType) else ""
        result = CGGeneric(f"{dictName}{generic}")
        if type_needs_tracing(returnType):
            result = CGWrapper(result, pre="RootedTraceableBox<", post=">")
        if nullable:
            result = CGWrapper(result, pre="Option<", post=">")
        return result

    raise TypeError(f"Don't know how to declare return value for {returnType}")


def MemberCondition(pref: str | None, func: str | None, exposed: set | None, secure: bool | None) -> list[str]:
    """
    A string representing the condition for a member to actually be exposed.
    Any of the arguments can be None. If not None, they should have the
    following types:

    pref: The name of the preference.
    func: The name of the function.
    exposed: One or more names of an exposed global.
    secure: Requires secure context.
    """
    assert pref is None or isinstance(pref, str)
    assert func is None or isinstance(func, str)
    assert exposed is None or isinstance(exposed, set)
    assert func is None or pref is None or exposed is None or secure is None
    conditions = []
    if secure:
        conditions.append('Condition::SecureContext()')
    if pref:
        conditions.append(f'Condition::Pref("{pref}")')
    if func:
        conditions.append(f'Condition::Func(D::{func})')
    if exposed:
        conditions.extend([
            f"Condition::Exposed(Globals::{camel_to_upper_snake(i)})" for i in exposed
        ])
    if len(conditions) == 0:
        conditions.append("Condition::Satisfied")
    return conditions

PropertyDefinerElementType = TypeVar('PropertyDefinerElementType')

class PropertyDefiner(Generic[PropertyDefinerElementType]):
    """
    A common superclass for defining things on prototype objects.

    Subclasses should implement generateArray to generate the actual arrays of
    things we're defining. They should also set self.regular to the list of
    things exposed to web pages.
    """
    name: str
    regular: list[PropertyDefinerElementType]

    def __init__(self, descriptor: Descriptor, name: str) -> None:
        self.descriptor = descriptor
        self.name = name

    def variableName(self) -> str:
        return f"s{self.name}"

    def length(self) -> int:
        return len(self.regular)

    @abstractmethod
    def generateArray(self, array: list[PropertyDefinerElementType], name: str) -> str:
        raise NotImplementedError

    def __str__(self) -> str:
        # We only need to generate id arrays for things that will end
        # up used via ResolveProperty or EnumerateProperties.
        return self.generateArray(self.regular, self.variableName())

    @staticmethod
    def getStringAttr(member: IDLInterfaceMember, name: str) -> str | None:
        attr = member.getExtendedAttribute(name)
        if attr is None:
            return None
        # It's a list of strings
        assert len(attr) == 1
        assert attr[0] is not None
        return attr[0]

    @staticmethod
    def getControllingCondition(interfaceMember: IDLInterfaceMember, descriptor: Descriptor) -> list[str]:
        return MemberCondition(
            PropertyDefiner.getStringAttr(interfaceMember,
                                          "Pref"),
            PropertyDefiner.getStringAttr(interfaceMember,
                                          "Func"),
            interfaceMember.exposureSet,
            interfaceMember.getExtendedAttribute("SecureContext"))

    def generateGuardedArray(
            self,
            array: list[PropertyDefinerElementType],
            name: str,
            specTemplate: Callable[[PropertyDefinerElementType], str] | str,
            specTerminator: str | None,
            specType: str,
            getCondition: Callable[[PropertyDefinerElementType, Descriptor], list[str]],
            getDataTuple: Callable[[PropertyDefinerElementType], tuple[str, ...]]
    ) -> str:
        """
        This method generates our various arrays.

        array is an array of interface members as passed to generateArray

        name is the name as passed to generateArray

        specTemplate is a template for each entry of the spec array

        specTerminator is a terminator for the spec array (inserted at the end
          of the array), or None

        specType is the actual typename of our spec

        getDataTuple is a callback function that takes an array entry and
          returns a tuple suitable for substitution into specTemplate.
        """

        # We generate an all-encompassing list of lists of specs, with each sublist
        # representing a group of members that share a common pref name. That will
        # make sure the order of the properties as exposed on the interface and
        # interface prototype objects does not change when pref control is added to
        # members while still allowing us to define all the members in the smallest
        # number of JSAPI calls.
        assert len(array) != 0
        specs = []
        prefableSpecs = []
        prefableTemplate = '    Guard::new(%s, (%s)[%d])'
        if isinstance(specTemplate, str):
            origTemplate = specTemplate
            specTemplate = lambda _: origTemplate  # noqa

        for cond, members in groupby(array, lambda m: getCondition(m, self.descriptor)):
            currentSpecs = [specTemplate(m) % getDataTuple(m) for m in members]
            if specTerminator:
                currentSpecs.append(specTerminator)
            joinedCurrentSpecs = ',\n'.join(currentSpecs)
            specs.append(f"&Box::leak(Box::new([\n{joinedCurrentSpecs}]))[..]\n")
            conds = ','.join(cond) if isinstance(cond, list) else cond
            prefableSpecs.append(
                prefableTemplate % (f"&[{conds}]", f"unsafe {{ {name}_specs.get() }}", len(specs) - 1)
            )

        joinedSpecs = ',\n'.join(specs)
        specsArray = f"static {name}_specs: ThreadUnsafeOnceLock<&[&[{specType}]]> = ThreadUnsafeOnceLock::new();\n"

        initSpecs = f"""
pub(crate) fn init_{name}_specs<D: DomTypes>() {{
    {name}_specs.set(Box::leak(Box::new([{joinedSpecs}])));
}}"""

        joinedPrefableSpecs = ',\n'.join(prefableSpecs)
        prefArray = f"static {name}: ThreadUnsafeOnceLock<&[Guard<&[{specType}]>]> = ThreadUnsafeOnceLock::new();\n"

        initPrefs = f"""
pub(crate) fn init_{name}_prefs<D: DomTypes>() {{
    {name}.set(Box::leak(Box::new([{joinedPrefableSpecs}])));
}}"""

        return f"{specsArray}{initSpecs}{prefArray}{initPrefs}"

    def generateUnguardedArray(
            self,
            array: list[PropertyDefinerElementType],
            name: str,
            specTemplate: Callable[[PropertyDefinerElementType], str] | str,
            specTerminator: str,
            specType: str,
            getCondition: Callable[[PropertyDefinerElementType, Descriptor], list[str]],
            getDataTuple: Callable[[PropertyDefinerElementType], tuple[str, ...]]
    ) -> str:
        """
        Takes the same set of parameters as generateGuardedArray but instead
        generates a single, flat array of type `&[specType]` that contains all
        provided members. The provided members' conditions shall be homogeneous,
        or else this method will fail.
        """

        # this method can't handle heterogeneous condition
        groups = groupby(array, lambda m: getCondition(m, self.descriptor))
        assert len(list(groups)) == 1

        if isinstance(specTemplate, str):
            origTemplate = specTemplate
            specTemplate = lambda _: origTemplate  # noqa

        specsArray = [specTemplate(m) % getDataTuple(m) for m in array]
        specsArray.append(specTerminator)

        joinedSpecs = ',\n'.join(specsArray)
        initialSpecs = f"static {name}: ThreadUnsafeOnceLock<&[{specType}]> = ThreadUnsafeOnceLock::new();\n"
        initSpecs = f"""
pub(crate) fn init_{name}<D: DomTypes>() {{
    {name}.set(Box::leak(Box::new([{joinedSpecs}])));
}}"""
        return dedent(f"{initialSpecs}{initSpecs}")


# The length of a method is the minimum of the lengths of the
# argument lists of all its overloads.
def methodLength(method: IDLMethod) -> int:
    signatures = method.signatures()
    return min(
        len([arg for arg in arguments if not arg.optional and not arg.variadic])
        for (_, arguments) in signatures)


class MethodDefiner(PropertyDefiner):
    """
    A class for defining methods on a prototype object.
    """
    def __init__(self, descriptor: Descriptor, name: str, static: bool, unforgeable: bool, crossorigin: bool = False) -> None:
        assert not (static and unforgeable)
        assert not (static and crossorigin)
        assert not (unforgeable and crossorigin)
        PropertyDefiner.__init__(self, descriptor, name)

        # TODO: Separate the `(static, unforgeable, crossorigin) = (False, False, True)` case
        #       to a separate class or something.

        # FIXME https://bugzilla.mozilla.org/show_bug.cgi?id=772822
        #       We should be able to check for special operations without an
        #       identifier. For now we check if the name starts with __

        # Ignore non-static methods for callback interfaces
        if not descriptor.interface.isCallback() or static:
            methods = [m for m in descriptor.interface.members if
                       m.isMethod() and m.isStatic() == static
                       and (bool(m.getExtendedAttribute("CrossOriginCallable")) or not crossorigin)
                       and not m.isIdentifierLess()
                       and (MemberIsLegacyUnforgeable(m, descriptor) == unforgeable or crossorigin)]
        else:
            methods = []
        self.regular: list[dict[str, Any]] = []
        for m in methods:
            method = self.methodData(m, descriptor, crossorigin)

            if m.isStatic():
                method["nativeName"] = CGDictionary.makeMemberName(
                    descriptor.binaryNameFor(m.identifier.name, True)
                )

            self.regular.append(method)

        # TODO: Once iterable is implemented, use tiebreak rules instead of
        # failing. Also, may be more tiebreak rules to implement once spec bug
        # is resolved.
        # https://www.w3.org/Bugs/Public/show_bug.cgi?id=28592
        def hasIterator(methods: list[IDLMethod], regular: list[dict[str, Any]]) -> bool:
            return (any("@@iterator" in m.aliases for m in methods)
                    or any("@@iterator" == r["name"] for r in regular))

        # Check whether we need to output an @@iterator due to having an indexed
        # getter.  We only do this while outputting non-static and
        # non-unforgeable methods, since the @@iterator function will be
        # neither.
        if (not static
            and not unforgeable
            and not crossorigin
            and descriptor.supportsIndexedProperties()):
            if hasIterator(methods, self.regular):
                raise TypeError("Cannot have indexed getter/attr on "
                                f"interface {self.descriptor.interface.identifier.name} with other members "
                                "that generate @@iterator, such as "
                                "maplike/setlike or aliased functions.")
            self.regular.append({"name": '@@iterator',
                                 "methodInfo": False,
                                 "selfHostedName": "$ArrayValues",
                                 "length": 0,
                                 "flags": "0",  # Not enumerable, per spec.
                                 "condition": "Condition::Satisfied"})

        # Generate the keys/values/entries aliases for value iterables.
        maplikeOrSetlikeOrIterable = descriptor.interface.maplikeOrSetlikeOrIterable
        if (not static and not unforgeable and not crossorigin
                and maplikeOrSetlikeOrIterable
                and maplikeOrSetlikeOrIterable.isIterable()
                and maplikeOrSetlikeOrIterable.isValueIterator()):
            m = maplikeOrSetlikeOrIterable

            # Add our keys/values/entries/forEach
            self.regular.append({
                "name": "keys",
                "methodInfo": False,
                "selfHostedName": "ArrayKeys",
                "length": 0,
                "flags": "JSPROP_ENUMERATE",
                "condition": PropertyDefiner.getControllingCondition(m,
                                                                     descriptor)
            })
            self.regular.append({
                "name": "values",
                "methodInfo": False,
                "selfHostedName": "$ArrayValues",
                "length": 0,
                "flags": "JSPROP_ENUMERATE",
                "condition": PropertyDefiner.getControllingCondition(m,
                                                                     descriptor)
            })
            self.regular.append({
                "name": "entries",
                "methodInfo": False,
                "selfHostedName": "ArrayEntries",
                "length": 0,
                "flags": "JSPROP_ENUMERATE",
                "condition": PropertyDefiner.getControllingCondition(m,
                                                                     descriptor)
            })
            self.regular.append({
                "name": "forEach",
                "methodInfo": False,
                "selfHostedName": "ArrayForEach",
                "length": 1,
                "flags": "JSPROP_ENUMERATE",
                "condition": PropertyDefiner.getControllingCondition(m,
                                                                     descriptor)
            })

        isLegacyUnforgeableInterface = bool(descriptor.interface.getExtendedAttribute("LegacyUnforgeable"))
        if not static and unforgeable == isLegacyUnforgeableInterface and not crossorigin:
            stringifier = descriptor.operations['Stringifier']
            if stringifier:
                self.regular.append({
                    "name": "toString",
                    "nativeName": stringifier.identifier.name,
                    "length": 0,
                    "flags": "JSPROP_ENUMERATE",
                    "condition": PropertyDefiner.getControllingCondition(stringifier, descriptor)
                })
        self.unforgeable = unforgeable
        self.crossorigin = crossorigin

    @staticmethod
    def methodData(m: IDLMethod, descriptor: Descriptor, crossorigin: bool) -> dict[str, Any]:
        return {
            "name": m.identifier.name,
            "methodInfo": not m.isStatic(),
            "length": methodLength(m),
            "flags": "JSPROP_READONLY" if crossorigin else "JSPROP_ENUMERATE",
            "condition": PropertyDefiner.getControllingCondition(m, descriptor),
            "returnsPromise": m.returnsPromise()
        }

    def generateArray(self, array: list[dict[str, Any]], name: str) -> str:
        if len(array) == 0:
            return ""

        def condition(m: dict[str, Any], d: Descriptor) -> list[str]:
            return m["condition"]

        def specData(m: dict[str, Any]) -> tuple:
            flags = m["flags"]
            if self.unforgeable:
                flags += " | JSPROP_PERMANENT | JSPROP_READONLY"
            if flags != "0":
                flags = f"({flags}) as u16"
            if "selfHostedName" in m:
                selfHostedName = str_to_cstr_ptr(m["selfHostedName"])
                assert not m.get("methodInfo", True)
                accessor = "None"
                jitinfo = "ptr::null()"
            else:
                selfHostedName = "ptr::null()"
                if m.get("methodInfo", True):
                    if m.get("returnsPromise", False):
                        exceptionToRejection = "true"
                    else:
                        exceptionToRejection = "false"
                    identifier = m.get("nativeName", m["name"])
                    # Go through an intermediate type here, because it's not
                    # easy to tell whether the methodinfo is a JSJitInfo or
                    # a JSTypedMethodJitInfo here.  The compiler knows, though,
                    # so let it do the work.
                    jitinfo = (f"unsafe {{ {identifier}_methodinfo.get() }}"
                               " as *const _ as *const JSJitInfo")
                    accessor = f"Some(generic_method::<{exceptionToRejection}>)"
                else:
                    if m.get("returnsPromise", False):
                        jitinfo = f"unsafe {{ {m.get('nativeName', m['name'])}_methodinfo.get() }}"
                        accessor = "Some(generic_static_promise_method)"
                    else:
                        jitinfo = "ptr::null()"
                        accessor = f'Some({m.get("nativeName", m["name"])}::<D>)'
            if m["name"].startswith("@@"):
                assert not self.crossorigin
                name = f'JSPropertySpec_Name {{ symbol_: SymbolCode::{m["name"][2:]} as usize + 1 }}'
            else:
                name = f'JSPropertySpec_Name {{ string_: {str_to_cstr_ptr(m["name"])} }}'
            return (name, accessor, jitinfo, m["length"], flags, selfHostedName)

        specTemplate = (
            '    JSFunctionSpec {\n'
            '        name: %s,\n'
            '        call: JSNativeWrapper { op: %s, info: %s },\n'
            '        nargs: %s,\n'
            '        flags: %s,\n'
            '        selfHostedName: %s\n'
            '    }')
        specTerminator = (
            '    JSFunctionSpec {\n'
            '        name: JSPropertySpec_Name { string_: ptr::null() },\n'
            '        call: JSNativeWrapper { op: None, info: ptr::null() },\n'
            '        nargs: 0,\n'
            '        flags: 0,\n'
            '        selfHostedName: ptr::null()\n'
            '    }')

        if self.crossorigin:
            return self.generateUnguardedArray(
                array, name,
                specTemplate, specTerminator,
                'JSFunctionSpec',
                condition, specData)
        else:
            return self.generateGuardedArray(
                array, name,
                specTemplate, specTerminator,
                'JSFunctionSpec',
                condition, specData)


class AttrDefiner(PropertyDefiner):
    def __init__(self, descriptor: Descriptor, name: str, static: bool, unforgeable: bool, crossorigin: bool = False) -> None:
        assert not (static and unforgeable)
        assert not (static and crossorigin)
        assert not (unforgeable and crossorigin)
        PropertyDefiner.__init__(self, descriptor, name)

        # TODO: Separate the `(static, unforgeable, crossorigin) = (False, False, True)` case
        #       to a separate class or something.

        self.name = name
        self.descriptor = descriptor
        self.regular: list[dict[str, Any]] = [
            {
                "name": m.identifier.name,
                "attr": m,
                "flags": "JSPROP_ENUMERATE",
                "kind": "JSPropertySpec_Kind::NativeAccessor",
            }
            for m in descriptor.interface.members if
            m.isAttr() and m.isStatic() == static
            and (MemberIsLegacyUnforgeable(m, descriptor) == unforgeable or crossorigin)
            and (not crossorigin
                 or m.getExtendedAttribute("CrossOriginReadable")
                 or m.getExtendedAttribute("CrossOriginWritable"))
        ]
        self.static = static
        self.unforgeable = unforgeable
        self.crossorigin = crossorigin

        if not static and not unforgeable and not crossorigin and not (
                descriptor.interface.isNamespace() or descriptor.interface.isCallback()
        ):
            self.regular.append({
                "name": "@@toStringTag",
                "attr": None,
                "flags": "JSPROP_READONLY",
                "kind": "JSPropertySpec_Kind::Value",
            })

    def generateArray(self, array: list[dict[str, Any]], name: str) -> str:
        if len(array) == 0:
            return ""

        def getter(attr: dict[str, Any]) -> str:
            attr = attr['attr']

            if self.crossorigin and not attr.getExtendedAttribute("CrossOriginReadable"):
                return "JSNativeWrapper { op: None, info: ptr::null() }"

            if self.static:
                accessor = f'get_{self.descriptor.internalNameFor(attr.identifier.name)}::<D>'
                jitinfo = "ptr::null()"
            else:
                if attr.type.isPromise():
                    exceptionToRejection = "true"
                else:
                    exceptionToRejection = "false"
                if attr.hasLegacyLenientThis():
                    accessor = f"generic_lenient_getter::<{exceptionToRejection}>"
                else:
                    accessor = f"generic_getter::<{exceptionToRejection}>"
                internalName = self.descriptor.internalNameFor(attr.identifier.name)
                jitinfo = f"unsafe {{ {internalName}_getterinfo.get() }}"

            return f"JSNativeWrapper {{ op: Some({accessor}), info: {jitinfo} }}"

        def setter(attr: dict[str, Any]) -> str :
            attr = attr['attr']

            if ((self.crossorigin and not attr.getExtendedAttribute("CrossOriginWritable"))
                or (attr.readonly
                    and not attr.getExtendedAttribute("PutForwards")
                    and not attr.getExtendedAttribute("Replaceable"))):
                return "JSNativeWrapper { op: None, info: ptr::null() }"

            if self.static:
                accessor = f'set_{self.descriptor.internalNameFor(attr.identifier.name)}::<D>'
                jitinfo = "ptr::null()"
            else:
                if attr.hasLegacyLenientThis():
                    accessor = "generic_lenient_setter"
                else:
                    accessor = "generic_setter"
                internalName = self.descriptor.internalNameFor(attr.identifier.name)
                jitinfo = f"unsafe {{ {internalName}_setterinfo.get() }}"

            return f"JSNativeWrapper {{ op: Some({accessor}), info: {jitinfo} }}"

        def condition(m: dict[str, Any], d: Descriptor) -> list[str]:
            if m["name"] == "@@toStringTag":
                return MemberCondition(pref=None, func=None, exposed=None, secure=None)
            return PropertyDefiner.getControllingCondition(m["attr"], d)

        def specData(attr: dict[str, Any]) -> tuple:
            if attr["name"] == "@@toStringTag":
                return (attr["name"][2:], attr["flags"], attr["kind"],
                        str_to_cstr_ptr(self.descriptor.interface.getClassName()))

            flags = attr["flags"]
            if self.unforgeable:
                flags += " | JSPROP_PERMANENT"
            return (str_to_cstr_ptr(attr["attr"].identifier.name), flags, attr["kind"], getter(attr),
                    setter(attr))

        def template(m: dict[str, Any]) -> str:
            if m["name"] == "@@toStringTag":
                return """    JSPropertySpec {
                    name: JSPropertySpec_Name { symbol_: SymbolCode::%s as usize + 1 },
                    attributes_: (%s),
                    kind_: (%s),
                    u: JSPropertySpec_AccessorsOrValue {
                        value: JSPropertySpec_ValueWrapper {
                            type_: JSPropertySpec_ValueWrapper_Type::String,
                            __bindgen_anon_1: JSPropertySpec_ValueWrapper__bindgen_ty_1 {
                                string: %s,
                            }
                        }
                    }
                }
"""
            return """    JSPropertySpec {
                    name: JSPropertySpec_Name { string_: %s },
                    attributes_: (%s),
                    kind_: (%s),
                    u: JSPropertySpec_AccessorsOrValue {
                        accessors: JSPropertySpec_AccessorsOrValue_Accessors {
                            getter: JSPropertySpec_Accessor {
                                native: %s,
                            },
                            setter: JSPropertySpec_Accessor {
                                native: %s,
                            }
                        }
                    }
                }
"""

        if self.crossorigin:
            return self.generateUnguardedArray(
                array, name,
                template,
                '    JSPropertySpec::ZERO',
                'JSPropertySpec',
                condition, specData)
        else:
            return self.generateGuardedArray(
                array, name,
                template,
                '    JSPropertySpec::ZERO',
                'JSPropertySpec',
                condition, specData)


class ConstDefiner(PropertyDefiner[IDLConst]):
    """
    A class for definining constants on the interface object
    """
    def __init__(self, descriptor: Descriptor, name: str) -> None:
        PropertyDefiner.__init__(self, descriptor, name)
        self.name = name
        self.regular: list[IDLConst] = [m for m in descriptor.interface.members if m.isConst()]

    def generateArray(self, array: list[IDLConst], name: str) -> str:
        if len(array) == 0:
            return ""

        def specData(const: IDLConst) -> tuple:
            return (str_to_cstr(const.identifier.name),
                    convertConstIDLValueToJSVal(const.value))

        return self.generateGuardedArray(
            array,
            name,
            '    ConstantSpec { name: %s, value: %s }',
            None,
            'ConstantSpec',
            PropertyDefiner.getControllingCondition, specData)


# We'll want to insert the indent at the beginnings of lines, but we
# don't want to indent empty lines.  So only indent lines that have a
# non-newline character on them.
lineStartDetector = re.compile("^(?=[^\n])", re.MULTILINE)


class CGIndenter(CGThing):
    """
    A class that takes another CGThing and generates code that indents that
    CGThing by some number of spaces.  The default indent is two spaces.
    """
    def __init__(self, child: CGThing, indentLevel: int = 4) -> None:
        CGThing.__init__(self)
        self.child = child
        self.indent = " " * indentLevel

    def define(self) -> str:
        defn = self.child.define()
        if defn != "":
            return re.sub(lineStartDetector, self.indent, defn)
        else:
            return defn


class CGWrapper(CGThing):
    """
    Generic CGThing that wraps other CGThings with pre and post text.
    """
    child: CGThing
    pre: str
    post: str
    reindent: bool

    def __init__(self, child: CGThing, pre: str = "", post: str= "", reindent: bool = False) -> None:
        CGThing.__init__(self)
        self.child = child
        self.pre = pre
        self.post = post
        self.reindent = reindent

    def define(self) -> str:
        defn = self.child.define()
        if self.reindent:
            # We don't use lineStartDetector because we don't want to
            # insert whitespace at the beginning of our _first_ line.
            defn = stripTrailingWhitespace(
                defn.replace("\n", f"\n{' ' * len(self.pre)}"))
        return f"{self.pre}{defn}{self.post}"


class CGRecord(CGThing):
    """
    CGThing that wraps value CGThing in record with key type equal to keyType parameter
    """
    def __init__(self, keyType: IDLType, value: CGThing) -> None:
        CGThing.__init__(self)
        assert keyType.isString()
        self.keyType = keyType
        self.value = value

    def define(self) -> str:
        if self.keyType.isByteString():
            keyDef = "ByteString"
        elif self.keyType.isDOMString():
            keyDef = "DOMString"
        elif self.keyType.isUSVString():
            keyDef = "USVString"
        else:
            assert False

        defn = f"{keyDef}, {self.value.define()}"
        return f"Record<{defn}>"


TopLevelType = IDLInterfaceOrNamespace | IDLDictionary | IDLEnum | IDLType


class CGImports(CGWrapper):
    """
    Generates the appropriate import/use statements.
    """
    def __init__(
            self,
            child: CGThing,
            descriptors: list[Descriptor],
            callbacks: list[IDLCallback],
            dictionaries: list[IDLDictionary],
            enums: list[IDLEnum],
            typedefs: list[IDLTypedef],
            imports: list[str],
            config: Configuration,
    ) -> None:
        """
        Adds a set of imports.
        """

        def componentTypes(type: IDLType | IDLDictionary) -> list[IDLType | IDLDictionary]:
            if isIDLType(type) and type.nullable():
                type = type.unroll()
            if type.isUnion():
                assert isinstance(type, IDLUnionType)
                assert type.flatMemberTypes is not None
                return type.flatMemberTypes
            if type.isDictionary():
                assert isinstance(type, (IDLDictionary, IDLWrapperType))
                return [type] + getTypesFromDictionary(type)
            if isinstance(type, IDLType) and type.isSequence():
                assert isinstance(type, IDLSequenceType)
                return componentTypes(type.inner)
            return [type]

        def isImportable(type: TopLevelType) -> bool:
            if not type.isType():
                assert (type.isInterface() or type.isDictionary()
                        or type.isEnum() or type.isNamespace())
                return True
            assert isinstance(type, IDLType)
            return not (type.builtin or type.isSequence() or type.isUnion())

        def relatedTypesForSignatures(method: IDLMethod | IDLCallback) -> list[IDLType]:
            types = []
            for (returnType, arguments) in method.signatures():
                types += componentTypes(returnType)
                for arg in arguments:
                    types += componentTypes(arg.type)
            return types

        def getIdentifier(t: IDLObject) -> IDLUnresolvedIdentifier:
            if isIDLType(t):
                if t.isCallback():
                    assert isinstance(t, IDLCallbackType)
                    return t.callback.identifier
                raise Exception(f"Don't know how to handle type without identifier: {t}")
            assert t.isInterface() or t.isDictionary() or t.isEnum() or t.isNamespace()
            assert isinstance(t, (IDLInterfaceOrNamespace, IDLDictionary, IDLEnum))
            return t.identifier

        def removeWrapperAndNullableTypes(
            types: list[IDLType | IDLDictionary | IDLInterfaceOrNamespace]
        ) -> list[TopLevelType]:
            normalized = []
            for t in types:
                while isIDLType(t) and (t.nullable() or isinstance(t, IDLWrapperType)):
                    assert isinstance(t, (IDLNullableType, IDLWrapperType))
                    t = t.inner
                if isImportable(t):
                    normalized += [t]
            return normalized

        types = []
        descriptorProvider = config.getDescriptorProvider()
        for d in descriptors:
            if not d.interface.isCallback():
                types += [d.interface]

            if d.interface.isIteratorInterface():
                types += [d.interface.iterableInterface]

            members = d.interface.members + d.interface.legacyFactoryFunctions
            constructor = d.interface.ctor()
            if constructor:
                members += [constructor]

            if d.proxy:
                members += [o for o in list(d.operations.values()) if o]

            for m in members:
                if m.isMethod():
                    types += relatedTypesForSignatures(m)
                    if m.isStatic():
                        types += [
                            descriptorProvider.getDescriptor(iface).interface
                            for iface in d.interface.exposureSet
                        ]
                elif m.isAttr():
                    types += componentTypes(m.type)

        # Import the type names used in the callbacks that are being defined.
        for c in callbacks:
            types += relatedTypesForSignatures(c)

        # Import the type names used in the dictionaries that are being defined.
        for d in dictionaries:
            types += componentTypes(d)

        # Import the type names used in the typedefs that are being defined.
        for t in typedefs:
            if not t.innerType.isCallback():
                types += componentTypes(t.innerType)

        # Normalize the types we've collected and remove any ones which can't be imported.
        types = removeWrapperAndNullableTypes(types)

        descriptorProvider = config.getDescriptorProvider()
        extras = []
        for t in types:
            # Importing these callbacks in the same module that defines them is an error.
            if t.isCallback():
                if getIdentifier(t) in [c.identifier for c in callbacks]:
                    continue
            # Importing these types in the same module that defines them is an error.
            if t in dictionaries or t in enums:
                continue
            if t.isInterface() or t.isNamespace():
                name = getIdentifier(t).name
                descriptor = descriptorProvider.getDescriptor(name)
                parentName = descriptor.getParentName()
                while parentName:
                    descriptor = descriptorProvider.getDescriptor(parentName)
                    extras += [descriptor.bindingPath]
                    parentName = descriptor.getParentName()
            elif isIDLType(t) and t.isRecord():
                extras += ['crate::record::Record']
            elif isinstance(t, IDLPromiseType):
                pass
            else:
                if t.isEnum():
                    extras += [f'{getModuleFromObject(t)}::{getIdentifier(t).name}Values']
                extras += [f'{getModuleFromObject(t)}::{getIdentifier(t).name}']

        statements = []
        statements.extend(f'use {i};' for i in sorted(set(imports + extras)))

        joinedStatements = '\n'.join(statements)
        CGWrapper.__init__(self, child,
                           pre=f'{joinedStatements}\n\n')


class CGIfWrapper(CGWrapper):
    def __init__(self, condition: str, child: CGThing) -> None:
        pre = CGWrapper(CGGeneric(condition), pre="if ", post=" {\n",
                        reindent=True)
        CGWrapper.__init__(self, CGIndenter(child), pre=pre.define(),
                           post="\n}")


class CGTemplatedType(CGWrapper):
    def __init__(self, templateName: str, child: CGThing) -> None:
        CGWrapper.__init__(self, child, pre=f"{templateName}<", post=">")


class CGNamespace(CGWrapper):
    def __init__(self, namespace: str, child: CGThing, public: bool = False) -> None:
        pub = "pub " if public else ""
        pre = f"{pub}mod {namespace} {{\n"
        post = f"}} // mod {namespace}"
        CGWrapper.__init__(self, child, pre=pre, post=post)

    @staticmethod
    def build(namespaces: list[str], child: CGThing, public: bool = False) -> CGThing:
        """
        Static helper method to build multiple wrapped namespaces.
        """
        if not namespaces:
            return child
        inner = CGNamespace.build(namespaces[1:], child, public=public)
        return CGNamespace(namespaces[0], inner, public=public)


def DOMClassTypeId(desc: Descriptor) -> str:
    protochain = desc.prototypeChain
    inner = ""
    if desc.hasDescendants():
        if desc.interface.getExtendedAttribute("Abstract"):
            return "crate::codegen::InheritTypes::TopTypeId { abstract_: () }"
        name = desc.interface.identifier.name
        inner = f"(crate::codegen::InheritTypes::{name}TypeId::{name})"
    elif len(protochain) == 1:
        return "crate::codegen::InheritTypes::TopTypeId { alone: () }"
    reversed_protochain = list(reversed(protochain))
    for (child, parent) in zip(reversed_protochain, reversed_protochain[1:]):
        inner = f"(crate::codegen::InheritTypes::{parent}TypeId::{child}{inner})"
    return f"crate::codegen::InheritTypes::TopTypeId {{ {protochain[0].lower()}: {inner} }}"


def DOMClass(descriptor: Descriptor) -> str:
    protoList = [f'PrototypeList::ID::{proto}' for proto in descriptor.prototypeChain]
    # Pad out the list to the right length with ID::Last so we
    # guarantee that all the lists are the same length.  ID::Last
    # is never the ID of any prototype, so it's safe to use as
    # padding.
    protoList.extend(['PrototypeList::ID::Last'] * (descriptor.config.maxProtoChainLength - len(protoList)))
    prototypeChainString = ', '.join(protoList)
    mallocSizeOf = f"malloc_size_of_including_raw_self::<{descriptor.concreteType}>"
    if descriptor.isGlobal():
        globals_ = camel_to_upper_snake(descriptor.name)
    else:
        globals_ = 'EMPTY'
    return f"""
DOMClass {{
    interface_chain: [ {prototypeChainString} ],
    depth: {descriptor.prototypeDepth},
    type_id: {DOMClassTypeId(descriptor)},
    malloc_size_of: {mallocSizeOf} as unsafe fn(&mut _, _) -> _,
    global: Globals::{globals_},
}}"""


class CGDOMJSClass(CGThing):
    """
    Generate a DOMJSClass for a given descriptor
    """
    def __init__(self, descriptor: Descriptor) -> None:
        CGThing.__init__(self)
        self.descriptor = descriptor

    def define(self) -> str:
        parentName = self.descriptor.getParentName()
        if not parentName:
            parentName = "Reflector"

        args = {
            "domClass": DOMClass(self.descriptor),
            "enumerateHook": "None",
            "finalizeHook": f"{FINALIZE_HOOK_NAME}::<D>",
            "flags": "JSCLASS_FOREGROUND_FINALIZE",
            "name": str_to_cstr_ptr(self.descriptor.interface.identifier.name),
            "resolveHook": "None",
            "mayResolveHook": "None",
            "slots": "1",
            "traceHook": f"{TRACE_HOOK_NAME}::<D>",
        }
        if self.descriptor.isGlobal():
            assert not self.descriptor.weakReferenceable
            args["flags"] = "JSCLASS_IS_GLOBAL | JSCLASS_DOM_GLOBAL | JSCLASS_FOREGROUND_FINALIZE"
            args["slots"] = "JSCLASS_GLOBAL_SLOT_COUNT + 1"
            if self.descriptor.interface.getExtendedAttribute("NeedResolve"):
                args["enumerateHook"] = "Some(enumerate_window::<D>)"
                args["resolveHook"] = "Some(resolve_window::<D>)"
                args["mayResolveHook"] = "Some(may_resolve_window::<D>)"
            else:
                args["enumerateHook"] = "Some(enumerate_global)"
                args["resolveHook"] = "Some(resolve_global)"
                args["mayResolveHook"] = "Some(may_resolve_global)"
            args["traceHook"] = "js::jsapi::JS_GlobalObjectTraceHook"
        elif self.descriptor.weakReferenceable:
            args["slots"] = "2"
        return f"""
static CLASS_OPS: ThreadUnsafeOnceLock<JSClassOps> = ThreadUnsafeOnceLock::new();

pub(crate) fn init_class_ops<D: DomTypes>() {{
    CLASS_OPS.set(JSClassOps {{
        addProperty: None,
        delProperty: None,
        enumerate: None,
        newEnumerate: {args['enumerateHook']},
        resolve: {args['resolveHook']},
        mayResolve: {args['mayResolveHook']},
        finalize: Some({args['finalizeHook']}),
        call: None,
        construct: None,
        trace: Some({args['traceHook']}),
    }});
}}

pub static Class: ThreadUnsafeOnceLock<DOMJSClass> = ThreadUnsafeOnceLock::new();

pub(crate) fn init_domjs_class<D: DomTypes>() {{
    init_class_ops::<D>();
    Class.set(DOMJSClass {{
        base: JSClass {{
            name: {args['name']},
            flags: JSCLASS_IS_DOMJSCLASS | {args['flags']} |
                   ((({args['slots']}) & JSCLASS_RESERVED_SLOTS_MASK) << JSCLASS_RESERVED_SLOTS_SHIFT)
                   /* JSCLASS_HAS_RESERVED_SLOTS({args['slots']}) */,
            cOps: unsafe {{ CLASS_OPS.get() }},
            spec: ptr::null(),
            ext: ptr::null(),
            oOps: ptr::null(),
        }},
        dom_class: {args['domClass']},
    }});
}}
"""


class CGAssertInheritance(CGThing):
    """
    Generate a type assertion for inheritance
    """
    def __init__(self, descriptor: Descriptor) -> None:
        CGThing.__init__(self)
        self.descriptor = descriptor

    def define(self) -> str:
        parent = self.descriptor.interface.parent
        parentName = ""
        if parent:
            parentName = parent.identifier.name
        else:
            parentName = "Reflector"

        selfName = self.descriptor.interface.identifier.name

        if selfName == "OffscreenCanvasRenderingContext2D":
            # OffscreenCanvasRenderingContext2D embeds a CanvasRenderingContext2D
            # instead of a Reflector as an optimization,
            # but this is fine since CanvasRenderingContext2D
            # also has a reflector
            #
            # FIXME *RenderingContext2D should use Inline
            parentName = "crate::dom::canvasrenderingcontext2d::CanvasRenderingContext2D"
        args = {
            "parentName": parentName,
            "selfName": selfName,
        }

        return f"""
impl {args['selfName']} {{
    fn __assert_parent_type(&self) {{
        use crate::dom::bindings::inheritance::HasParent;
        // If this type assertion fails, make sure the first field of your
        // DOM struct is of the correct type -- it must be the parent class.
        let _: &{args['parentName']} = self.as_parent();
    }}
}}
"""


def str_to_cstr(s: str) -> str:
    return f'c"{s}"'


def str_to_cstr_ptr(s: str) -> str:
    return f'c"{s}".as_ptr()'


class CGPrototypeJSClass(CGThing):
    def __init__(self, descriptor: Descriptor) -> None:
        CGThing.__init__(self)
        self.descriptor = descriptor

    def define(self) -> str:
        name = str_to_cstr_ptr(f"{self.descriptor.interface.identifier.name}Prototype")
        slotCount = 0
        if self.descriptor.hasLegacyUnforgeableMembers:
            slotCount += 1
        slotCountStr = f"{slotCount} & JSCLASS_RESERVED_SLOTS_MASK" if slotCount > 0 else "0"
        return f"""
static PrototypeClass: JSClass = JSClass {{
    name: {name},
    flags:
        // JSCLASS_HAS_RESERVED_SLOTS()
        ({slotCountStr} ) << JSCLASS_RESERVED_SLOTS_SHIFT,
    cOps: ptr::null(),
    spec: ptr::null(),
    ext: ptr::null(),
    oOps: ptr::null(),
}};
"""


class CGInterfaceObjectJSClass(CGThing):
    def __init__(self, descriptor: Descriptor) -> None:
        assert descriptor.interface.hasInterfaceObject() and not descriptor.interface.isCallback()
        CGThing.__init__(self)
        self.descriptor = descriptor

    def define(self) -> str:
        if self.descriptor.interface.isNamespace():
            classString = self.descriptor.interface.getExtendedAttribute("ClassString")
            if classString:
                classString = classString[0]
            else:
                classString = "Object"
            return f"""
static NAMESPACE_OBJECT_CLASS: NamespaceObjectClass = unsafe {{
    NamespaceObjectClass::new({str_to_cstr(classString)})
}};
"""
        if self.descriptor.interface.ctor():
            constructorBehavior = f"InterfaceConstructorBehavior::call({CONSTRUCT_HOOK_NAME}::<D>)"
        else:
            constructorBehavior = "InterfaceConstructorBehavior::throw()"
        name = self.descriptor.interface.identifier.name
        representation = f'b"function {name}() {{\\n    [native code]\\n}}"'
        return f"""
static INTERFACE_OBJECT_CLASS: ThreadUnsafeOnceLock<NonCallbackInterfaceObjectClass> = ThreadUnsafeOnceLock::new();

pub(crate) fn init_interface_object<D: DomTypes>() {{
    INTERFACE_OBJECT_CLASS.set(NonCallbackInterfaceObjectClass::new(
        Box::leak(Box::new({constructorBehavior})),
        {representation},
        PrototypeList::ID::{name},
        {self.descriptor.prototypeDepth},
    ));
}}
"""


class CGList(CGThing):
    """
    Generate code for a list of GCThings.  Just concatenates them together, with
    an optional joiner string.  "\n" is a common joiner.
    """
    def __init__(self, children: Iterable[CGThing | None], joiner: str = "") -> None:
        CGThing.__init__(self)
        # Make a copy of the kids into a list, because if someone passes in a
        # generator we won't be able to both declare and define ourselves, or
        # define ourselves more than once!
        self.children = list(children)
        self.joiner = joiner

    def append(self, child: CGThing | None) -> None:
        self.children.append(child)

    def prepend(self, child: CGThing | None) -> None:
        self.children.insert(0, child)

    def join(self, iterable: Iterable[str]) -> str:
        return self.joiner.join(s for s in iterable if len(s) > 0)

    def define(self) -> str:
        return self.join(child.define() for child in self.children if child is not None)

    def __len__(self) -> int:
        return len(self.children)


class CGIfElseWrapper(CGList):
    def __init__(self, condition: str, ifTrue: CGGeneric | CGWrapper, ifFalse: CGGeneric) -> None:
        if ifFalse.text.strip().startswith("if"):
            elseBranch = CGWrapper(ifFalse, pre=" else ")
        else:
            elseBranch = CGWrapper(CGIndenter(ifFalse), pre=" else {\n", post="\n}")
        kids = [CGIfWrapper(condition, ifTrue), elseBranch]
        CGList.__init__(self, kids)


class CGGeneric(CGThing):
    """
    A class that spits out a fixed string into the codegen.  Can spit out a
    separate string for the declaration too.
    """
    text: str
    def __init__(self, text: str) -> None:
        self.text = text

    def define(self) -> str:
        return self.text


class CGCallbackTempRoot(CGGeneric):
    def __init__(self, name: str) -> None:
        CGGeneric.__init__(self, f"{name.replace('<D>', '::<D>')}::new(cx, ${{val}}.get().to_object())")


def getAllTypes(
    descriptors: list[Descriptor],
    dictionaries: list[IDLDictionary],
    callbacks: list[IDLCallback],
    typedefs: list[IDLTypedef]
) -> Generator[tuple[IDLType, Optional[Descriptor]], None, None]:
    """
    Generate all the types we're dealing with.  For each type, a tuple
    containing type, descriptor, dictionary is yielded.  The
    descriptor can be None if the type does not come from a descriptor.
    """
    for d in descriptors:
        for t in getTypesFromDescriptor(d):
            if t.isRecord():
                # pyrefly: ignore  # missing-attribute
                yield (t.inner, d)
            yield (t, d)
    for dictionary in dictionaries:
        for t in getTypesFromDictionary(dictionary):
            # pyrefly: ignore  # missing-attribute
            if t.isRecord():
                # pyrefly: ignore  # missing-attribute
                yield (t.inner, None)
            yield (t, None)
    for callback in callbacks:
        for t in getTypesFromCallback(callback):
            if t.isRecord():
                # pyrefly: ignore  # missing-attribute
                yield (t.inner, None)
            yield (t, None)
    for typedef in typedefs:
        if typedef.innerType.isRecord():
            yield (typedef.innerType.inner, None)
        yield (typedef.innerType, None)


def UnionTypes(
    descriptors: list[Descriptor],
    dictionaries: list[IDLDictionary],
    callbacks: list[IDLCallback],
    typedefs: list[IDLTypedef],
    config: Configuration
) -> CGThing:
    """
    Returns a CGList containing CGUnionStructs for every union.
    """

    imports = [
        'crate::import::base::*',
        'crate::codegen::DomTypes::DomTypes',
        'crate::conversions::windowproxy_from_handlevalue',
        'crate::record::Record',
        'js::typedarray',
    ]

    # Now find all the things we'll need as arguments and return values because
    # we need to wrap or unwrap them.
    unionStructs: dict[str, Any] = dict()
    for (t, descriptor) in getAllTypes(descriptors, dictionaries, callbacks, typedefs):
        # pyrefly: ignore  # missing-attribute
        t = t.unroll()
        if not t.isUnion():
            continue
        assert isinstance(t, IDLUnionType) and t.flatMemberTypes is not None
        for memberType in t.flatMemberTypes:
            if memberType.isDictionary() or memberType.isEnum() or memberType.isCallback():
                memberModule = getModuleFromObject(memberType)
                memberName = (memberType.callback.identifier.name
                              if memberType.isCallback() else memberType.inner.identifier.name)
                imports.append(f"{memberModule}::{memberName}")
                if memberType.isEnum():
                    imports.append(f"{memberModule}::{memberName}Values")
        name = str(t)
        if name not in unionStructs:
            provider = descriptor or config.getDescriptorProvider()
            unionStructs[name] = CGList([
                CGUnionStruct(t, provider, config),
                CGUnionConversionStruct(t, provider)
            ])

    # Sort unionStructs by key, retrieve value
    unionStructsCG = (i[1] for i in sorted(list(unionStructs.items()), key=operator.itemgetter(0)))

    return CGImports(CGList(unionStructsCG, "\n\n"), descriptors=[], callbacks=[], dictionaries=[], enums=[],
                     typedefs=[], imports=imports, config=config)


def DomTypes(descriptors: list[Descriptor],
             descriptorProvider: DescriptorProvider,
             dictionaries: list[IDLDictionary],
             callbacks: list[IDLCallback],
             typedefs: list[IDLTypedef],
             config: Configuration
             ) -> CGThing:
    traits = [
        "crate::interfaces::DomHelpers<Self>",
        "js::rust::Trace",
        "malloc_size_of::MallocSizeOf",
        "Sized",
    ]
    joinedTraits = ' + '.join(traits)
    elements = [CGGeneric(f"pub trait DomTypes: {joinedTraits} where Self: 'static {{\n")]

    def fixupInterfaceTypeReferences(typename: str) -> str:
        return typename.replace("D::", "Self::")

    for descriptor in descriptors:
        iface_name = descriptor.interface.identifier.name
        traits = []

        traits += descriptor.additionalTraits

        chain = descriptor.prototypeChain
        upcast = descriptor.hasDescendants()

        if not upcast:
            # No other interface will implement DeriveFrom<Foo> for this Foo, so avoid
            # implementing it for itself.
            chain = chain[:-1]

        if chain:
            traits += ["crate::inheritance::Castable"]

        for parent in chain:
            traits += [f"crate::conversions::DerivedFrom<Self::{parent}>"]

        for marker in ["Serializable", "Transferable"]:
            if descriptor.interface.getExtendedAttribute(marker):
                traits += [f"crate::structuredclone::MarkedAs{marker}InIdl"]

        iterableDecl = descriptor.interface.maplikeOrSetlikeOrIterable
        if iterableDecl:
            if iterableDecl.isMaplike():
                keytype = fixupInterfaceTypeReferences(
                    getRetvalDeclarationForType(iterableDecl.keyType, descriptor).define()
                )
                valuetype = fixupInterfaceTypeReferences(
                    getRetvalDeclarationForType(iterableDecl.valueType, descriptor).define()
                )
                traits += [f"crate::like::Maplike<Key={keytype}, Value={valuetype}>"]
            if iterableDecl.isSetlike():
                keytype = fixupInterfaceTypeReferences(
                    getRetvalDeclarationForType(iterableDecl.keyType, descriptor).define()
                )
                traits += [f"crate::like::Setlike<Key={keytype}>"]
            if iterableDecl.hasKeyType():
                traits += [
                    "crate::reflector::DomObjectIteratorWrap<Self>",
                    "crate::iterable::IteratorDerives",
                ]

        if descriptor.weakReferenceable:
            traits += ["crate::weakref::WeakReferenceable"]

        if not descriptor.interface.isNamespace():
            traits += [
                "js::conversions::ToJSValConvertible",
                "crate::reflector::MutDomObject",
                "crate::reflector::DomObject",
                "crate::reflector::DomGlobalGeneric<Self>",
                "malloc_size_of::MallocSizeOf",
            ]

        if descriptor.register:
            if (
                (descriptor.concrete or descriptor.hasDescendants())
                and not descriptor.interface.isNamespace()
                and not descriptor.interface.isIteratorInterface()
            ):
                traits += [
                    "crate::conversions::IDLInterface",
                    "PartialEq",
                ]

            if descriptor.concrete and not descriptor.isGlobal():
                traits += ["crate::reflector::DomObjectWrap<Self>"]

        if not descriptor.interface.isCallback() and not descriptor.interface.isIteratorInterface():
            nonConstMembers = [m for m in descriptor.interface.members if not m.isConst()]
            ctor = descriptor.interface.ctor()
            if (
                    nonConstMembers
                    or (ctor and not ctor.isHTMLConstructor())
                    or descriptor.interface.legacyFactoryFunctions
            ):
                namespace = f"{toBindingPath(descriptor)}"
                traits += [f"crate::codegen::GenericBindings::{namespace}::{iface_name}Methods<Self>"]
            isPromise = firstCap(iface_name) == "Promise"
            elements += [
                CGGeneric("    #[cfg_attr(crown, crown::unrooted_must_root_lint::must_root)]\n"),
                CGGeneric(
                    "    #[cfg_attr(crown, crown::unrooted_must_root_lint::allow_unrooted_in_rc)]\n"
                    if isPromise else ""
                ),
                CGGeneric(f"    type {firstCap(iface_name)}: {' + '.join(traits)};\n")
            ]
    elements += [CGGeneric("}\n")]
    imports = [
        CGGeneric("use crate::root::DomRoot;\n"),
        CGGeneric("use crate::str::DOMString;\n"),
    ]
    return CGList(imports + elements)


def DomTypeHolder(descriptors: list[Descriptor],
                  descriptorProvider: DescriptorProvider,
                  dictionaries: list[IDLDictionary],
                  callbacks: list[IDLCallback],
                  typedefs: list[IDLTypedef],
                  config: Configuration
                  ) -> CGThing:
    elements = [
        CGGeneric(
            "#[derive(JSTraceable, MallocSizeOf, PartialEq)]\n"
            "pub(crate) struct DomTypeHolder;\n"
            "impl crate::DomTypes for DomTypeHolder {\n"
        ),
    ]
    for descriptor in descriptors:
        if descriptor.interface.isCallback() or descriptor.interface.isIteratorInterface():
            continue
        iface_name = descriptor.interface.identifier.name
        path = f"crate::dom::{iface_name.lower()}::{firstCap(iface_name)}"
        elements.append(CGGeneric(f"    type {firstCap(iface_name)} = {path};\n"))
    elements.append(CGGeneric("}\n"))
    return CGList(elements)


class Argument():
    """
    A class for outputting the type and name of an argument
    """
    def __init__(self, argType: str | None, name: str, default: str | None = None, mutable: bool = False) -> None:
        self.argType = argType
        self.name = name
        self.default = default
        self.mutable = mutable

    def declare(self) -> str:
        mut = 'mut ' if self.mutable else ''
        argType = f': {self.argType}' if self.argType else ''
        string = f"{mut}{self.name}{argType}"
        # XXXjdm Support default arguments somehow :/
        # if self.default is not None:
        #     string += " = " + self.default
        return string

    def define(self) -> str:
        return f'{self.argType} {self.name}'


class CGAbstractMethod(CGThing):
    """
    An abstract class for generating code for a method.  Subclasses
    should override definition_body to create the actual code.

    descriptor is the descriptor for the interface the method is associated with

    name is the name of the method as a string

    returnType is the IDLType of the return value

    args is a list of Argument objects

    inline should be True to generate an inline method, whose body is
    part of the declaration.

    alwaysInline should be True to generate an inline method annotated with
    MOZ_ALWAYS_INLINE.

    If templateArgs is not None it should be a list of strings containing
    template arguments, and the function will be templatized using those
    arguments.

    docs is None or documentation for the method in a string.

    unsafe is used to add the decorator 'unsafe' to a function, giving as a result
    an 'unsafe fn()' declaration.
    """
    def __init__(self, descriptor: Descriptor, name: str, returnType: str, args: list[Argument], inline: bool = False,
                 alwaysInline: bool = False, extern: bool = False, unsafe: bool = False, pub: bool = False,
                 templateArgs: list[str] | None = None, docs: str | None = None, doesNotPanic: bool = False,
                 extra_decorators: list[str] = []) -> None:
        CGThing.__init__(self)
        self.descriptor = descriptor
        self.name = name
        self.returnType = returnType
        self.args = args
        self.alwaysInline = alwaysInline
        self.extern = extern
        self.unsafe = extern or unsafe
        self.templateArgs = templateArgs
        self.pub = pub
        self.docs = docs
        self.catchPanic = self.extern and not doesNotPanic
        self.extra_decorators = extra_decorators

    def _argstring(self) -> str:
        return ', '.join([a.declare() for a in self.args])

    def _template(self) -> str:
        if self.templateArgs is None:
            return ''
        return f'<{", ".join(self.templateArgs)}>\n'

    def _docs(self) -> str:
        if self.docs is None:
            return ''

        lines = self.docs.splitlines()
        return ''.join(f'/// {line}\n' for line in lines)

    def _decorators(self) -> str:
        decorators = []
        if self.alwaysInline:
            decorators.append('#[inline]')

        decorators.extend(self.extra_decorators)

        if self.pub:
            decorators.append('pub')

        if self.unsafe:
            decorators.append('unsafe')

        if self.extern:
            decorators.append('extern "C"')

        if not decorators:
            return ''
        return f'{" ".join(decorators)} '

    def _returnType(self) -> str:
        return f" -> {self.returnType}" if self.returnType != "void" else ""

    def define(self) -> str:
        body = self.definition_body()

        if self.catchPanic:
            if self.returnType == "void":
                pre = "wrap_panic(&mut || {\n"
                post = "\n})"
            elif "return" not in body.define() or self.name.startswith("_constructor"):
                pre = (
                    "let mut result = false;\n"
                    "wrap_panic(&mut || result = {\n"
                )
                post = (
                    "\n});\n"
                    "result"
                )
            else:
                pre = (
                    "let mut result = false;\n"
                    "wrap_panic(&mut || result = (|| {\n"
                )
                post = (
                    "\n})());\n"
                    "result"
                )
            body = CGWrapper(CGIndenter(body), pre=pre, post=post)

        return CGWrapper(CGIndenter(body),
                         pre=self.definition_prologue(),
                         post=self.definition_epilogue()).define()

    def definition_prologue(self) -> str:
        return (f"{self._docs()}{self._decorators()}"
                f"fn {self.name}{self._template()}({self._argstring()}){self._returnType()}{{\n")

    def definition_epilogue(self) -> str:
        return "\n}\n"

    def definition_body(self) -> CGThing:
        raise NotImplementedError


class CGConstructorEnabled(CGAbstractMethod):
    """
    A method for testing whether we should be exposing this interface object.
    This can perform various tests depending on what conditions are specified
    on the interface.
    """
    def __init__(self, descriptor: Descriptor) -> None:
        CGAbstractMethod.__init__(self, descriptor,
                                  'ConstructorEnabled', 'bool',
                                  [Argument("SafeJSContext", "aCx"),
                                   Argument("HandleObject", "aObj")],
                                  templateArgs=['D: DomTypes'],
                                  pub=True)

    def definition_body(self) -> CGThing:
        conditions = []
        iface = self.descriptor.interface

        bits = " | ".join(sorted(
            f"Globals::{camel_to_upper_snake(i)}" for i in iface.exposureSet
        ))
        conditions.append(f"is_exposed_in(aObj, {bits})")

        pref = iface.getExtendedAttribute("Pref")
        if pref:
            assert isinstance(pref, list) and len(pref) == 1
            conditions.append(f'pref!({pref[0]})')

        func = iface.getExtendedAttribute("Func")
        if func:
            assert isinstance(func, list) and len(func) == 1
            conditions.append(f"D::{func[0]}(aCx, aObj)")

        secure = iface.getExtendedAttribute("SecureContext")
        if secure:
            conditions.append("""
unsafe {
    let in_realm_proof = AlreadyInRealm::assert_for_cx(aCx);
    D::GlobalScope::from_context(*aCx, InRealm::Already(&in_realm_proof)).is_secure_context()
}
""")

        return CGList((CGGeneric(cond) for cond in conditions), " &&\n")


def InitLegacyUnforgeablePropertiesOnHolder(descriptor: Descriptor, properties: PropertyArrays) -> CGThing:
    """
    Define the unforgeable properties on the unforgeable holder for
    the interface represented by descriptor.

    properties is a PropertyArrays instance.
    """
    unforgeables = []

    defineLegacyUnforgeableAttrs = "define_guarded_properties::<D>(cx, unforgeable_holder.handle(), %s, global);"
    defineLegacyUnforgeableMethods = "define_guarded_methods::<D>(cx, unforgeable_holder.handle(), %s, global);"

    unforgeableMembers = [
        (defineLegacyUnforgeableAttrs, properties.unforgeable_attrs),
        (defineLegacyUnforgeableMethods, properties.unforgeable_methods),
    ]
    for template, array in unforgeableMembers:
        if array.length() > 0:
            unforgeables.append(CGGeneric(template % f"unsafe {{ {array.variableName()}.get() }}"))
    return CGList(unforgeables, "\n")


def CopyLegacyUnforgeablePropertiesToInstance(descriptor: Descriptor) -> str:
    """
    Copy the unforgeable properties from the unforgeable holder for
    this interface to the instance object we have.
    """
    if not descriptor.hasLegacyUnforgeableMembers:
        return ""
    copyCode = ""

    # For proxies, we want to define on the expando object, not directly on the
    # reflector, so we can make sure we don't get confused by named getters.
    if descriptor.proxy:
        copyCode += """\
rooted!(in(*cx) let mut expando = ptr::null_mut::<JSObject>());
ensure_expando_object(*cx, obj.handle().into(), expando.handle_mut());
"""
        obj = "expando"
    else:
        obj = "obj"

    # We can't do the fast copy for globals, because we can't allocate the
    # unforgeable holder for those with the right JSClass. Luckily, there
    # aren't too many globals being created.
    if descriptor.isGlobal():
        copyFunc = "JS_CopyOwnPropertiesAndPrivateFields"
    else:
        copyFunc = "JS_InitializePropertiesFromCompatibleNativeObject"
    copyCode += f"""
let mut slot = UndefinedValue();
JS_GetReservedSlot(canonical_proto.get(), DOM_PROTO_UNFORGEABLE_HOLDER_SLOT, &mut slot);
rooted!(in(*cx) let mut unforgeable_holder = ptr::null_mut::<JSObject>());
unforgeable_holder.handle_mut().set(slot.to_object());
assert!({copyFunc}(*cx, {obj}.handle(), unforgeable_holder.handle()));
"""

    return copyCode


class CGWrapMethod(CGAbstractMethod):
    """
    Class that generates the Foo_Binding::Wrap function for non-callback
    interfaces.
    """
    def __init__(self, descriptor: Descriptor) -> None:
        assert not descriptor.interface.isCallback()
        assert not descriptor.isGlobal()
        args = [Argument('SafeJSContext', 'cx'),
                Argument('&D::GlobalScope', 'scope'),
                Argument('Option<HandleObject>', 'given_proto'),
                Argument(f"Box<{descriptor.concreteType}>", 'object'),
                Argument('CanGc', '_can_gc')]
        retval = f'DomRoot<{descriptor.concreteType}>'
        CGAbstractMethod.__init__(self, descriptor, 'Wrap', retval, args,
                                  pub=True, unsafe=True,
                                  extra_decorators=['#[cfg_attr(crown, allow(crown::unrooted_must_root))]'],
                                  templateArgs=['D: DomTypes'])

    def definition_body(self) -> CGThing:
        unforgeable = CopyLegacyUnforgeablePropertiesToInstance(self.descriptor)
        if self.descriptor.proxy:
            if self.descriptor.isMaybeCrossOriginObject():
                proto = "ptr::null_mut()"
                lazyProto = "true"  # Our proxy handler will manage the prototype
            else:
                proto = "canonical_proto.get()"
                lazyProto = "false"

            create = f"""
let handler: *const libc::c_void =
    RegisterBindings::proxy_handlers::{self.descriptor.interface.identifier.name}
    .load(std::sync::atomic::Ordering::Acquire);
rooted!(in(*cx) let obj = NewProxyObject(
    *cx,
    handler,
    Handle::from_raw(UndefinedHandleValue),
    {proto},
    ptr::null(),
    {lazyProto},
));
assert!(!obj.is_null());
SetProxyReservedSlot(
    obj.get(),
    0,
    &PrivateValue(raw.as_ptr() as *const libc::c_void),
);
"""
        else:
            create = """
rooted!(in(*cx) let mut proto = ptr::null_mut::<JSObject>());
if let Some(given) = given_proto {
    proto.set(*given);
    if get_context_realm(*cx) != get_object_realm(*given) {
        assert!(JS_WrapObject(*cx, proto.handle_mut()));
    }
} else {
    proto.set(*canonical_proto);
}
rooted!(in(*cx) let obj = JS_NewObjectWithGivenProto(
    *cx,
    &Class.get().base,
    proto.handle(),
));
assert!(!obj.is_null());
JS_SetReservedSlot(
    obj.get(),
    DOM_OBJECT_SLOT,
    &PrivateValue(raw.as_ptr() as *const libc::c_void),
);
"""
        if self.descriptor.weakReferenceable:
            create += """
let val = PrivateValue(ptr::null());
JS_SetReservedSlot(obj.get(), DOM_WEAK_SLOT, &val);
"""

        return CGGeneric(f"""
let raw = Root::new(MaybeUnreflectedDom::from_box(object));

let scope = scope.reflector().get_jsobject();
assert!(!scope.get().is_null());
assert!(((*get_object_class(scope.get())).flags & JSCLASS_IS_GLOBAL) != 0);
let _ac = JSAutoRealm::new(*cx, scope.get());

rooted!(in(*cx) let mut canonical_proto = ptr::null_mut::<JSObject>());
GetProtoObject::<D>(cx, scope, canonical_proto.handle_mut());
assert!(!canonical_proto.is_null());

{create}
let root = raw.reflect_with(obj.get());

{unforgeable}

DomRoot::from_ref(&*root)\
""")


class CGWrapGlobalMethod(CGAbstractMethod):
    """
    Class that generates the Foo_Binding::Wrap function for global interfaces.
    """
    def __init__(self, descriptor: Descriptor, properties: PropertyArrays) -> None:
        assert not descriptor.interface.isCallback()
        assert descriptor.isGlobal()
        args = [Argument('SafeJSContext', 'cx'),
                Argument(f"Box<{descriptor.concreteType}>", 'object')]
        retval = f'DomRoot<{descriptor.concreteType}>'
        CGAbstractMethod.__init__(self, descriptor, 'Wrap', retval, args,
                                  pub=True,
                                  extra_decorators=['#[cfg_attr(crown, allow(crown::unrooted_must_root))]'],
                                  templateArgs=['D: DomTypes'])
        self.properties = properties

    def definition_body(self) -> CGThing:
        pairs = [
            ("define_guarded_properties", self.properties.attrs),
            ("define_guarded_methods", self.properties.methods),
            ("define_guarded_constants", self.properties.consts)
        ]
        members = [f"{function}::<D>(cx, obj.handle(), {array.variableName()}.get(), obj.handle());"
                   for (function, array) in pairs if array.length() > 0]
        membersStr = "\n".join(members)

        return CGGeneric(f"""
unsafe {{
    let raw = Root::new(MaybeUnreflectedDom::from_box(object));
    let origin = (*raw.as_ptr()).upcast::<D::GlobalScope>().origin();

    rooted!(in(*cx) let mut obj = ptr::null_mut::<JSObject>());
    create_global_object::<D>(
        cx,
        &Class.get().base,
        raw.as_ptr() as *const libc::c_void,
        {TRACE_HOOK_NAME}::<D>,
        obj.handle_mut(),
        origin,
        {"true" if self.descriptor.useSystemCompartment else "false"});
    assert!(!obj.is_null());

    let root = raw.reflect_with(obj.get());

    let _ac = JSAutoRealm::new(*cx, obj.get());
    rooted!(in(*cx) let mut canonical_proto = ptr::null_mut::<JSObject>());
    GetProtoObject::<D>(cx, obj.handle(), canonical_proto.handle_mut());
    assert!(JS_SetPrototype(*cx, obj.handle(), canonical_proto.handle()));
    let mut immutable = false;
    assert!(JS_SetImmutablePrototype(*cx, obj.handle(), &mut immutable));
    assert!(immutable);

    {membersStr}

    {CopyLegacyUnforgeablePropertiesToInstance(self.descriptor)}

    DomRoot::from_ref(&*root)
}}
""")


def toBindingPath(descriptor: Descriptor) -> str:
    module = toBindingModuleFileFromDescriptor(descriptor)
    namespace = toBindingNamespace(descriptor.interface.identifier.name)
    return f"{module}::{namespace}"


class CGIDLInterface(CGThing):
    """
    Class for codegen of an implementation of the IDLInterface trait.
    """
    def __init__(self, descriptor: Descriptor) -> None:
        CGThing.__init__(self)
        self.descriptor = descriptor

    def define(self) -> str:
        interface = self.descriptor.interface
        name = interface.identifier.name
        bindingModule = f"crate::dom::bindings::codegen::GenericBindings::{toBindingPath(self.descriptor)}"
        if (interface.getUserData("hasConcreteDescendant", False)
                or interface.getUserData("hasProxyDescendant", False)):
            depth = self.descriptor.prototypeDepth
            check = f"class.interface_chain[{depth}] == PrototypeList::ID::{name}"
        elif self.descriptor.proxy:
            check = f"ptr::eq(class, unsafe {{ {bindingModule}::Class.get() }})"
        else:
            check = f"ptr::eq(class, unsafe {{ &{bindingModule}::Class.get().dom_class }})"
        return f"""
impl IDLInterface for {name} {{
    #[inline]
    fn derives(class: &'static DOMClass) -> bool {{
        {check}
    }}
}}
"""


class CGIteratorDerives(CGThing):
    """
    Class for codegen of an implementation of the IteratorDerives trait.
    """
    def __init__(self, descriptor: Descriptor) -> None:
        CGThing.__init__(self)
        self.descriptor = descriptor

    def define(self) -> str:
        iterableInterface = self.descriptor.interface.iterableInterface
        assert iterableInterface is not None
        name = iterableInterface.identifier.name
        bindingModule = f"crate::dom::bindings::codegen::Bindings::{toBindingPath(self.descriptor)}"
        return f"""
impl crate::dom::bindings::iterable::IteratorDerives for {name} {{
    #[inline]
    fn derives(class: &'static DOMClass) -> bool {{
        unsafe {{ ptr::eq(class, &{bindingModule}::Class.get().dom_class) }}
    }}
}}
"""


class CGDomObjectWrap(CGThing):
    """
    Class for codegen of an implementation of the DomObjectWrap trait.
    """
    def __init__(self, descriptor: Descriptor) -> None:
        CGThing.__init__(self)
        self.descriptor = descriptor

    def define(self) -> str:
        ifaceName = self.descriptor.interface.identifier.name
        bindingModule = f"crate::dom::bindings::codegen::GenericBindings::{toBindingPath(self.descriptor)}"
        return f"""
impl DomObjectWrap<crate::DomTypeHolder> for {firstCap(ifaceName)} {{
    const WRAP: unsafe fn(
        SafeJSContext,
        &GlobalScope,
        Option<HandleObject>,
        Box<Self>,
        CanGc,
    ) -> Root<Dom<Self>> = {bindingModule}::Wrap::<crate::DomTypeHolder>;
}}
"""


class CGDomObjectIteratorWrap(CGThing):
    """
    Class for codegen of an implementation of the DomObjectIteratorWrap trait.
    """
    def __init__(self, descriptor: Descriptor) -> None:
        CGThing.__init__(self)
        self.descriptor = descriptor

    def define(self) -> str:
        assert self.descriptor.interface.isIteratorInterface()
        iterableInterface = self.descriptor.interface.iterableInterface
        assert iterableInterface is not None
        name = iterableInterface.identifier.name
        bindingModule = f"crate::dom::bindings::codegen::GenericBindings::{toBindingPath(self.descriptor)}"
        return f"""
impl DomObjectIteratorWrap<crate::DomTypeHolder> for {name} {{
    const ITER_WRAP: unsafe fn(
        SafeJSContext,
        &GlobalScope,
        Option<HandleObject>,
        Box<IterableIterator<crate::DomTypeHolder, Self>>,
        CanGc,
    ) -> Root<Dom<IterableIterator<crate::DomTypeHolder, Self>>> = {bindingModule}::Wrap::<crate::DomTypeHolder>;
}}
"""


class CGAbstractExternMethod(CGAbstractMethod):
    """
    Abstract base class for codegen of implementation-only (no
    declaration) static methods.
    """
    def __init__(self,
                 descriptor: Descriptor,
                 name: str,
                 returnType: str,
                 args: list[Argument],
                 doesNotPanic: bool = False,
                 templateArgs: list[str] | None = None
                 ) -> None:
        CGAbstractMethod.__init__(self, descriptor, name, returnType, args,
                                  inline=False, extern=True, doesNotPanic=doesNotPanic, templateArgs=templateArgs)


class PropertyArrays():
    def __init__(self, descriptor: Descriptor) -> None:
        self.static_methods = MethodDefiner(descriptor, "StaticMethods",
                                            static=True, unforgeable=False)
        self.static_attrs = AttrDefiner(descriptor, "StaticAttributes",
                                        static=True, unforgeable=False)
        self.methods = MethodDefiner(descriptor, "Methods", static=False, unforgeable=False)
        self.unforgeable_methods = MethodDefiner(descriptor, "LegacyUnforgeableMethods",
                                                 static=False, unforgeable=True)
        self.attrs = AttrDefiner(descriptor, "Attributes", static=False, unforgeable=False)
        self.unforgeable_attrs = AttrDefiner(descriptor, "LegacyUnforgeableAttributes",
                                             static=False, unforgeable=True)
        self.consts = ConstDefiner(descriptor, "Constants")
        pass

    @staticmethod
    def arrayNames() -> list[str]:
        return [
            "static_methods",
            "static_attrs",
            "methods",
            "unforgeable_methods",
            "attrs",
            "unforgeable_attrs",
            "consts",
        ]

    def variableNames(self) -> dict[str, PropertyDefiner]:
        names = {}
        for array in self.arrayNames():
            names[array] = getattr(self, array).variableName()
        return names

    def __str__(self) -> str:
        define = ""
        for array in self.arrayNames():
            define += str(getattr(self, array))
        return define


class CGCrossOriginProperties(CGThing):
    def __init__(self, descriptor: Descriptor) -> None:
        self.methods = MethodDefiner(descriptor, "CrossOriginMethods", static=False,
                                     unforgeable=False, crossorigin=True)
        self.attributes = AttrDefiner(descriptor, "CrossOriginAttributes", static=False,
                                      unforgeable=False, crossorigin=True)

    def define(self) -> str:
        return f"{self.methods}{self.attributes}" + dedent(
            """
            static CROSS_ORIGIN_PROPERTIES: ThreadUnsafeOnceLock<CrossOriginProperties> = ThreadUnsafeOnceLock::new();

            pub(crate) fn init_cross_origin_properties<D: DomTypes>() {
                CROSS_ORIGIN_PROPERTIES.set(CrossOriginProperties {
                    attributes: unsafe { sCrossOriginAttributes.get() },
                    methods: unsafe { sCrossOriginMethods.get() },
                });
            }
            """
        )


class CGCollectJSONAttributesMethod(CGAbstractMethod):
    """
    Generate the CollectJSONAttributes method for an interface descriptor
    """
    def __init__(self, descriptor: Descriptor, toJSONMethod: IDLType | None) -> None:
        args = [Argument('*mut JSContext', 'cx'),
                Argument('RawHandleObject', 'obj'),
                Argument('*mut libc::c_void', 'this'),
                Argument('HandleObject', 'result')]
        CGAbstractMethod.__init__(self, descriptor, 'CollectJSONAttributes',
                                  'bool', args, pub=True, unsafe=True, templateArgs=["D: DomTypes"])
        self.toJSONMethod = toJSONMethod

    def definition_body(self) -> CGThing:
        ret = """let incumbent_global = D::GlobalScope::incumbent().expect("no incumbent global");
let global = incumbent_global.reflector().get_jsobject();\n"""
        interface = self.descriptor.interface
        for m in interface.members:
            if m.isAttr() and not m.isStatic() and m.type.isJSONType():
                name = m.identifier.name
                conditions = MemberCondition(None, None, m.exposureSet, None)
                ret_conditions = f'&[{", ".join(conditions)}]'
                ret += fill(
                    """
                    let conditions = ${conditions};
                    let is_satisfied = conditions.iter().any(|c|
                         c.is_satisfied::<D>(
                           SafeJSContext::from_ptr(cx),
                           HandleObject::from_raw(obj),
                           global));
                    if is_satisfied {
                      rooted!(in(cx) let mut temp = UndefinedValue());
                      if !get_${name}::<D>(cx, obj, this, JSJitGetterCallArgs { _base: temp.handle_mut().into() }) {
                        return false;
                      }
                      if !JS_DefineProperty(cx, result,
                                            ${nameAsArray},
                                            temp.handle(), JSPROP_ENUMERATE as u32) {
                        return false;
                      }
                    }
                    """,
                    name=name, nameAsArray=str_to_cstr_ptr(name), conditions=ret_conditions)
        ret += 'true\n'
        return CGGeneric(ret)


class CGCreateInterfaceObjectsMethod(CGAbstractMethod):
    """
    Generate the CreateInterfaceObjects method for an interface descriptor.

    properties should be a PropertyArrays instance.
    """
    def __init__(self, descriptor: Descriptor, properties: PropertyArrays, haveUnscopables: bool, haveLegacyWindowAliases: bool) -> None:
        args = [Argument('SafeJSContext', 'cx'), Argument('HandleObject', 'global'),
                Argument('*mut ProtoOrIfaceArray', 'cache')]
        CGAbstractMethod.__init__(self, descriptor, 'CreateInterfaceObjects', 'void', args,
                                  unsafe=True, templateArgs=['D: DomTypes'])
        self.properties = properties
        self.haveUnscopables = haveUnscopables
        self.haveLegacyWindowAliases = haveLegacyWindowAliases

    def definition_body(self) -> CGThing:
        name = self.descriptor.interface.identifier.name
        if self.descriptor.interface.isNamespace():
            if self.descriptor.interface.getExtendedAttribute("ProtoObjectHack"):
                proto = "GetRealmObjectPrototype(*cx)"
            else:
                proto = "JS_NewPlainObject(*cx)"
            if self.properties.static_methods.length():
                methods = f"{self.properties.static_methods.variableName()}.get()"
            else:
                methods = "&[]"
            if self.descriptor.interface.hasConstants():
                constants = "sConstants.get()"
            else:
                constants = "&[]"
            id = MakeNativeName(name)
            return CGGeneric(f"""
rooted!(in(*cx) let proto = {proto});
assert!(!proto.is_null());
rooted!(in(*cx) let mut namespace = ptr::null_mut::<JSObject>());
create_namespace_object::<D>(cx, global, proto.handle(), &NAMESPACE_OBJECT_CLASS,
                        {methods}, {constants}, {str_to_cstr(name)}, namespace.handle_mut());
assert!(!namespace.is_null());
assert!((*cache)[PrototypeList::Constructor::{id} as usize].is_null());
(*cache)[PrototypeList::Constructor::{id} as usize] = namespace.get();
<*mut JSObject>::post_barrier((*cache).as_mut_ptr().offset(PrototypeList::Constructor::{id} as isize),
                              ptr::null_mut(),
                              namespace.get());
""")
        if self.descriptor.interface.isCallback():
            assert not self.descriptor.interface.ctor() and self.descriptor.interface.hasConstants()
            cName = str_to_cstr(name)
            return CGGeneric(f"""
rooted!(in(*cx) let mut interface = ptr::null_mut::<JSObject>());
create_callback_interface_object::<D>(cx, global, sConstants.get(), {cName}, interface.handle_mut());
assert!(!interface.is_null());
assert!((*cache)[PrototypeList::Constructor::{name} as usize].is_null());
(*cache)[PrototypeList::Constructor::{name} as usize] = interface.get();
<*mut JSObject>::post_barrier((*cache).as_mut_ptr().offset(PrototypeList::Constructor::{name} as isize),
                              ptr::null_mut(),
                              interface.get());
""")

        parentName = self.descriptor.getParentName()
        if not parentName:
            if self.descriptor.interface.getExtendedAttribute("ExceptionClass"):
                protoGetter = "GetRealmErrorPrototype"
            elif self.descriptor.interface.isIteratorInterface():
                protoGetter = "GetRealmIteratorPrototype"
            else:
                protoGetter = "GetRealmObjectPrototype"
            getPrototypeProto = f"prototype_proto.set({protoGetter}(*cx))"
        else:
            getPrototypeProto = (
                f"{toBindingNamespace(parentName)}::GetProtoObject::<D>(cx, global, prototype_proto.handle_mut())"
            )

        code: list = [CGGeneric(f"""
rooted!(in(*cx) let mut prototype_proto = ptr::null_mut::<JSObject>());
{getPrototypeProto};
assert!(!prototype_proto.is_null());""")]

        if self.descriptor.hasNamedPropertiesObject():
            assert not self.haveUnscopables
            code.append(CGGeneric(f"""
rooted!(in(*cx) let mut prototype_proto_proto = prototype_proto.get());
D::{name}::create_named_properties_object(cx, prototype_proto_proto.handle(), prototype_proto.handle_mut());
assert!(!prototype_proto.is_null());"""))

        properties = {
            "id": name,
            "unscopables": "unscopable_names" if self.haveUnscopables else "&[]",
            "legacyWindowAliases": "legacy_window_aliases" if self.haveLegacyWindowAliases else "&[]"
        }
        for arrayName in self.properties.arrayNames():
            array = getattr(self.properties, arrayName)
            if array.length():
                properties[arrayName] = f"{array.variableName()}.get()"
            else:
                properties[arrayName] = "&[]"

        if self.descriptor.isGlobal():
            assert not self.haveUnscopables
            proto_properties = {
                "attrs": "&[]",
                "consts": "&[]",
                "id": name,
                "methods": "&[]",
                "unscopables": "&[]",
            }
        else:
            proto_properties = properties

        code.append(CGGeneric(f"""
rooted!(in(*cx) let mut prototype = ptr::null_mut::<JSObject>());
create_interface_prototype_object::<D>(cx,
                                  global,
                                  prototype_proto.handle(),
                                  &PrototypeClass,
                                  {proto_properties['methods']},
                                  {proto_properties['attrs']},
                                  {proto_properties['consts']},
                                  {proto_properties['unscopables']},
                                  prototype.handle_mut());
assert!(!prototype.is_null());
assert!((*cache)[PrototypeList::ID::{proto_properties['id']} as usize].is_null());
(*cache)[PrototypeList::ID::{proto_properties['id']} as usize] = prototype.get();
<*mut JSObject>::post_barrier((*cache).as_mut_ptr().offset(PrototypeList::ID::{proto_properties['id']} as isize),
                              ptr::null_mut(),
                              prototype.get());
"""))

        if self.descriptor.interface.hasInterfaceObject():
            properties["name"] = str_to_cstr(name)
            ctor = self.descriptor.interface.ctor()
            if ctor:
                properties["length"] = methodLength(ctor)
            else:
                properties["length"] = 0
            parentName = self.descriptor.getParentName()
            code.append(CGGeneric("rooted!(in(*cx) let mut interface_proto = ptr::null_mut::<JSObject>());"))
            if parentName:
                parentName = toBindingNamespace(parentName)
                code.append(CGGeneric(f"""
{parentName}::GetConstructorObject::<D>(cx, global, interface_proto.handle_mut());"""))
            else:
                code.append(CGGeneric("interface_proto.set(GetRealmFunctionPrototype(*cx));"))
            code.append(CGGeneric(f"""
assert!(!interface_proto.is_null());

rooted!(in(*cx) let mut interface = ptr::null_mut::<JSObject>());
create_noncallback_interface_object::<D>(cx,
                                    global,
                                    interface_proto.handle(),
                                    INTERFACE_OBJECT_CLASS.get(),
                                    {properties['static_methods']},
                                    {properties['static_attrs']},
                                    {properties['consts']},
                                    prototype.handle(),
                                    {properties['name']},
                                    {properties['length']},
                                    {properties['legacyWindowAliases']},
                                    interface.handle_mut());
assert!(!interface.is_null());"""))
            if self.descriptor.shouldCacheConstructor():
                code.append(CGGeneric(f"""
assert!((*cache)[PrototypeList::Constructor::{properties['id']} as usize].is_null());
(*cache)[PrototypeList::Constructor::{properties['id']} as usize] = interface.get();
<*mut JSObject>::post_barrier((*cache).as_mut_ptr().offset(PrototypeList::Constructor::{properties['id']} as isize),
                              ptr::null_mut(),
                              interface.get());
"""))

        aliasedMembers = [m for m in self.descriptor.interface.members if m.isMethod() and m.aliases]
        if aliasedMembers:
            def defineAlias(alias: str) -> CGThing:
                if alias == "@@iterator":
                    symbolJSID = "RUST_SYMBOL_TO_JSID(GetWellKnownSymbol(*cx, SymbolCode::iterator), \
                                  iteratorId.handle_mut())"
                    getSymbolJSID: CGThing | None = CGGeneric(fill("rooted!(in(*cx) let mut iteratorId: jsid);\n${symbolJSID};\n",
                                                   symbolJSID=symbolJSID))
                    defineFn = "JS_DefinePropertyById2"
                    prop = "iteratorId.handle()"
                    enumFlags = "0"  # Not enumerable, per spec.
                elif alias.startswith("@@"):
                    raise TypeError("Can't handle any well-known Symbol other than @@iterator")
                else:
                    getSymbolJSID = None
                    defineFn = "JS_DefineProperty"
                    prop = f'"{alias}"'
                    enumFlags = "JSPROP_ENUMERATE"
                if enumFlags != "0":
                    enumFlags = f"{enumFlags} as u32"
                return CGList([
                    getSymbolJSID,
                    # XXX If we ever create non-enumerable properties that can
                    #     be aliased, we should consider making the aliases
                    #     match the enumerability of the property being aliased.
                    CGGeneric(fill(
                        """
                        assert!(${defineFn}(*cx, prototype.handle(), ${prop}, aliasedVal.handle(), ${enumFlags}));
                        """,
                        defineFn=defineFn,
                        prop=prop,
                        enumFlags=enumFlags))
                ], "\n")

            def defineAliasesFor(m: IDLMethod) -> CGThing:
                return CGList([
                    CGGeneric(fill(
                        """
                        assert!(JS_GetProperty(*cx, prototype.handle(),
                                               ${prop} as *const u8 as *const _,
                                               aliasedVal.handle_mut()));
                        """,
                        prop=str_to_cstr_ptr(m.identifier.name)))
                ] + [defineAlias(alias) for alias in sorted(m.aliases)])

            defineAliases = CGList([
                CGGeneric(fill("""
                    // Set up aliases on the interface prototype object we just created.

                    """)),
                CGGeneric("rooted!(in(*cx) let mut aliasedVal = UndefinedValue());\n\n")
            ] + [defineAliasesFor(m) for m in sorted(aliasedMembers)])
            code.append(defineAliases)

        constructors = self.descriptor.interface.legacyFactoryFunctions
        if constructors:
            decl = f"let named_constructors: [(ConstructorClassHook, &std::ffi::CStr, u32); {len(constructors)}]"
            specs = []
            for constructor in constructors:
                hook = f"{CONSTRUCT_HOOK_NAME}_{constructor.identifier.name}"
                name = str_to_cstr(constructor.identifier.name)
                length = methodLength(constructor)
                specs.append(CGGeneric(f"({hook}::<D> as ConstructorClassHook, {name}, {length})"))
            values = CGIndenter(CGList(specs, "\n"), 4)
            code.append(CGWrapper(values, pre=f"{decl} = [\n", post="\n];"))
            code.append(CGGeneric("create_named_constructors(cx, global, &named_constructors, prototype.handle());"))

        if self.descriptor.hasLegacyUnforgeableMembers:
            # We want to use the same JSClass and prototype as the object we'll
            # end up defining the unforgeable properties on in the end, so that
            # we can use JS_InitializePropertiesFromCompatibleNativeObject to do
            # a fast copy.  In the case of proxies that's null, because the
            # expando object is a vanilla object, but in the case of other DOM
            # objects it's whatever our class is.
            #
            # Also, for a global we can't use the global's class; just use
            # nullpr and when we do the copy off the holder we'll take a slower
            # path.  This also means that we don't need to worry about matching
            # the prototype.
            if self.descriptor.proxy or self.descriptor.isGlobal():
                holderClass = "ptr::null()"
                holderProto = "HandleObject::null()"
            else:
                holderClass = "&Class.get().base as *const JSClass"
                holderProto = "prototype.handle()"
            code.append(CGGeneric(f"""
rooted!(in(*cx) let mut unforgeable_holder = ptr::null_mut::<JSObject>());
unforgeable_holder.handle_mut().set(
    JS_NewObjectWithoutMetadata(*cx, {holderClass}, {holderProto}));
assert!(!unforgeable_holder.is_null());
"""))
            code.append(InitLegacyUnforgeablePropertiesOnHolder(self.descriptor, self.properties))
            code.append(CGGeneric("""\
let val = ObjectValue(unforgeable_holder.get());
JS_SetReservedSlot(prototype.get(), DOM_PROTO_UNFORGEABLE_HOLDER_SLOT, &val)"""))

        return CGList(code, "\n")


class CGGetPerInterfaceObject(CGAbstractMethod):
    """
    A method for getting a per-interface object (a prototype object or interface
    constructor object).
    """
    def __init__(self, descriptor: Descriptor, name: str, idPrefix: str = "", pub: bool = False) -> None:
        args = [Argument('SafeJSContext', 'cx'),
                Argument('HandleObject', 'global'),
                Argument('MutableHandleObject', 'mut rval')]
        CGAbstractMethod.__init__(self, descriptor, name,
                                  'void', args, pub=pub, templateArgs=['D: DomTypes'])
        self.id = f"{idPrefix}::{MakeNativeName(self.descriptor.name)}"
        self.variant = self.id.split('::')[-2]

    def definition_body(self) -> CGThing:
        return CGGeneric(
            "get_per_interface_object_handle"
            f"(cx, global, ProtoOrIfaceIndex::{self.variant}({self.id}), CreateInterfaceObjects::<D>, rval)"
        )


class CGGetProtoObjectMethod(CGGetPerInterfaceObject):
    """
    A method for getting the interface prototype object.
    """
    def __init__(self, descriptor: Descriptor) -> None:
        CGGetPerInterfaceObject.__init__(self, descriptor, "GetProtoObject",
                                         "PrototypeList::ID", pub=True)

    def definition_body(self) -> CGThing:
        return CGList([
            CGGeneric("""\
/* Get the interface prototype object for this class.  This will create the
   object as needed. */"""),
            CGGetPerInterfaceObject.definition_body(self),
        ])


class CGGetConstructorObjectMethod(CGGetPerInterfaceObject):
    """
    A method for getting the interface constructor object.
    """
    def __init__(self, descriptor: Descriptor) -> None:
        CGGetPerInterfaceObject.__init__(self, descriptor, "GetConstructorObject",
                                         "PrototypeList::Constructor",
                                         pub=True)

    def definition_body(self) -> CGThing:
        return CGList([
            CGGeneric("""\
/* Get the interface object for this class.  This will create the object as
   needed. */"""),
            CGGetPerInterfaceObject.definition_body(self),
        ])


class CGDefineProxyHandler(CGAbstractMethod):
    """
    A method to create and cache the proxy trap for a given interface.
    """
    def __init__(self, descriptor: Descriptor) -> None:
        assert descriptor.proxy
        CGAbstractMethod.__init__(self, descriptor, 'DefineProxyHandler',
                                  '*const libc::c_void', [],
                                  pub=True, unsafe=True, templateArgs=["D: DomTypes"])

    def define(self) -> str:
        return CGAbstractMethod.define(self)

    def definition_body(self) -> CGThing:
        customDefineProperty = 'proxyhandler::define_property'
        if self.descriptor.isMaybeCrossOriginObject() or self.descriptor.operations['IndexedSetter'] or \
           self.descriptor.operations['NamedSetter']:
            customDefineProperty = 'defineProperty::<D>'

        customDelete = 'proxyhandler::delete'
        if self.descriptor.isMaybeCrossOriginObject() or self.descriptor.operations['NamedDeleter']:
            customDelete = 'delete::<D>'

        customGetPrototypeIfOrdinary = 'Some(proxyhandler::get_prototype_if_ordinary)'
        customGetPrototype = 'None'
        customSetPrototype = 'None'
        if self.descriptor.isMaybeCrossOriginObject():
            customGetPrototypeIfOrdinary = 'Some(proxyhandler::maybe_cross_origin_get_prototype_if_ordinary_rawcx)'
            customGetPrototype = 'Some(getPrototype::<D>)'
            customSetPrototype = 'Some(proxyhandler::maybe_cross_origin_set_prototype_rawcx)'
        # The base class `BaseProxyHandler`'s `setImmutablePrototype` (not to be
        # confused with ECMAScript's `[[SetImmutablePrototype]]`) always fails.
        # This is the desired behavior, so we don't override it.

        customSet = 'None'
        if self.descriptor.isMaybeCrossOriginObject():
            # `maybe_cross_origin_set_rawcx` doesn't support legacy platform objects'
            # `[[Set]]` (https://heycam.github.io/webidl/#legacy-platform-object-set) (yet).
            assert not self.descriptor.operations['IndexedGetter']
            assert not self.descriptor.operations['NamedGetter']
            customSet = 'Some(proxyhandler::maybe_cross_origin_set_rawcx::<D>)'

        getOwnEnumerablePropertyKeys = "own_property_keys::<D>"
        if self.descriptor.interface.getExtendedAttribute("LegacyUnenumerableNamedProperties") or \
           self.descriptor.isMaybeCrossOriginObject():
            getOwnEnumerablePropertyKeys = "getOwnEnumerablePropertyKeys::<D>"

        return CGGeneric(f"""
init_proxy_handler_dom_class::<D>();

let traps = ProxyTraps {{
    enter: None,
    getOwnPropertyDescriptor: Some(getOwnPropertyDescriptor::<D>),
    defineProperty: Some({customDefineProperty}),
    ownPropertyKeys: Some(own_property_keys::<D>),
    delete_: Some({customDelete}),
    enumerate: None,
    getPrototypeIfOrdinary: {customGetPrototypeIfOrdinary},
    getPrototype: {customGetPrototype},
    setPrototype: {customSetPrototype},
    setImmutablePrototype: None,
    preventExtensions: Some(proxyhandler::prevent_extensions),
    isExtensible: Some(proxyhandler::is_extensible),
    has: None,
    get: Some(get::<D>),
    set: {customSet},
    call: None,
    construct: None,
    hasOwn: Some(hasOwn::<D>),
    getOwnEnumerablePropertyKeys: Some({getOwnEnumerablePropertyKeys}),
    nativeCall: None,
    objectClassIs: None,
    className: Some(className),
    fun_toString: None,
    boxedValue_unbox: None,
    defaultValue: None,
    trace: Some({TRACE_HOOK_NAME}::<D>),
    finalize: Some({FINALIZE_HOOK_NAME}::<D>),
    objectMoved: None,
    isCallable: None,
    isConstructor: None,
}};

CreateProxyHandler(&traps, unsafe {{ Class.get() }}.as_void_ptr())\
""")


class CGDefineDOMInterfaceMethod(CGAbstractMethod):
    """
    A method for resolve hooks to try to lazily define the interface object for
    a given interface.
    """
    def __init__(self, descriptor: Descriptor) -> None:
        assert descriptor.interface.hasInterfaceObject()
        args = [
            Argument('SafeJSContext', 'cx'),
            Argument('HandleObject', 'global'),
        ]
        CGAbstractMethod.__init__(self, descriptor, 'DefineDOMInterface',
                                  'void', args, pub=True, templateArgs=['D: DomTypes'])
        if self.descriptor.interface.isCallback() or self.descriptor.interface.isNamespace():
            idPrefix = "PrototypeList::Constructor"
        else:
            idPrefix = "PrototypeList::ID"
        self.id = f"{idPrefix}::{MakeNativeName(self.descriptor.name)}"
        self.variant = self.id.split('::')[-2]

    def define(self) -> str:
        return CGAbstractMethod.define(self)

    def definition_body(self) -> CGThing:
        return CGGeneric(
            "define_dom_interface"
            f"(cx, global, ProtoOrIfaceIndex::{self.variant}({self.id}),"
            "CreateInterfaceObjects::<D>, ConstructorEnabled::<D>)"
        )


def needCx(returnType: IDLType | None, arguments: Iterable[IDLArgument | FakeArgument], considerTypes: bool) -> bool:
    return (considerTypes
            and (typeNeedsCx(returnType, True)
                 or any(typeNeedsCx(a.type) for a in arguments)))


class CGCallGenerator(CGThing):
    """
    A class to generate an actual call to a C++ object.  Assumes that the C++
    object is stored in a variable whose name is given by the |object| argument.

    errorResult should be a string for the value to return in case of an
    exception from the native code, or None if no error reporting is needed.
    """
    def __init__(self,
                 errorResult: str | None,
                 arguments: list[tuple[IDLArgument | FakeArgument, str]],
                 argsPre: list[str],
                 returnType: IDLType | None,
                 extendedAttributes: list[str],
                 descriptor: Descriptor,
                 nativeMethodName: str,
                 static: bool,
                 object: str = "this",
                 hasCEReactions: bool = False
                 ) -> None:
        CGThing.__init__(self)

        assert errorResult is None or isinstance(errorResult, str)

        isFallible = errorResult is not None

        result = getRetvalDeclarationForType(returnType, descriptor)
        if returnType and returnTypeNeedsOutparam(returnType):
            rootType = result
            result = CGGeneric("()")
        else:
            rootType = None

        if isFallible:
            result = CGWrapper(result, pre="Result<", post=", Error>")

        args = CGList([CGGeneric(arg) for arg in argsPre], ", ")
        for (a, name) in arguments:
            # XXXjdm Perhaps we should pass all nontrivial types by borrowed pointer
            if a.type.isDictionary() and not type_needs_tracing(a.type):
                name = f"&{name}"
            args.append(CGGeneric(name))

        needsCx = needCx(returnType, (a for (a, _) in arguments), True)

        if "cx" not in argsPre and needsCx:
            args.prepend(CGGeneric("cx"))
        if nativeMethodName in descriptor.inRealmMethods:
            args.append(CGGeneric("InRealm::already(&AlreadyInRealm::assert_for_cx(cx))"))
        if nativeMethodName in descriptor.canGcMethods:
            args.append(CGGeneric("CanGc::note()"))
        if rootType:
            args.append(CGGeneric("retval.handle_mut()"))

        # Build up our actual call
        self.cgRoot = CGList([], "\n")

        if rootType:
            self.cgRoot.append(CGList([
                CGGeneric("rooted!(in(*cx) let mut retval: "),
                rootType,
                CGGeneric(");"),
            ]))

        call = CGGeneric(nativeMethodName)
        if static:
            call = CGWrapper(call, pre=f"<D::{MakeNativeName(descriptor.interface.identifier.name)}>::")
        else:
            call = CGWrapper(call, pre=f"{object}.")
        call = CGList([call, CGWrapper(args, pre="(", post=")")])

        if hasCEReactions:
            self.cgRoot.append(CGGeneric("<D as DomHelpers<D>>::push_new_element_queue();\n"))

        self.cgRoot.append(CGList([
            CGGeneric("let result: "),
            result,
            CGGeneric(" = "),
            call,
            CGGeneric(";"),
        ]))

        if hasCEReactions:
            self.cgRoot.append(CGGeneric("<D as DomHelpers<D>>::pop_current_element_queue(CanGc::note());\n"))

        if isFallible:
            if static:
                glob = "global.upcast::<D::GlobalScope>()"
            else:
                glob = "&this.global_(InRealm::already(&AlreadyInRealm::assert_for_cx(cx)))"

            self.cgRoot.append(CGGeneric(
                "let result = match result {\n"
                "    Ok(result) => result,\n"
                "    Err(e) => {\n"
                f"        <D as DomHelpers<D>>::throw_dom_exception(cx, {glob}, e, CanGc::note());\n"
                f"        return{errorResult};\n"
                "    },\n"
                "};"))

    def define(self) -> str:
        return self.cgRoot.define()


class CGPerSignatureCall(CGThing):
    """
    This class handles the guts of generating code for a particular
    call signature.  A call signature consists of four things:

    1) A return type, which can be None to indicate that there is no
       actual return value (e.g. this is an attribute setter) or an
       IDLType if there's an IDL type involved (including |void|).
    2) An argument list, which is allowed to be empty.
    3) A name of a native method to call.
    4) Whether or not this method is static.

    We also need to know whether this is a method or a getter/setter
    to do error reporting correctly.

    The idlNode parameter can be either a method or an attr. We can query
    |idlNode.identifier| in both cases, so we can be agnostic between the two.
    """
    # XXXbz For now each entry in the argument list is either an
    # IDLArgument or a FakeArgument, but longer-term we may want to
    # have ways of flagging things like JSContext* or optional_argc in
    # there.

    def __init__(self,
                 returnType: IDLType | None,
                 argsPre: list[str],
                 arguments: list[IDLArgument | FakeArgument],
                 nativeMethodName: str,
                 static: bool,
                 descriptor: Descriptor,
                 idlNode: IDLInterfaceMember,
                 argConversionStartsAt: int = 0,
                 getter: bool = False,
                 setter: bool = False) -> None:
        CGThing.__init__(self)
        self.returnType = returnType
        self.descriptor = descriptor
        self.idlNode = idlNode
        self.extendedAttributes = descriptor.getExtendedAttributes(idlNode,
                                                                   getter=getter,
                                                                   setter=setter)
        self.argsPre = argsPre
        self.arguments = arguments
        self.argCount = len(arguments)
        cgThings: list[CGThing] = []
        cgThings.extend([CGArgumentConverter(arguments[i], i, self.getArgs(),
                                             self.getArgc(), self.descriptor,
                                             invalidEnumValueFatal=not setter) for
                         i in range(argConversionStartsAt, self.argCount)])

        errorResult = None
        if self.isFallible():
            errorResult = " false"

        if isinstance(idlNode, IDLMethod) and idlNode.isMethod() and idlNode.isMaplikeOrSetlikeOrIterableMethod():
            assert idlNode.maplikeOrSetlikeOrIterable is not None
            if idlNode.maplikeOrSetlikeOrIterable.isMaplike() or \
               idlNode.maplikeOrSetlikeOrIterable.isSetlike():
                cgThings.append(CGMaplikeOrSetlikeMethodGenerator(descriptor,
                                                                  idlNode.maplikeOrSetlikeOrIterable,
                                                                  idlNode.identifier.name))
            else:
                cgThings.append(CGIterableMethodGenerator(descriptor,
                                                          idlNode.maplikeOrSetlikeOrIterable,
                                                          idlNode.identifier.name))
        else:
            hasCEReactions = idlNode.getExtendedAttribute("CEReactions") or False
            cgThings.append(CGCallGenerator(
                errorResult,
                self.getArguments(), self.argsPre, returnType,
                self.extendedAttributes, descriptor, nativeMethodName,
                static, hasCEReactions=hasCEReactions))

        self.cgRoot = CGList(cgThings, "\n")

    def getArgs(self) -> str:
        return "args" if self.argCount > 0 else ""

    def getArgc(self) -> str:
        return "argc"

    def getArguments(self) -> list[tuple[IDLArgument | FakeArgument, str]]:
        return [(a, process_arg(f"arg{i}", a)) for (i, a) in enumerate(self.arguments)]

    def isFallible(self) -> bool:
        return 'infallible' not in self.extendedAttributes

    def wrap_return_value(self) -> str:
        resultName = "result"
        # Maplike methods have `any` return values in WebIDL, but our internal bindings
        # use stronger types so we need to exclude them from being handled like other
        # generated code.
        if returnTypeNeedsOutparam(self.returnType) and (
           not (isinstance(self.idlNode, IDLMethod) and self.idlNode.isMethod() and self.idlNode.isMaplikeOrSetlikeOrIterableMethod())):
            resultName = "retval"
        return wrapForType(
            'MutableHandleValue::from_raw(args.rval())',
            result=resultName,
            successCode='return true;',
        )

    def define(self) -> str:
        return f"{self.cgRoot.define()}\n{self.wrap_return_value()}"


class CGSwitch(CGList):
    """
    A class to generate code for a switch statement.

    Takes three constructor arguments: an expression, a list of cases,
    and an optional default.

    Each case is a CGCase.  The default is a CGThing for the body of
    the default case, if any.
    """
    def __init__(self, expression: str, cases: list[CGThing], default: CGThing | None = None) -> None:
        CGList.__init__(self, [CGIndenter(c) for c in cases], "\n")
        self.prepend(CGWrapper(CGGeneric(expression),
                               pre="match ", post=" {"))
        if default is not None:
            self.append(
                CGIndenter(
                    CGWrapper(
                        CGIndenter(default),
                        pre="_ => {\n",
                        post="\n}"
                    )
                )
            )

        self.append(CGGeneric("}"))


class CGCase(CGList):
    """
    A class to generate code for a case statement.

    Takes three constructor arguments: an expression, a CGThing for
    the body (allowed to be None if there is no body), and an optional
    argument (defaulting to False) for whether to fall through.
    """
    def __init__(self, expression: str, body: CGThing, fallThrough: bool = False) -> None:
        CGList.__init__(self, [], "\n")
        self.append(CGWrapper(CGGeneric(expression), post=" => {"))
        bodyList = CGList([body], "\n")
        if fallThrough:
            raise TypeError("fall through required but unsupported")
            # bodyList.append(CGGeneric('panic!("fall through unsupported"); /* Fall through */'))
        self.append(CGIndenter(bodyList))
        self.append(CGGeneric("}"))


class CGGetterCall(CGPerSignatureCall):
    """
    A class to generate a native object getter call for a particular IDL
    getter.
    """
    def __init__(self, argsPre: list[str], returnType: IDLType | None, nativeMethodName: str, descriptor: Descriptor, attr: IDLAttribute) -> None:
        CGPerSignatureCall.__init__(self, returnType, argsPre, [],
                                    nativeMethodName, attr.isStatic(), descriptor,
                                    attr, getter=True)


class FakeArgument():
    """
    A class that quacks like an IDLArgument.  This is used to make
    setters look like method calls or for special operations.
    """
    def __init__(self, type: IDLType, interfaceMember: IDLInterfaceMember, allowTreatNonObjectAsNull: bool = False) -> None:
        self.type = type
        self.optional = False
        self.variadic = False
        self.defaultValue = None
        self._allowTreatNonObjectAsNull = allowTreatNonObjectAsNull

    def allowTreatNonCallableAsNull(self) -> bool:
        return self._allowTreatNonObjectAsNull

    @property
    def identifier(self) -> Any:
        raise NotImplementedError("FakeArgument identifier has not been implemented")

class CGSetterCall(CGPerSignatureCall):
    """
    A class to generate a native object setter call for a particular IDL
    setter.
    """
    def __init__(self, argsPre: list[str], argType: IDLType, nativeMethodName: str, descriptor: Descriptor, attr: IDLAttribute) -> None:
        CGPerSignatureCall.__init__(self, None, argsPre,
                                    [FakeArgument(argType, attr, allowTreatNonObjectAsNull=True)],
                                    nativeMethodName, attr.isStatic(), descriptor, attr,
                                    setter=True)

    def wrap_return_value(self) -> str:
        # We have no return value
        return "\ntrue"

    def getArgc(self) -> str:
        return "1"


class CGAbstractStaticBindingMethod(CGAbstractMethod):
    """
    Common class to generate the JSNatives for all our static methods, getters
    and setters.  This will generate the function declaration and unwrap the
    global object.  Subclasses are expected to override the generate_code
    function to do the rest of the work.  This function should return a
    CGThing which is already properly indented.
    """
    def __init__(self, descriptor: Descriptor, name: str, templateArgs: list[str] | None = None) -> None:
        args = [
            Argument('*mut JSContext', 'cx'),
            Argument('libc::c_uint', 'argc'),
            Argument('*mut JSVal', 'vp'),
        ]
        CGAbstractMethod.__init__(self, descriptor, name, "bool", args, extern=True, templateArgs=templateArgs)
        self.exposureSet = descriptor.interface.exposureSet

    def definition_body(self) -> CGThing:
        preamble = """\
let args = CallArgs::from_vp(vp, argc);
let global = D::GlobalScope::from_object(args.callee());
"""
        if len(self.exposureSet) == 1:
            preamble += f"let global = DomRoot::downcast::<D::{list(self.exposureSet)[0]}>(global).unwrap();\n"
        return CGList([CGGeneric(preamble), self.generate_code()])

    def generate_code(self) -> CGThing:
        raise NotImplementedError


def GetConstructorNameForReporting(descriptor: Descriptor, ctor: IDLConstructor) -> str:
    # Figure out the name of our constructor for reporting purposes.
    # For unnamed webidl constructors, identifier.name is "constructor" but
    # the name JS sees is the interface name; for legacy factory functions
    # identifier.name is the actual name.
    ctorName = ctor.identifier.name
    if ctorName == "constructor":
        return descriptor.interface.identifier.name
    return ctorName


class CGSpecializedMethod(CGAbstractExternMethod):
    """
    A class for generating the C++ code for a specialized method that the JIT
    can call with lower overhead.
    """
    def __init__(self, descriptor: Descriptor, method: IDLMethod) -> None:
        self.method = method
        name = method.identifier.name
        args = [Argument('*mut JSContext', 'cx'),
                Argument('RawHandleObject', '_obj'),
                Argument('*mut libc::c_void', 'this'),
                Argument('*const JSJitMethodCallArgs', 'args')]
        CGAbstractExternMethod.__init__(self, descriptor, name, 'bool', args, templateArgs=["D: DomTypes"])

    def definition_body(self) -> CGThing:
        nativeName = CGSpecializedMethod.makeNativeName(self.descriptor,
                                                        self.method)
        return CGWrapper(CGMethodCall([], nativeName, self.method.isStatic(),
                                      self.descriptor, self.method),
                         pre="let cx = SafeJSContext::from_ptr(cx);\n"
                             f"let this = &*(this as *const {self.descriptor.concreteType});\n"
                             "let args = &*args;\n"
                             "let argc = args.argc_;\n")

    @staticmethod
    def makeNativeName(descriptor: Descriptor, method: IDLMethod) -> str:
        if method.underlyingAttr:
            return CGSpecializedGetter.makeNativeName(descriptor, method.underlyingAttr)
        name = method.identifier.name
        nativeName = descriptor.binaryNameFor(name, method.isStatic())
        if nativeName == name:
            nativeName = descriptor.internalNameFor(name)
        return MakeNativeName(nativeName)


# https://searchfox.org/mozilla-central/rev/b220e40ff2ee3d10ce68e07d8a8a577d5558e2a2/dom/bindings/Codegen.py#10655-10684
class CGMethodPromiseWrapper(CGAbstractExternMethod):
    """
    A class for generating a wrapper around another method that will
    convert exceptions to promises.
    """

    def __init__(self, descriptor: Descriptor, methodToWrap: IDLMethod) -> None:
        self.method = methodToWrap
        name = CGMethodPromiseWrapper.makeNativeName(descriptor, self.method)
        args = [Argument('*mut JSContext', 'cx'),
                Argument('RawHandleObject', '_obj'),
                Argument('*mut libc::c_void', 'this'),
                Argument('*const JSJitMethodCallArgs', 'args')]
        CGAbstractExternMethod.__init__(self, descriptor, name, 'bool', args, templateArgs=["D: DomTypes"])

    def definition_body(self) -> CGThing:
        return CGGeneric(fill(
            """
            let ok = ${methodName}::<D>(${args});
            if ok {
              return true;
            }
            return exception_to_promise(cx, (*args).rval(), CanGc::note());
            """,
            methodName=self.method.identifier.name,
            args=", ".join(arg.name for arg in self.args),
        ))

    @staticmethod
    def makeNativeName(descriptor: Descriptor, m: IDLMethod) -> str:
        return f"{m.identifier.name}_promise_wrapper"


# https://searchfox.org/mozilla-central/rev/7279a1df13a819be254fd4649e07c4ff93e4bd45/dom/bindings/Codegen.py#11390-11419
class CGGetterPromiseWrapper(CGAbstractExternMethod):
    """
    A class for generating a wrapper around another getter that will
    convert exceptions to promises.
    """

    def __init__(self, descriptor: Descriptor, methodToWrap: IDLMethod) -> None:
        self.method = methodToWrap
        name = CGGetterPromiseWrapper.makeNativeName(descriptor, self.method)
        self.method_call = CGGetterPromiseWrapper.makeOrigName(descriptor, self.method)
        args = [Argument('*mut JSContext', 'cx'),
                Argument('RawHandleObject', '_obj'),
                Argument('*mut libc::c_void', 'this'),
                Argument('JSJitGetterCallArgs', 'args')]
        CGAbstractExternMethod.__init__(self, descriptor, name, 'bool', args, templateArgs=["D: DomTypes"])

    def definition_body(self) -> CGThing:
        return CGGeneric(fill(
            """
            let ok = ${methodName}::<D>(${args});
            if ok {
              return true;
            }
            return exception_to_promise(cx, args.rval(), CanGc::note());
            """,
            methodName=self.method_call,
            args=", ".join(arg.name for arg in self.args),
        ))

    @staticmethod
    def makeOrigName(descriptor: Descriptor, m: IDLInterfaceMember) -> str:
        return f'get_{descriptor.internalNameFor(m.identifier.name)}'

    @staticmethod
    def makeNativeName(descriptor: Descriptor, m: IDLInterfaceMember) -> str:
        return f"{CGGetterPromiseWrapper.makeOrigName(descriptor, m)}_promise_wrapper"


class CGDefaultToJSONMethod(CGSpecializedMethod):
    def __init__(self, descriptor: Descriptor, method: IDLMethod) -> None:
        assert method.isDefaultToJSON()
        CGSpecializedMethod.__init__(self, descriptor, method)

    def definition_body(self) -> CGThing:
        ret = dedent("""
            use crate::inheritance::HasParent;
            rooted!(in(cx) let result = JS_NewPlainObject(cx));
            if result.is_null() {
              return false;
            }
            """)

        jsonDescriptors = [self.descriptor]
        interface = self.descriptor.interface.parent
        while interface:
            descriptor = self.descriptor.getDescriptor(interface.identifier.name)
            if descriptor.hasDefaultToJSON:
                jsonDescriptors.append(descriptor)
            interface = interface.parent

        parents = len(jsonDescriptors) - 1
        form = """
             if !${parentclass}CollectJSONAttributes::<D>(cx, _obj, this, result.handle()) {
                 return false;
             }
             """

        # Iterate the array in reverse: oldest ancestor first
        for descriptor in jsonDescriptors[:0:-1]:
            ret += fill(form, parentclass=f"{toBindingNamespace(descriptor.name)}::")
            parents -= 1
        ret += fill(form, parentclass="")
        ret += ('(*args).rval().set(ObjectValue(*result));\n'
                'true\n')
        return CGGeneric(ret)


class CGStaticMethod(CGAbstractStaticBindingMethod):
    """
    A class for generating the Rust code for an IDL static method.
    """
    def __init__(self, descriptor: Descriptor, method: IDLMethod) -> None:
        self.method = method
        name = descriptor.binaryNameFor(method.identifier.name, True)
        CGAbstractStaticBindingMethod.__init__(self, descriptor, name, templateArgs=["D: DomTypes"])

    def generate_code(self) -> CGThing:
        nativeName = CGSpecializedMethod.makeNativeName(self.descriptor,
                                                        self.method)
        safeContext = CGGeneric("let cx = SafeJSContext::from_ptr(cx);\n")
        setupArgs = CGGeneric("let args = CallArgs::from_vp(vp, argc);\n")
        call = CGMethodCall(["&global"], nativeName, True, self.descriptor, self.method)
        return CGList([safeContext, setupArgs, call])


class CGSpecializedGetter(CGAbstractExternMethod):
    """
    A class for generating the code for a specialized attribute getter
    that the JIT can call with lower overhead.
    """
    def __init__(self, descriptor: Descriptor, attr: IDLAttribute) -> None:
        self.attr = attr
        name = f'get_{descriptor.internalNameFor(attr.identifier.name)}'
        args = [Argument('*mut JSContext', 'cx'),
                Argument('RawHandleObject', '_obj'),
                Argument('*mut libc::c_void', 'this'),
                Argument('JSJitGetterCallArgs', 'args')]
        CGAbstractExternMethod.__init__(self, descriptor, name, "bool", args, templateArgs=["D: DomTypes"])

    def definition_body(self) -> CGThing:
        nativeName = CGSpecializedGetter.makeNativeName(self.descriptor,
                                                        self.attr)

        return CGWrapper(CGGetterCall([], self.attr.type, nativeName,
                                      self.descriptor, self.attr),
                         pre="let cx = SafeJSContext::from_ptr(cx);\n"
                             f"let this = &*(this as *const {self.descriptor.concreteType});\n")

    @staticmethod
    def makeNativeName(descriptor: Descriptor, attr: IDLAttribute) -> str:
        name = attr.identifier.name
        nativeName = descriptor.binaryNameFor(name, attr.isStatic())
        if nativeName == name:
            nativeName = descriptor.internalNameFor(name)
        nativeName = MakeNativeName(nativeName)
        infallible = ('infallible' in
                      descriptor.getExtendedAttributes(attr, getter=True))
        if attr.type.nullable() or not infallible:
            return f"Get{nativeName}"

        return nativeName


class CGStaticGetter(CGAbstractStaticBindingMethod):
    """
    A class for generating the C++ code for an IDL static attribute getter.
    """
    def __init__(self, descriptor: Descriptor, attr: IDLAttribute) -> None:
        self.attr = attr
        name = f'get_{attr.identifier.name}'
        CGAbstractStaticBindingMethod.__init__(self, descriptor, name, templateArgs=["D: DomTypes"])

    def generate_code(self) -> CGThing:
        nativeName = CGSpecializedGetter.makeNativeName(self.descriptor,
                                                        self.attr)
        safeContext = CGGeneric("let cx = SafeJSContext::from_ptr(cx);\n")
        setupArgs = CGGeneric("let args = CallArgs::from_vp(vp, argc);\n")
        call = CGGetterCall(["&global"], self.attr.type, nativeName, self.descriptor,
                            self.attr)
        return CGList([safeContext, setupArgs, call])


class CGSpecializedSetter(CGAbstractExternMethod):
    """
    A class for generating the code for a specialized attribute setter
    that the JIT can call with lower overhead.
    """
    def __init__(self, descriptor: Descriptor, attr: IDLAttribute) -> None:
        self.attr = attr
        name = f'set_{descriptor.internalNameFor(attr.identifier.name)}'
        args = [Argument('*mut JSContext', 'cx'),
                Argument('RawHandleObject', 'obj'),
                Argument('*mut libc::c_void', 'this'),
                Argument('JSJitSetterCallArgs', 'args')]
        CGAbstractExternMethod.__init__(self, descriptor, name, "bool", args, templateArgs=["D: DomTypes"])

    def definition_body(self) -> CGThing:
        nativeName = CGSpecializedSetter.makeNativeName(self.descriptor,
                                                        self.attr)
        return CGWrapper(
            CGSetterCall([], self.attr.type, nativeName, self.descriptor, self.attr),
            pre=("let cx = SafeJSContext::from_ptr(cx);\n"
                 f"let this = &*(this as *const {self.descriptor.concreteType});\n")
        )

    @staticmethod
    def makeNativeName(descriptor: Descriptor, attr: IDLAttribute) -> str:
        name = attr.identifier.name
        nativeName = descriptor.binaryNameFor(name, attr.isStatic())
        if nativeName == name:
            nativeName = descriptor.internalNameFor(name)
        return f"Set{MakeNativeName(nativeName)}"


class CGStaticSetter(CGAbstractStaticBindingMethod):
    """
    A class for generating the C++ code for an IDL static attribute setter.
    """
    def __init__(self, descriptor: Descriptor, attr: IDLAttribute) -> None:
        self.attr = attr
        name = f'set_{attr.identifier.name}'
        CGAbstractStaticBindingMethod.__init__(self, descriptor, name, templateArgs=["D: DomTypes"])

    def generate_code(self) -> CGThing:
        nativeName = CGSpecializedSetter.makeNativeName(self.descriptor,
                                                        self.attr)
        safeContext = CGGeneric("let cx = SafeJSContext::from_ptr(cx);\n")
        checkForArg = CGGeneric(
            "let args = CallArgs::from_vp(vp, argc);\n"
            "if argc == 0 {\n"
            f'    throw_type_error(*cx, "Not enough arguments to {self.attr.identifier.name} setter.");\n'
            "    return false;\n"
            "}")
        call = CGSetterCall(["&global"], self.attr.type, nativeName, self.descriptor,
                            self.attr)
        return CGList([safeContext, checkForArg, call])


class CGSpecializedForwardingSetter(CGSpecializedSetter):
    """
    A class for generating the code for an IDL attribute forwarding setter.
    """
    def __init__(self, descriptor: Descriptor, attr: IDLAttribute) -> None:
        CGSpecializedSetter.__init__(self, descriptor, attr)

    def definition_body(self) -> CGThing:
        attrName = self.attr.identifier.name
        forwardToAttr = self.attr.getExtendedAttribute("PutForwards")
        assert forwardToAttr is not None
        forwardToAttrName = forwardToAttr[0]
        # JS_GetProperty and JS_SetProperty can only deal with ASCII
        assert all(ord(c) < 128 for c in attrName)
        assert all(ord(c) < 128 for c in forwardToAttrName)
        return CGGeneric(f"""
let cx = SafeJSContext::from_ptr(cx);
rooted!(in(*cx) let mut v = UndefinedValue());
if !JS_GetProperty(*cx, HandleObject::from_raw(obj), {str_to_cstr_ptr(attrName)}, v.handle_mut()) {{
    return false;
}}
if !v.is_object() {{
    throw_type_error(*cx, "Value.{attrName} is not an object.");
    return false;
}}
rooted!(in(*cx) let target_obj = v.to_object());
JS_SetProperty(*cx, target_obj.handle(), {str_to_cstr_ptr(forwardToAttrName)}, HandleValue::from_raw(args.get(0)))
""")


class CGSpecializedReplaceableSetter(CGSpecializedSetter):
    """
    A class for generating the code for an IDL replaceable attribute setter.
    """
    def __init__(self, descriptor: Descriptor, attr: IDLAttribute) -> None:
        CGSpecializedSetter.__init__(self, descriptor, attr)

    def definition_body(self) -> CGThing:
        assert self.attr.readonly
        name = str_to_cstr_ptr(self.attr.identifier.name)
        # JS_DefineProperty can only deal with ASCII.
        assert all(ord(c) < 128 for c in name)
        return CGGeneric(f"""
JS_DefineProperty(cx, HandleObject::from_raw(obj), {name},
                  HandleValue::from_raw(args.get(0)), JSPROP_ENUMERATE as u32)""")


class CGMemberJITInfo(CGThing):
    """
    A class for generating the JITInfo for a property that points to
    our specialized getter and setter.
    """
    def __init__(self, descriptor: Descriptor, member: IDLInterfaceMember) -> None:
        self.member = member
        self.descriptor = descriptor

    def defineJitInfo(self, infoName: str, opName: str, opType: str, infallible: bool, movable: bool,
                      aliasSet: str, alwaysInSlot: bool, lazilyInSlot: bool, slotIndex: str,
                      returnTypes: list[IDLType], args: list[IDLArgument] | None) -> str:
        """
        aliasSet is a JSJitInfo_AliasSet value, without the "JSJitInfo_AliasSet::" bit.

        args is None if we don't want to output argTypes for some
        reason (e.g. we have overloads or we're not a method) and
        otherwise an iterable of the arguments for this method.
        """
        assert not movable or aliasSet != "AliasEverything"  # Can't move write-aliasing things
        assert not alwaysInSlot or movable  # Things always in slots had better be movable

        def jitInfoInitializer(isTypedMethod: bool) -> str:
            initializer = fill(
                """
                JSJitInfo {
                    __bindgen_anon_1: JSJitInfo__bindgen_ty_1 {
                        ${opKind}: ${opValue}
                    },
                    __bindgen_anon_2: JSJitInfo__bindgen_ty_2 {
                        protoID: PrototypeList::ID::${name} as u16,
                    },
                    __bindgen_anon_3: JSJitInfo__bindgen_ty_3 { depth: ${depth} },
                    _bitfield_align_1: [],
                    _bitfield_1: __BindgenBitfieldUnit::new(
                        new_jsjitinfo_bitfield_1!(
                            JSJitInfo_OpType::${opType} as u8,
                            JSJitInfo_AliasSet::${aliasSet} as u8,
                            JSValueType::${returnType} as u8,
                            ${isInfallible},
                            ${isMovable},
                            ${isEliminatable},
                            ${isAlwaysInSlot},
                            ${isLazilyCachedInSlot},
                            ${isTypedMethod},
                            ${slotIndex},
                        ).to_ne_bytes()
                    ),
                }
                """,
                opValue=f"Some({opName}::<D>)",
                name=self.descriptor.name,
                depth=str(self.descriptor.interface.inheritanceDepth()),
                opType=opType,
                opKind=opType.lower(),
                aliasSet=aliasSet,
                returnType=functools.reduce(CGMemberJITInfo.getSingleReturnType, returnTypes,
                                            ""),
                isInfallible=toStringBool(infallible),
                isMovable=toStringBool(movable),
                # FIXME(nox): https://github.com/servo/servo/issues/10991
                isEliminatable=toStringBool(False),
                isAlwaysInSlot=toStringBool(alwaysInSlot),
                isLazilyCachedInSlot=toStringBool(lazilyInSlot),
                isTypedMethod=toStringBool(isTypedMethod),
                slotIndex=slotIndex)
            return initializer.rstrip()

        if args is not None:
            argTypesArray = f"{infoName}_argTypes"
            argTypes = [CGMemberJITInfo.getJSArgType(arg.type) for arg in args]
            argTypes.append("JSJitInfo_ArgType::ArgTypeListEnd as i32")
            argTypesDecl = f"const {argTypesArray}: [i32; {len(argTypes)}] = [ {', '.join(argTypes)} ];\n"
            return fill(
                """
                $*{argTypesDecl}
                static ${infoName}: ThreadUnsafeOnceLock<JSTypedMethodJitInfo> = ThreadUnsafeOnceLock::new();

                pub(crate) fn init_${infoName}<D: DomTypes>() {
                    ${infoName}.set(JSTypedMethodJitInfo {
                        base: ${jitInfoInit},
                        argTypes: &${argTypes} as *const _ as *const JSJitInfo_ArgType,
                    });
                }
                """,
                argTypesDecl=argTypesDecl,
                infoName=infoName,
                jitInfoInit=indent(jitInfoInitializer(True)),
                argTypes=argTypesArray)

        return f"""
static {infoName}: ThreadUnsafeOnceLock<JSJitInfo> = ThreadUnsafeOnceLock::new();

pub(crate) fn init_{infoName}<D: DomTypes>() {{
    {infoName}.set({jitInfoInitializer(False)});
}}"""

    def define(self) -> str:
        if self.member.isAttr():
            assert isinstance(self.member, IDLAttribute)
            internalMemberName = self.descriptor.internalNameFor(self.member.identifier.name)
            getterinfo = f"{internalMemberName}_getterinfo"
            getter = f"get_{internalMemberName}"
            if self.member.type.isPromise():
                getter = CGGetterPromiseWrapper.makeNativeName(self.descriptor, self.member)
            getterinfal = "infallible" in self.descriptor.getExtendedAttributes(self.member, getter=True)

            movable = self.mayBeMovable() and getterinfal
            aliasSet = self.aliasSet()

            isAlwaysInSlot = self.member.getExtendedAttribute("StoreInSlot") or False
            if self.member.slotIndices is not None:
                assert isAlwaysInSlot or self.member.getExtendedAttribute("Cached")
                isLazilyCachedInSlot = not isAlwaysInSlot
                # pyrefly: ignore  # unknown-name
                slotIndex = memberReservedSlot(self.member)  # noqa: F821 FIXME: memberReservedSlot is not defined
                # We'll statically assert that this is not too big in
                # CGUpdateMemberSlotsMethod, in the case when
                # isAlwaysInSlot is true.
            else:
                isLazilyCachedInSlot = False
                slotIndex = "0"

            result = self.defineJitInfo(getterinfo, getter, "Getter",
                                        getterinfal, movable, aliasSet,
                                        isAlwaysInSlot, isLazilyCachedInSlot,
                                        slotIndex,
                                        [self.member.type], None)
            if (not self.member.readonly or self.member.getExtendedAttribute("PutForwards")
                    or self.member.getExtendedAttribute("Replaceable")):
                setterinfo = f"{internalMemberName}_setterinfo"
                setter = f"set_{internalMemberName}"
                # Setters are always fallible, since they have to do a typed unwrap.
                result += self.defineJitInfo(setterinfo, setter, "Setter",
                                             False, False, "AliasEverything",
                                             False, False, "0",
                                             # pyrefly: ignore  # missing-attribute
                                             [BuiltinTypes[IDLBuiltinType.Types.undefined]],
                                             None)
            return result
        if self.member.isMethod():
            assert isinstance(self.member, IDLMethod)
            methodinfo = f"{self.member.identifier.name}_methodinfo"
            method = f"{self.member.identifier.name}"
            if self.member.returnsPromise():
                method = CGMethodPromiseWrapper.makeNativeName(self.descriptor, self.member)

            # Methods are infallible if they are infallible, have no arguments
            # to unwrap, and have a return type that's infallible to wrap up for
            # return.
            sigs = self.member.signatures()
            if len(sigs) != 1:
                # Don't handle overloading. If there's more than one signature,
                # one of them must take arguments.
                methodInfal = False
                args = None
                movable = False
            else:
                sig = sigs[0]
                # For methods that affect nothing, it's OK to set movable to our
                # notion of infallible on the C++ side, without considering
                # argument conversions, since argument conversions that can
                # reliably throw would be effectful anyway and the jit doesn't
                # move effectful things.
                hasInfallibleImpl = "infallible" in self.descriptor.getExtendedAttributes(self.member)
                movable = self.mayBeMovable() and hasInfallibleImpl
                # XXXbz can we move the smarts about fallibility due to arg
                # conversions into the JIT, using our new args stuff?
                if (len(sig[1]) != 0):
                    # We have arguments or our return-value boxing can fail
                    methodInfal = False
                else:
                    methodInfal = hasInfallibleImpl
                # For now, only bother to output args if we're side-effect-free.
                if self.member.affects == "Nothing":
                    args = sig[1]
                else:
                    args = None

            aliasSet = self.aliasSet()
            result = self.defineJitInfo(methodinfo, method, "Method",
                                        methodInfal, movable, aliasSet,
                                        False, False, "0",
                                        [s[0] for s in sigs], args)
            return result
        raise TypeError("Illegal member type to CGPropertyJITInfo")

    def mayBeMovable(self) -> bool:
        """
        Returns whether this attribute or method may be movable, just
        based on Affects/DependsOn annotations.
        """
        affects = self.member.affects
        dependsOn = self.member.dependsOn
        assert affects in IDLInterfaceMember.AffectsValues
        assert dependsOn in IDLInterfaceMember.DependsOnValues
        # Things that are DependsOn=DeviceState are not movable, because we
        # don't want them coalesced with each other or loop-hoisted, since
        # their return value can change even if nothing is going on from our
        # point of view.
        return (affects == "Nothing"
                and (dependsOn != "Everything" and dependsOn != "DeviceState"))

    def aliasSet(self) -> str:
        """Returns the alias set to store in the jitinfo.  This may not be the
        effective alias set the JIT uses, depending on whether we have enough
        information about our args to allow the JIT to prove that effectful
        argument conversions won't happen.

        """
        dependsOn = self.member.dependsOn
        assert dependsOn in IDLInterfaceMember.DependsOnValues

        if dependsOn == "Nothing" or dependsOn == "DeviceState":
            assert self.member.affects == "Nothing"
            return "AliasNone"

        if dependsOn == "DOMState":
            assert self.member.affects == "Nothing"
            return "AliasDOMSets"

        return "AliasEverything"

    @staticmethod
    def getJSReturnTypeTag(t: IDLType) -> str:
        if t.nullable():
            # Sometimes it might return null, sometimes not
            return "JSVAL_TYPE_UNKNOWN"
        if t.isUndefined():
            # No return, every time
            return "JSVAL_TYPE_UNDEFINED"
        if t.isSequence():
            return "JSVAL_TYPE_OBJECT"
        if t.isRecord():
            return "JSVAL_TYPE_OBJECT"
        if t.isPromise():
            return "JSVAL_TYPE_OBJECT"
        if t.isGeckoInterface():
            return "JSVAL_TYPE_OBJECT"
        if t.isString():
            return "JSVAL_TYPE_STRING"
        if t.isEnum():
            return "JSVAL_TYPE_STRING"
        if t.isCallback():
            return "JSVAL_TYPE_OBJECT"
        if t.isAny():
            # The whole point is to return various stuff
            return "JSVAL_TYPE_UNKNOWN"
        if t.isObject():
            return "JSVAL_TYPE_OBJECT"
        if t.isSpiderMonkeyInterface():
            return "JSVAL_TYPE_OBJECT"
        if t.isUnion():
            u = t.unroll()
            assert isinstance(u, IDLUnionType)
            if u.hasNullableType:
                # Might be null or not
                return "JSVAL_TYPE_UNKNOWN"
            assert u.flatMemberTypes is not None
            return functools.reduce(CGMemberJITInfo.getSingleReturnType,
                                    u.flatMemberTypes, "")
        if t.isDictionary():
            return "JSVAL_TYPE_OBJECT"
        if not t.isPrimitive():
            raise TypeError(f"No idea what type {t} is.")
        tag = t.tag()
        if tag == IDLType.Tags.bool:
            return "JSVAL_TYPE_BOOLEAN"
        if tag in [IDLType.Tags.int8, IDLType.Tags.uint8,
                   IDLType.Tags.int16, IDLType.Tags.uint16,
                   IDLType.Tags.int32]:
            return "JSVAL_TYPE_INT32"
        if tag in [IDLType.Tags.int64, IDLType.Tags.uint64,
                   IDLType.Tags.unrestricted_float, IDLType.Tags.float,
                   IDLType.Tags.unrestricted_double, IDLType.Tags.double]:
            # These all use JS_NumberValue, which can return int or double.
            # But TI treats "double" as meaning "int or double", so we're
            # good to return JSVAL_TYPE_DOUBLE here.
            return "JSVAL_TYPE_DOUBLE"
        if tag != IDLType.Tags.uint32:
            raise TypeError(f"No idea what type {t} is.")
        # uint32 is sometimes int and sometimes double.
        return "JSVAL_TYPE_DOUBLE"

    @staticmethod
    def getSingleReturnType(existingType: str, t: IDLType) -> str:
        type = CGMemberJITInfo.getJSReturnTypeTag(t)
        if existingType == "":
            # First element of the list; just return its type
            return type

        if type == existingType:
            return existingType
        if ((type == "JSVAL_TYPE_DOUBLE"
             and existingType == "JSVAL_TYPE_INT32")
            or (existingType == "JSVAL_TYPE_DOUBLE"
                and type == "JSVAL_TYPE_INT32")):
            # Promote INT32 to DOUBLE as needed
            return "JSVAL_TYPE_DOUBLE"
        # Different types
        return "JSVAL_TYPE_UNKNOWN"

    @staticmethod
    def getJSArgType(t: IDLType) -> str:
        assert not t.isUndefined()
        if t.nullable():
            # Sometimes it might return null, sometimes not
            assert isinstance(t, IDLNullableType)
            return f"JSJitInfo_ArgType::Null as i32 | {CGMemberJITInfo.getJSArgType(t.inner)}"
        if t.isSequence():
            return "JSJitInfo_ArgType::Object as i32"
        if t.isGeckoInterface():
            return "JSJitInfo_ArgType::Object as i32"
        if t.isString():
            return "JSJitInfo_ArgType::String as i32"
        if t.isEnum():
            return "JSJitInfo_ArgType::String as i32"
        if t.isCallback():
            return "JSJitInfo_ArgType::Object as i32"
        if t.isAny():
            # The whole point is to return various stuff
            return "JSJitInfo_ArgType::Any as i32"
        if t.isObject():
            return "JSJitInfo_ArgType::Object as i32"
        if t.isSpiderMonkeyInterface():
            return "JSJitInfo_ArgType::Object as i32"
        if t.isUnion():
            u = t.unroll()
            assert isinstance(u, IDLUnionType) and u.flatMemberTypes is not None
            type = "JSJitInfo_ArgType::Null as i32" if u.hasNullableType else ""
            return functools.reduce(CGMemberJITInfo.getSingleArgType,
                                    u.flatMemberTypes, type)
        if t.isDictionary():
            return "JSJitInfo_ArgType::Object as i32"
        if not t.isPrimitive():
            raise TypeError(f"No idea what type {t} is.")
        tag = t.tag()
        if tag == IDLType.Tags.bool:
            return "JSJitInfo_ArgType::Boolean as i32"
        if tag in [IDLType.Tags.int8, IDLType.Tags.uint8,
                   IDLType.Tags.int16, IDLType.Tags.uint16,
                   IDLType.Tags.int32]:
            return "JSJitInfo_ArgType::Integer as i32"
        if tag in [IDLType.Tags.int64, IDLType.Tags.uint64,
                   IDLType.Tags.unrestricted_float, IDLType.Tags.float,
                   IDLType.Tags.unrestricted_double, IDLType.Tags.double]:
            # These all use JS_NumberValue, which can return int or double.
            # But TI treats "double" as meaning "int or double", so we're
            # good to return JSVAL_TYPE_DOUBLE here.
            return "JSJitInfo_ArgType::Double as i32"
        if tag != IDLType.Tags.uint32:
            raise TypeError(f"No idea what type {t} is.")
        # uint32 is sometimes int and sometimes double.
        return "JSJitInfo_ArgType::Double as i32"

    @staticmethod
    def getSingleArgType(existingType: str, t: IDLType) -> str:
        type = CGMemberJITInfo.getJSArgType(t)
        if existingType == "":
            # First element of the list; just return its type
            return type

        if type == existingType:
            return existingType
        return f"{existingType} | {type}"


# https://searchfox.org/mozilla-central/rev/9993372dd72daea851eba4600d5750067104bc15/dom/bindings/Codegen.py#12355-12374
class CGStaticMethodJitinfo(CGGeneric):
    """
    A class for generating the JITInfo for a promise-returning static method.
    """

    def __init__(self, method: IDLMethod) -> None:
        CGGeneric.__init__(
            self,
            f"""
            static {method.identifier.name}_methodinfo: ThreadUnsafeOnceLock<JSJitInfo> = ThreadUnsafeOnceLock::new();

            pub(crate) fn init_{method.identifier.name}_methodinfo<D: DomTypes>() {{
                {method.identifier.name}_methodinfo.set(JSJitInfo {{
                    __bindgen_anon_1: JSJitInfo__bindgen_ty_1 {{
                        staticMethod: Some({method.identifier.name}::<D>)
                    }},
                    __bindgen_anon_2: JSJitInfo__bindgen_ty_2 {{
                        protoID: PrototypeList::ID::Last as u16,
                    }},
                    __bindgen_anon_3: JSJitInfo__bindgen_ty_3 {{ depth: 0 }},
                    _bitfield_align_1: [],
                    _bitfield_1: __BindgenBitfieldUnit::new(
                        new_jsjitinfo_bitfield_1!(
                            JSJitInfo_OpType::StaticMethod as u8,
                            JSJitInfo_AliasSet::AliasEverything as u8,
                            JSValueType::JSVAL_TYPE_OBJECT as u8,
                            false,
                            false,
                            false,
                            false,
                            false,
                            false,
                            0,
                        ).to_ne_bytes()
                    ),
                }});
            }}
            """
        )


def getEnumValueName(value: str) -> str:
    # Some enum values can be empty strings.  Others might have weird
    # characters in them.  Deal with the former by returning "_empty",
    # deal with possible name collisions from that by throwing if the
    # enum value is actually "_empty", and throw on any value
    # containing non-ASCII chars for now. Replace all chars other than
    # [0-9A-Za-z_] with '_'.
    if re.match("[^\x20-\x7E]", value):
        raise SyntaxError(f'Enum value "{value}" contains non-ASCII characters')
    if re.match("^[0-9]", value):
        value = '_' + value
    value = re.sub(r'[^0-9A-Za-z_]', '_', value)
    if re.match("^_[A-Z]|__", value):
        raise SyntaxError(f'Enum value "{value}" is reserved by the C++ spec')
    if value == "_empty":
        raise SyntaxError('"_empty" is not an IDL enum value we support yet')
    if value == "":
        return "_empty"
    return MakeNativeName(value)


class CGEnum(CGThing):
    def __init__(self, enum: IDLEnum, config: Configuration) -> None:
        CGThing.__init__(self)

        ident = enum.identifier.name
        enums = ",\n    ".join(map(getEnumValueName, list(enum.values())))
        derives = ["Copy", "Clone", "Debug", "JSTraceable", "MallocSizeOf", "PartialEq"]
        enum_config = config.getEnumConfig(ident)
        extra_derives = enum_config.get('derives', [])
        derives = ', '.join(derives + extra_derives)
        decl = f"""
#[repr(usize)]
#[derive({derives})]
pub enum {ident} {{
    {enums}
}}
"""

        pairs = ",\n    ".join([f'("{val}", super::{ident}::{getEnumValueName(val)})'
                                for val in list(enum.values())])

        inner = f"""
use crate::utils::find_enum_value;
use js::conversions::ConversionResult;
use js::conversions::FromJSValConvertible;
use js::conversions::ToJSValConvertible;
use js::jsapi::JSContext;
use js::rust::HandleValue;
use js::rust::MutableHandleValue;
use js::jsval::JSVal;

pub(crate) const pairs: &[(&str, super::{ident})] = &[
    {pairs},
];

impl super::{ident} {{
    pub fn as_str(&self) -> &'static str {{
        pairs[*self as usize].0
    }}
}}

impl Default for super::{ident} {{
    fn default() -> super::{ident} {{
        pairs[0].1
    }}
}}

impl std::str::FromStr for super::{ident} {{
    type Err = ();

    fn from_str(s: &str) -> Result<Self, Self::Err> {{
        pairs
            .iter()
            .find(|&&(key, _)| s == key)
            .map(|&(_, ev)| ev)
            .ok_or(())
    }}
}}

impl ToJSValConvertible for super::{ident} {{
    unsafe fn to_jsval(&self, cx: *mut JSContext, rval: MutableHandleValue) {{
        pairs[*self as usize].0.to_jsval(cx, rval);
    }}
}}

impl FromJSValConvertible for super::{ident} {{
    type Config = ();
    unsafe fn from_jsval(cx: *mut JSContext, value: HandleValue, _option: ())
                         -> Result<ConversionResult<super::{ident}>, ()> {{
        match find_enum_value(cx, value, pairs) {{
            Err(_) => Err(()),
            Ok((None, search)) => {{
                Ok(ConversionResult::Failure(
                    format!("'{{}}' is not a valid enum value for enumeration '{ident}'.", search).into()
                ))
            }}
            Ok((Some(&value), _)) => Ok(ConversionResult::Success(value)),
        }}
    }}
}}
    """
        self.cgRoot = CGList([
            CGGeneric(decl),
            CGNamespace.build([f"{ident}Values"],
                              CGIndenter(CGGeneric(inner)), public=True),
        ])

    def define(self) -> str:
        return self.cgRoot.define()


def convertConstIDLValueToRust(value: IDLConst) -> str:
    tag = value.type.tag()
    if tag in [IDLType.Tags.int8, IDLType.Tags.uint8,
               IDLType.Tags.int16, IDLType.Tags.uint16,
               IDLType.Tags.int32, IDLType.Tags.uint32,
               IDLType.Tags.int64, IDLType.Tags.uint64,
               IDLType.Tags.unrestricted_float, IDLType.Tags.float,
               IDLType.Tags.unrestricted_double, IDLType.Tags.double]:
        return str(value.value)

    if tag == IDLType.Tags.bool:
        return toStringBool(value.value)

    raise TypeError(f"Const value of unhandled type: {value.type}")


class CGConstant(CGThing):
    def __init__(self, constant: IDLConst) -> None:
        CGThing.__init__(self)
        self.constant = constant

    def define(self) -> str:
        name = self.constant.identifier.name
        value = convertConstIDLValueToRust(self.constant.value)

        tag = self.constant.value.type.tag()
        const_type = builtinNames[self.constant.value.type.tag()]
        # Finite<f32> or Finite<f64> cannot be used un a constant declaration.
        # Remote the Finite type from restricted float and double tag declarations.
        if tag == IDLType.Tags.float:
            const_type = "f32"
        elif tag == IDLType.Tags.double:
            const_type = "f64"

        return f"pub const {name}: {const_type} = {value};\n"


def getUnionTypeTemplateVars(type: IDLType, descriptorProvider: DescriptorProvider) -> dict[str, Any]:
    if type.isGeckoInterface():
        # pyrefly: ignore  # missing-attribute
        name = type.inner.identifier.name
        typeName = descriptorProvider.getDescriptor(name).returnType
    elif type.isEnum():
        # pyrefly: ignore  # missing-attribute
        name = type.inner.identifier.name
        typeName = name
    elif type.isDictionary():
        name = type.name
        typeName = name
        if containsDomInterface(type):
            typeName += "<D>"
    elif type.isSequence() or type.isRecord():
        name = type.name
        inner = getUnionTypeTemplateVars(innerContainerType(type), descriptorProvider)
        typeName = wrapInNativeContainerType(type, CGGeneric(inner["typeName"])).define()
    elif type.isByteString():
        name = type.name
        typeName = "ByteString"
    elif type.isDOMString():
        name = type.name
        typeName = "DOMString"
    elif type.isUSVString():
        name = type.name
        typeName = "USVString"
    elif type.isPrimitive():
        name = type.name
        typeName = builtinNames[type.tag()]
    elif type.isObject():
        name = type.name
        typeName = "Heap<*mut JSObject>"
    elif is_typed_array(type):
        name = type.name
        typeName = f"typedarray::Heap{name}"
    elif type.isCallback():
        name = type.name
        typeName = f"{name}<D>"
    elif type.isUndefined():
        return {
            "name": type.name,
            "typeName": "()",
            "jsConversion": CGGeneric("if value.is_undefined() { Ok(Some(())) } else { Ok(None) }")
        }
    else:
        raise TypeError(f"Can't handle {type} in unions yet")

    info = getJSToNativeConversionInfo(
        type, descriptorProvider, failureCode="return Ok(None);",
        exceptionCode='return Err(());',
        isDefinitelyObject=True,
        isMember="Union")
    template = info.template

    jsConversion = string.Template(template).substitute({
        "val": "value",
    })
    jsConversion = CGWrapper(CGGeneric(jsConversion), pre="Ok(Some(", post="))")

    return {
        "name": name,
        "typeName": typeName,
        "jsConversion": jsConversion,
    }


def traitRequiresManualImpl(name: str, ty: IDLObject) -> bool:
    return name == "Clone" and containsDomInterface(ty)


class CGUnionStruct(CGThing):
    def __init__(self, type: IDLUnionType, descriptorProvider: DescriptorProvider, config: Configuration) -> None:
        assert not type.nullable()
        assert not type.hasNullableType

        CGThing.__init__(self)
        self.type = type
        derivesList = config.getUnionConfig(str(type)).get('derives', [])
        self.manualImpls = list(filter(lambda t: traitRequiresManualImpl(t, type), derivesList))
        self.derives = list(filter(lambda t: not traitRequiresManualImpl(t, type), derivesList))
        self.descriptorProvider = descriptorProvider

        self.generic, self.genericSuffix = genericsForType(self.type)

    def membersNeedTracing(self) -> bool:
        assert self.type.flatMemberTypes is not None
        for t in self.type.flatMemberTypes:
            if type_needs_tracing(t):
                return True
        return False

    def manualImplClone(self, templateVars: list[tuple[dict[str, Any], str]]) -> str:
        arms = [f"            {self.type}::{v['name']}(inner) => "
                f"{self.type}::{v['name']}(inner.clone()),"
                for (v, _) in templateVars]
        arms = "\n".join(arms)
        return f"""
#[allow(clippy::clone_on_copy)]
impl{self.generic} Clone for {self.type}{self.genericSuffix} {{
    fn clone(&self) -> Self {{
        match self {{
{arms}
        }}
    }}
}}
        """

    def manualImpl(self, t: str, templateVars: list[tuple[dict[str, Any], str]]) -> str:
        if t == "Clone":
            return self.manualImplClone(templateVars)
        raise ValueError(f"Don't know how to impl {t} for union")

    def define(self) -> str:
        def getTypeWrapper(t: IDLType) -> str:
            if type_needs_tracing(t):
                return "RootedTraceableBox"
            if t.isCallback():
                return "Rc"
            return ""

        assert self.type.flatMemberTypes is not None

        templateVars = [(getUnionTypeTemplateVars(t, self.descriptorProvider),
                         getTypeWrapper(t)) for t in self.type.flatMemberTypes]
        enumValues = [
            f"    {v['name']}({wrapper}<{v['typeName']}>)," if wrapper else f"    {v['name']}({v['typeName']}),"
            for (v, wrapper) in templateVars
        ]
        enumConversions = [
            f"            {self.type}::{v['name']}(ref inner) => inner.to_jsval(cx, rval),"
            for (v, _) in templateVars
        ]
        joinedEnumValues = "\n".join(enumValues)
        joinedEnumConversions = "\n".join(enumConversions)
        derives = ["JSTraceable"] + self.derives
        manualImpls = "\n".join(map(lambda t: self.manualImpl(t, templateVars), self.manualImpls))
        return f"""
#[derive({", ".join(derives)})]
pub enum {self.type}{self.generic} {{
{joinedEnumValues}
}}

impl{self.generic} ToJSValConvertible for {self.type}{self.genericSuffix} {{
    unsafe fn to_jsval(&self, cx: *mut JSContext, rval: MutableHandleValue) {{
        match *self {{
{joinedEnumConversions}
        }}
    }}
}}

{manualImpls}
"""


class CGUnionConversionStruct(CGThing):
    def __init__(self, type: IDLUnionType, descriptorProvider: DescriptorProvider) -> None:
        assert not type.nullable()
        assert not type.hasNullableType

        CGThing.__init__(self)
        self.type = type
        self.descriptorProvider = descriptorProvider

    def membersNeedTracing(self) -> bool:
        assert self.type.flatMemberTypes is not None
        for t in self.type.flatMemberTypes:
            if type_needs_tracing(t):
                return True
        return False

    def from_jsval(self) -> CGWrapper:
        memberTypes = cast(list[IDLType], self.type.flatMemberTypes)
        names = []
        conversions = []

        def get_name(memberType: IDLType) -> str:
            if self.type.isGeckoInterface():
                # pyrefly: ignore  # missing-attribute
                return memberType.inner.identifier.name

            return memberType.name

        def get_match(name: str) -> str:
            generic = "::<D>" if containsDomInterface(self.type) else ""
            return (
                f"match {self.type}{generic}::TryConvertTo{name}(SafeJSContext::from_ptr(cx), value) {{\n"
                "    Err(_) => return Err(()),\n"
                f"    Ok(Some(value)) => return Ok(ConversionResult::Success({self.type}::{name}(value))),\n"
                "    Ok(None) => (),\n"
                "}\n")

        interfaceMemberTypes = [t for t in memberTypes if t.isNonCallbackInterface()]
        if len(interfaceMemberTypes) > 0:
            typeNames = [get_name(memberType) for memberType in interfaceMemberTypes]
            interfaceObject = CGList((CGGeneric(get_match(typeName)) for typeName in typeNames))
            names.extend(typeNames)
        else:
            interfaceObject = None

        arrayObjectMemberTypes = [t for t in memberTypes if t.isSequence()]
        if len(arrayObjectMemberTypes) > 0:
            assert len(arrayObjectMemberTypes) == 1
            typeName = arrayObjectMemberTypes[0].name
            arrayObject: CGThing | None = CGGeneric(get_match(typeName))
            names.append(typeName)
        else:
            arrayObject = None

        callbackMemberTypes = [t for t in memberTypes if t.isCallback() or t.isCallbackInterface()]
        if len(callbackMemberTypes) > 0:
            assert len(callbackMemberTypes) == 1
            typeName = callbackMemberTypes[0].name
            callbackObject: CGThing | None = CGGeneric(get_match(typeName))
        else:
            callbackObject = None

        dictionaryMemberTypes = [t for t in memberTypes if t.isDictionary()]
        if len(dictionaryMemberTypes) > 0:
            assert len(dictionaryMemberTypes) == 1
            typeName = dictionaryMemberTypes[0].name
            dictionaryObject = CGGeneric(get_match(typeName))
            names.append(typeName)
        else:
            dictionaryObject = None

        objectMemberTypes = [t for t in memberTypes if t.isObject()]
        if len(objectMemberTypes) > 0:
            assert len(objectMemberTypes) == 1
            typeName = objectMemberTypes[0].name
            object = CGGeneric(get_match(typeName))
            names.append(typeName)
        else:
            object = None

        mozMapMemberTypes = [t for t in memberTypes if t.isRecord()]
        if len(mozMapMemberTypes) > 0:
            assert len(mozMapMemberTypes) == 1
            typeName = mozMapMemberTypes[0].name
            mozMapObject = CGGeneric(get_match(typeName))
            names.append(typeName)
        else:
            mozMapObject = None

        hasObjectTypes = object or interfaceObject or arrayObject or callbackObject or mozMapObject
        if hasObjectTypes:
            # "object" is not distinguishable from other types
            assert not object or not (interfaceObject or arrayObject or callbackObject or mozMapObject)
            templateBody = CGList([], "\n")
            if arrayObject or callbackObject:
                # An object can be both an sequence object and a callback or
                # dictionary, but we shouldn't have both in the union's members
                # because they are not distinguishable.
                assert not (arrayObject and callbackObject)
                templateBody.append(arrayObject if arrayObject else callbackObject)
            if interfaceObject:
                assert not object
                templateBody.append(interfaceObject)
            elif object:
                templateBody.append(object)
            if mozMapObject:
                templateBody.append(mozMapObject)

            conversions.append(CGIfWrapper("value.get().is_object()", templateBody))

        if dictionaryObject:
            assert not object
            conversions.append(dictionaryObject)

        stringTypes = [t for t in memberTypes if t.isString() or t.isEnum()]
        numericTypes = [t for t in memberTypes if t.isNumeric()]
        booleanTypes = [t for t in memberTypes if t.isBoolean()]
        numUndefinedVariants = [t.isUndefined() for t in memberTypes].count(True)
        if stringTypes or numericTypes or booleanTypes or numUndefinedVariants != 0:
            assert len(stringTypes) <= 1
            assert len(numericTypes) <= 1
            assert len(booleanTypes) <= 1
            assert numUndefinedVariants <= 1

            def getStringOrPrimitiveConversion(memberType: IDLType) -> CGThing:
                typename = get_name(memberType)
                return CGGeneric(get_match(typename))

            other: list[CGThing] = []
            stringConversion = list(map(getStringOrPrimitiveConversion, stringTypes))
            numericConversion = list(map(getStringOrPrimitiveConversion, numericTypes))
            booleanConversion = list(map(getStringOrPrimitiveConversion, booleanTypes))
            undefinedConversion = CGGeneric("return Ok(ConversionResult::Success(Self::Undefined(())));")

            if stringConversion:
                if booleanConversion:
                    other.append(CGIfWrapper("value.get().is_boolean()", booleanConversion[0]))
                if numericConversion:
                    other.append(CGIfWrapper("value.get().is_number()", numericConversion[0]))
                if numUndefinedVariants != 0:
                    other.append(CGIfWrapper("value.get().is_undefined()", undefinedConversion))
                other.append(stringConversion[0])
            elif numericConversion:
                if booleanConversion:
                    other.append(CGIfWrapper("value.get().is_boolean()", booleanConversion[0]))
                if numUndefinedVariants != 0:
                    other.append(CGIfWrapper("value.get().is_undefined()", undefinedConversion))
                other.append(numericConversion[0])
            elif booleanConversion:
                if numUndefinedVariants != 0:
                    other.append(CGIfWrapper("value.get().is_undefined()", undefinedConversion))
                other.append(booleanConversion[0])
            else:
                assert numUndefinedVariants != 0
                other.append(undefinedConversion)
            conversions.append(CGList(other, "\n\n"))
        conversions.append(CGGeneric(
            f'Ok(ConversionResult::Failure("argument could not be converted to any of: {", ".join(names)}".into()))'
        ))
        generic, genericSuffix = genericsForType(self.type)
        method = CGWrapper(
            CGIndenter(CGList(conversions, "\n\n")),
            pre="unsafe fn from_jsval(cx: *mut JSContext,\n"
                "                     value: HandleValue,\n"
                "                     _option: ())\n"
                f"                     -> Result<ConversionResult<{self.type}{genericSuffix}>, ()> {{\n",
            post="\n}")
        return CGWrapper(
            CGIndenter(CGList([
                CGGeneric("type Config = ();"),
                method,
            ], "\n")),
            pre=f"impl{generic} FromJSValConvertible for {self.type}{genericSuffix} {{\n",
            post="\n}")

    def try_method(self, t: IDLType) -> CGThing:
        if t.isUndefined():
            # undefined does not require a conversion method, so we don't generate one
            return CGGeneric("")

        templateVars = getUnionTypeTemplateVars(t, self.descriptorProvider)
        actualType = templateVars["typeName"]
        if type_needs_tracing(t):
            actualType = f"RootedTraceableBox<{actualType}>"
        if t.isCallback():
            actualType = f"Rc<{actualType}>"
        returnType = f"Result<Option<{actualType}>, ()>"
        jsConversion = templateVars["jsConversion"]

        return CGWrapper(
            CGIndenter(jsConversion, 4),
            pre=f"unsafe fn TryConvertTo{t.name}(cx: SafeJSContext, value: HandleValue) -> {returnType} {{\n",
            post="\n}")

    def define(self) -> str:
        from_jsval = self.from_jsval()
        assert self.type.flatMemberTypes is not None
        methods = CGIndenter(CGList([
            self.try_method(t) for t in self.type.flatMemberTypes
        ], "\n\n"))
        generic, genericSuffix = genericsForType(self.type)
        return f"""
{from_jsval.define()}

impl{generic} {self.type}{genericSuffix} {{
{methods.define()}
}}
"""


class ClassItem:
    """ Use with CGClass """
    def __init__(self, name: str | None, visibility: str) -> None:
        self.name = name
        self.visibility = visibility

    def declare(self, cgClass: CGClass) -> str: # pyrefly: ignore # bad-return
        assert False

    def define(self, cgClass: CGClass) -> str: # pyrefly: ignore # bad-return
        assert False


class ClassBase(ClassItem):
    def __init__(self, name: str, visibility: str = 'pub') -> None:
        ClassItem.__init__(self, name, visibility)

    def declare(self, cgClass: CGClass) -> str:
        return f'{self.visibility} {self.name}'

    def define(self, cgClass: CGClass) -> str:
        # Only in the header
        return ''


class ClassMethod(ClassItem):
    body: str | None
    def __init__(self,
                 name: str,
                 returnType: str,
                 args: list[Argument],
                 inline: bool = False,
                 static: bool = False,
                 virtual: bool = False,
                 const: bool = False,
                 bodyInHeader: bool = False,
                 templateArgs: list[str] | None = None,
                 visibility: str = 'public',
                 body: str | None = None,
                 breakAfterReturnDecl: str = "\n",
                 unsafe: bool = False,
                 breakAfterSelf: str = "\n",
                 override: bool = False
                 ) -> None:
        """
        override indicates whether to flag the method as MOZ_OVERRIDE
        """
        assert not override or virtual
        assert not (override and static)
        self.returnType = returnType
        self.args = args
        self.inline = False
        self.static = static
        self.virtual = virtual
        self.const = const
        self.bodyInHeader = True
        self.templateArgs = templateArgs
        self.body = body
        self.breakAfterReturnDecl = breakAfterReturnDecl
        self.breakAfterSelf = breakAfterSelf
        self.override = override
        self.unsafe = unsafe
        ClassItem.__init__(self, name, visibility)

    def getDecorators(self, declaring: bool) -> str:
        decorators = []
        if self.inline:
            decorators.append('inline')
        if declaring:
            if self.static:
                decorators.append('static')
            if self.virtual:
                decorators.append('virtual')
        if decorators:
            return f'{" ".join(decorators)} '
        return ''

    def getBody(self) -> str:
        # Override me or pass a string to constructor
        assert self.body is not None
        return self.body

    def declare(self, cgClass: CGClass) -> str:

        templateClause = f"<{', '.join(self.templateArgs)}>" if self.bodyInHeader and self.templateArgs else '<>'
        args = ', '.join([a.declare() for a in self.args])
        if self.bodyInHeader:
            body = CGIndenter(CGGeneric(self.getBody())).define()
            body = f' {{\n{body}\n}}'
        else:
            body = ';'
        visibility = f'{self.visibility} ' if self.visibility != 'priv' else ''
        unsafe = "unsafe " if self.unsafe else ""
        returnType = f" -> {self.returnType}" if self.returnType else ""
        const = ' const' if self.const else ''
        override = ' MOZ_OVERRIDE' if self.override else ''
        return (
            f"{self.getDecorators(True)}{self.breakAfterReturnDecl}"
            f"{visibility}{unsafe}fn {self.name}{templateClause}({args})"
            f"{returnType}{const}{override}{body}{self.breakAfterSelf}"
        )

    def define(self, cgClass: CGClass) -> str: # pyrefly: ignore # bad-return
        assert False


class ClassConstructor(ClassItem):
    """
    Used for adding a constructor to a CGClass.

    args is a list of Argument objects that are the arguments taken by the
    constructor.

    inline should be True if the constructor should be marked inline.

    bodyInHeader should be True if the body should be placed in the class
    declaration in the header.

    visibility determines the visibility of the constructor (public,
    protected, private), defaults to private.

    explicit should be True if the constructor should be marked explicit.

    baseConstructors is a list of strings containing calls to base constructors,
    defaults to None.

    body contains a string with the code for the constructor, defaults to empty.
    """
    def __init__(self, args: list[Argument], inline: bool = False, bodyInHeader: bool = False,
                 visibility: str = "priv", explicit: bool = False, baseConstructors: list[str] | None = None,
                 body: str = "") -> None:
        self.args = args
        self.inline = False
        self.bodyInHeader = bodyInHeader
        self.explicit = explicit
        self.baseConstructors = baseConstructors or []
        self.body = body
        ClassItem.__init__(self, None, visibility)

    def getDecorators(self, declaring: bool) -> str:
        decorators = []
        if self.explicit:
            decorators.append('explicit')
        if self.inline and declaring:
            decorators.append('inline')
        if decorators:
            return f'{" ".join(decorators)} '
        return ''

    def getInitializationList(self, cgClass: CGClass) -> str:
        items = [str(c) for c in self.baseConstructors]
        for m in cgClass.members:
            if not m.static:
                initialize = m.body
                if initialize:
                    items.append(f"{m.name}({initialize})")

        if len(items) > 0:
            joinedItems = ",\n    ".join(items)
            return f'\n  : {joinedItems}'
        return ''

    def getBody(self, cgClass: CGClass) -> str:
        initializers = [f"    parent: {self.baseConstructors[0]}"]
        joinedInitializers = '\n'.join(initializers)
        return (
            f"{self.body}"
            f"let mut ret = Rc::new({cgClass.name} {{\n"
            f"{joinedInitializers}\n"
            "});\n"
            "// Note: callback cannot be moved after calling init.\n"
            "match Rc::get_mut(&mut ret) {\n"
            f"    Some(ref mut callback) => callback.parent.init({self.args[0].name}, {self.args[1].name}),\n"
            "    None => unreachable!(),\n"
            "};\n"
            "ret"
        )

    def declare(self, cgClass: CGClass) -> str:
        args = ', '.join([a.declare() for a in self.args])
        body = f'    {self.getBody(cgClass)}'
        body = stripTrailingWhitespace(body.replace('\n', '\n    '))
        if len(body) > 0:
            body += '\n'
        body = f' {{\n{body}}}'

        name = cgClass.getNameString().replace(': DomTypes', '')
        return f"""
pub unsafe fn {self.getDecorators(True)}new({args}) -> Rc<{name}>{body}
"""

    def define(self, cgClass: CGClass) -> str:
        if self.bodyInHeader:
            return ''

        args = ', '.join([a.define() for a in self.args])

        body = f'    {self.getBody(cgClass)}'
        trimmedBody = stripTrailingWhitespace(body.replace('\n', '\n    '))
        body = f'\n{trimmedBody}'
        if len(body) > 0:
            body += '\n'

        className = cgClass.getNameString()
        return f"""
{self.getDecorators(False)}
{className}::{className}({args}){self.getInitializationList(cgClass)}
{{{body}}}
"""


class ClassMember(ClassItem):
    def __init__(self, name: str | None, type: str, visibility: str = "priv", static: bool = False,
                 body: str | None = None) -> None:
        self.type = type
        self.static = static
        self.body = body
        ClassItem.__init__(self, name, visibility)

    def declare(self, cgClass: CGClass) -> str:
        return f'{self.visibility} {self.name}: {self.type},\n'

    def define(self, cgClass: CGClass) -> str:
        if not self.static:
            return ''
        if self.body:
            body = f" = {self.body}"
        else:
            body = ""
        return f'{self.type} {cgClass.getNameString()}::{self.name}{body};\n'


class CGClass(CGThing):
    def __init__(self,
                 name: str,
                 bases: list[ClassBase] = [],
                 members: list[ClassMember] = [],
                 constructors: list[ClassConstructor] = [],
                 destructor: ClassItem | None = None,
                 methods: list[ClassMethod] = [],
                 typedefs: list[ClassItem] = [],
                 enums: list[ClassItem] = [],
                 unions: list[ClassItem] =[],
                 templateArgs: list[Argument] | None = [],
                 templateSpecialization: list[str] = [],
                 disallowCopyConstruction: bool = False,
                 indent: str = '',
                 decorators: str = '',
                 extradeclarations: str = '') -> None:
        CGThing.__init__(self)
        self.name = name
        self.bases = bases
        self.members = members
        self.constructors = constructors
        # We store our single destructor in a list, since all of our
        # code wants lists of members.
        self.destructors = [destructor] if destructor else []
        self.methods = methods
        self.typedefs = typedefs
        self.enums = enums
        self.unions = unions
        self.templateArgs = templateArgs
        self.templateSpecialization = templateSpecialization
        self.disallowCopyConstruction = disallowCopyConstruction
        self.indent = indent
        self.decorators = decorators
        self.extradeclarations = extradeclarations

    def getNameString(self) -> str:
        className = self.name
        if self.templateSpecialization:
            className = f"{className}<{', '.join([str(a) for a in self.templateSpecialization])}>"
        return className

    def define(self) -> str:
        result = ''
        if self.templateArgs:
            templateArgs = [a.declare() for a in self.templateArgs]
            templateArgs = templateArgs[len(self.templateSpecialization):]
            result = f"{result}{self.indent}template <{','.join([str(a) for a in templateArgs])}>\n"

        if self.templateSpecialization:
            specialization = f"<{', '.join([str(a) for a in self.templateSpecialization])}>"
        else:
            specialization = ''

        myself = ''
        if self.decorators != '':
            myself += f'{self.decorators}\n'
        myself += f'{self.indent}pub struct {self.name}{specialization}'
        result += myself

        assert len(self.bases) == 1  # XXjdm Can we support multiple inheritance?

        result += ' {\n'

        if self.bases:
            self.members = [ClassMember("parent", self.bases[0].name, "pub")] + self.members

        result += CGIndenter(CGGeneric(self.extradeclarations),
                             len(self.indent)).define()

        def declareMembers(cgClass: CGClass, memberList: Iterable[ClassItem]) -> str:
            result = ''

            for member in memberList:
                declaration = member.declare(cgClass)
                declaration = CGIndenter(CGGeneric(declaration)).define()
                result = f"{result}{declaration}"
            return result

        if self.disallowCopyConstruction:
            class DisallowedCopyConstructor(ClassItem):
                def __init__(self) -> None:
                    self.visibility = "private"

                def declare(self, cgClass: CGClass) -> str:
                    name = cgClass.getNameString()
                    return (f"{name}(const {name}&) MOZ_DELETE;\n"
                            f"void operator=(const {name}) MOZ_DELETE;\n")
            disallowedCopyConstructors = [DisallowedCopyConstructor()]
        else:
            disallowedCopyConstructors = []

        order = [(self.enums, ''), (self.unions, ''),
                 (self.typedefs, ''), (self.members, '')]

        for (memberList, separator) in order:
            memberString = declareMembers(self, memberList)
            if self.indent:
                memberString = CGIndenter(CGGeneric(memberString),
                                          len(self.indent)).define()
            result = f"{result}{memberString}"

        result += f'{self.indent}}}\n\n'
        result += f'impl{specialization} {self.name}{specialization.replace(": DomTypes", "")} {{\n'

        order = [(self.constructors + disallowedCopyConstructors, '\n'),
                 (self.destructors, '\n'), (self.methods, '\n)')]
        for (memberList, separator) in order:
            memberString = declareMembers(self, memberList)
            if self.indent:
                memberString = CGIndenter(CGGeneric(memberString),
                                          len(self.indent)).define()
            result = f"{result}{memberString}"

        result += "}"
        return result


class CGProxySpecialOperation(CGPerSignatureCall):
    """
    Base class for classes for calling an indexed or named special operation
    (don't use this directly, use the derived classes below).
    """
    templateValues: dict[str, Any] | None
    def __init__(self, descriptor: Descriptor, operationName: str) -> None:
        nativeName = MakeNativeName(descriptor.binaryNameFor(operationName, False))
        operation = descriptor.operations[operationName]
        assert isinstance(operation, IDLMethod)
        assert len(operation.signatures()) == 1
        signature = operation.signatures()[0]

        (returnType, arguments) = signature
        if operation.isGetter() and not returnType.nullable():
            returnType = IDLNullableType(returnType.location, returnType)

        # We pass len(arguments) as the final argument so that the
        # CGPerSignatureCall won't do any argument conversion of its own.
        CGPerSignatureCall.__init__(self, returnType, [], arguments, nativeName,
                                    False, descriptor, operation,
                                    len(arguments))

        if operation.isSetter():
            # arguments[0] is the index or name of the item that we're setting.
            argument = arguments[1]
            info = getJSToNativeConversionInfo(
                argument.type, descriptor,
                exceptionCode="return false;")
            template = info.template
            declType = info.declType

            templateValues = {
                "val": "value.handle()",
            }
            self.cgRoot.prepend(instantiateJSToNativeConversionTemplate(
                template, templateValues, declType, argument.identifier.name))
            self.cgRoot.prepend(CGGeneric("rooted!(in(*cx) let value = desc.value_);"))

    def getArguments(self) -> list[tuple[FakeArgument | IDLArgument, str]]:
        args = [(a, process_arg(a.identifier.name, a)) for a in self.arguments]
        return args

    def wrap_return_value(self) -> str:
        if isinstance(self.idlNode, IDLMethod) and not self.idlNode.isGetter() or self.templateValues is None:
            return ""

        wrap = CGGeneric(wrapForType(**self.templateValues))
        wrap = CGIfWrapper("let Some(result) = result", wrap)
        return f"\n{wrap.define()}"


class CGProxyIndexedGetter(CGProxySpecialOperation):
    """
    Class to generate a call to an indexed getter. If templateValues is not None
    the returned value will be wrapped with wrapForType using templateValues.
    """
    def __init__(self, descriptor: Descriptor, templateValues: dict[str, Any] | None = None) -> None:
        self.templateValues = templateValues
        CGProxySpecialOperation.__init__(self, descriptor, 'IndexedGetter')


class CGProxyIndexedSetter(CGProxySpecialOperation):
    """
    Class to generate a call to an indexed setter.
    """
    def __init__(self, descriptor: Descriptor) -> None:
        CGProxySpecialOperation.__init__(self, descriptor, 'IndexedSetter')


class CGProxyNamedOperation(CGProxySpecialOperation):
    """
    Class to generate a call to a named operation.
    """
    def __init__(self, descriptor: Descriptor, name: str) -> None:
        CGProxySpecialOperation.__init__(self, descriptor, name)

    def define(self) -> str:
        # Our first argument is the id we're getting.
        argName = self.arguments[0].identifier.name
        return (f'let {argName} = jsid_to_string(*cx, Handle::from_raw(id)).expect("Not a string-convertible JSID?");\n'
                "let this = UnwrapProxy::<D>(proxy);\n"
                "let this = &*this;\n"
                f"{CGProxySpecialOperation.define(self)}")


class CGProxyNamedGetter(CGProxyNamedOperation):
    """
    Class to generate a call to an named getter. If templateValues is not None
    the returned value will be wrapped with wrapForType using templateValues.
    """
    def __init__(self, descriptor: Descriptor, templateValues: dict[str, Any] | None = None) -> None:
        self.templateValues = templateValues
        CGProxySpecialOperation.__init__(self, descriptor, 'NamedGetter')


class CGProxyNamedPresenceChecker(CGProxyNamedGetter):
    """
    Class to generate a call that checks whether a named property exists.
    For now, we just delegate to CGProxyNamedGetter
    """
    def __init__(self, descriptor: Descriptor) -> None:
        CGProxyNamedGetter.__init__(self, descriptor)


class CGProxyNamedSetter(CGProxyNamedOperation):
    """
    Class to generate a call to a named setter.
    """
    def __init__(self, descriptor: Descriptor) -> None:
        CGProxySpecialOperation.__init__(self, descriptor, 'NamedSetter')


class CGProxyNamedDeleter(CGProxyNamedOperation):
    """
    Class to generate a call to a named deleter.
    """
    def __init__(self, descriptor: Descriptor) -> None:
        CGProxySpecialOperation.__init__(self, descriptor, 'NamedDeleter')

    def define(self) -> str:
        # Our first argument is the id we're getting.
        argName = self.arguments[0].identifier.name
        return ("if !id.is_symbol() {\n"
                f'    let {argName} = match jsid_to_string(*cx, Handle::from_raw(id)) {{\n'
                "        Some(val) => val,\n"
                "        None => {\n"
                "            throw_type_error(*cx, \"Not a string-convertible JSID\");\n"
                "            return false;\n"
                "        }\n"
                "    };\n"
                "    let this = UnwrapProxy::<D>(proxy);\n"
                "    let this = &*this;\n"
                f"    {CGProxySpecialOperation.define(self)}"
                "}\n")


class CGProxyUnwrap(CGAbstractMethod):
    def __init__(self, descriptor: Descriptor) -> None:
        args = [Argument('RawHandleObject', 'obj')]
        CGAbstractMethod.__init__(self, descriptor, "UnwrapProxy",
                                  f'*const {descriptor.concreteType}', args,
                                  alwaysInline=True, unsafe=True,
                                  templateArgs=['D: DomTypes'])

    def definition_body(self) -> CGThing:
        return CGGeneric(f"""
        let mut slot = UndefinedValue();
        GetProxyReservedSlot(obj.get(), 0, &mut slot);
        let box_ = slot.to_private() as *const {self.descriptor.concreteType};
return box_;""")


class CGDOMJSProxyHandler_getOwnPropertyDescriptor(CGAbstractExternMethod):
    def __init__(self, descriptor: Descriptor) -> None:
        args = [Argument('*mut JSContext', 'cx'), Argument('RawHandleObject', 'proxy'),
                Argument('RawHandleId', 'id'),
                Argument('RawMutableHandle<PropertyDescriptor>', 'mut desc'),
                Argument('*mut bool', 'is_none')]
        CGAbstractExternMethod.__init__(self, descriptor, "getOwnPropertyDescriptor",
                                        "bool", args, templateArgs=['D: DomTypes'])
        self.descriptor = descriptor

    # https://heycam.github.io/webidl/#LegacyPlatformObjectGetOwnProperty
    def getBody(self) -> str:
        indexedGetter = self.descriptor.operations['IndexedGetter']

        get = "let cx = SafeJSContext::from_ptr(cx);\n"

        if self.descriptor.isMaybeCrossOriginObject():
            get += dedent(
                """
                if !<D as DomHelpers<D>>::is_platform_object_same_origin(cx, proxy) {
                    if !proxyhandler::cross_origin_get_own_property_helper(
                        cx, proxy, CROSS_ORIGIN_PROPERTIES.get(), id, desc, &mut *is_none
                    ) {
                        return false;
                    }
                    if *is_none {
                        return proxyhandler::cross_origin_property_fallback::<D>(cx, proxy, id, desc, &mut *is_none);
                    }
                    return true;
                }

                // Safe to enter the Realm of proxy now.
                let _ac = JSAutoRealm::new(*cx, proxy.get());
                """)

        if indexedGetter:
            get += "let index = get_array_index_from_id(Handle::from_raw(id));\n"

            attrs = "JSPROP_ENUMERATE"
            if self.descriptor.operations['IndexedSetter'] is None:
                attrs += " | JSPROP_READONLY"
            fillDescriptor = ("set_property_descriptor(\n"
                              "    MutableHandle::from_raw(desc),\n"
                              "    rval.handle(),\n"
                              f"    ({attrs}) as u32,\n"
                              "    &mut *is_none\n"
                              ");\n"
                              "return true;")
            templateValues = {
                'jsvalRef': 'rval.handle_mut()',
                'successCode': fillDescriptor,
                'pre': 'rooted!(in(*cx) let mut rval = UndefinedValue());'
            }
            get += ("if let Some(index) = index {\n"
                    "    let this = UnwrapProxy::<D>(proxy);\n"
                    "    let this = &*this;\n"
                    f"{CGIndenter(CGProxyIndexedGetter(self.descriptor, templateValues)).define()}\n"
                    "}\n")

        if self.descriptor.supportsNamedProperties():
            attrs = []
            if not self.descriptor.interface.getExtendedAttribute("LegacyUnenumerableNamedProperties"):
                attrs.append("JSPROP_ENUMERATE")
            if self.descriptor.operations['NamedSetter'] is None:
                attrs.append("JSPROP_READONLY")
            if attrs:
                attrs = " | ".join(attrs)
            else:
                attrs = "0"
            fillDescriptor = ("set_property_descriptor(\n"
                              "    MutableHandle::from_raw(desc),\n"
                              "    rval.handle(),\n"
                              f"    ({attrs}) as u32,\n"
                              "    &mut *is_none\n"
                              ");\n"
                              "return true;")
            templateValues = {
                'jsvalRef': 'rval.handle_mut()',
                'successCode': fillDescriptor,
                'pre': 'rooted!(in(*cx) let mut rval = UndefinedValue());'
            }

            # See the similar-looking in CGDOMJSProxyHandler_get for the spec quote.
            condition = "id.is_string() || id.is_int()"
            if indexedGetter:
                condition = f"index.is_none() && ({condition})"
            # Once we start supporting OverrideBuiltins we need to make
            # ResolveOwnProperty or EnumerateOwnProperties filter out named
            # properties that shadow prototype properties.
            namedGet = f"""
if {condition} {{
    let mut has_on_proto = false;
    if !has_property_on_prototype(*cx, proxy_lt, id_lt, &mut has_on_proto) {{
        return false;
    }}
    if !has_on_proto {{
        {CGIndenter(CGProxyNamedGetter(self.descriptor, templateValues), 8).define()}
    }}
}}
"""
        else:
            namedGet = ""

        return f"""{get}\
rooted!(in(*cx) let mut expando = ptr::null_mut::<JSObject>());
get_expando_object(proxy, expando.handle_mut());
//if (!xpc::WrapperFactory::IsXrayWrapper(proxy) && (expando = GetExpandoObject(proxy))) {{
let proxy_lt = Handle::from_raw(proxy);
let id_lt = Handle::from_raw(id);
if !expando.is_null() {{
    rooted!(in(*cx) let mut ignored = ptr::null_mut::<JSObject>());
    if !JS_GetPropertyDescriptorById(*cx, expando.handle().into(), id, desc, ignored.handle_mut().into(), is_none) {{
        return false;
    }}
    if !*is_none {{
        // Pretend the property lives on the wrapper.
        return true;
    }}
}}
{namedGet}\
true"""

    def definition_body(self) -> CGThing:
        return CGGeneric(self.getBody())


class CGDOMJSProxyHandler_defineProperty(CGAbstractExternMethod):
    def __init__(self, descriptor: Descriptor) -> None:
        args = [Argument('*mut JSContext', 'cx'), Argument('RawHandleObject', 'proxy'),
                Argument('RawHandleId', 'id'),
                Argument('RawHandle<PropertyDescriptor>', 'desc'),
                Argument('*mut ObjectOpResult', 'opresult')]
        CGAbstractExternMethod.__init__(self, descriptor, "defineProperty", "bool", args, templateArgs=['D: DomTypes'])
        self.descriptor = descriptor

    def getBody(self) -> str:
        set = "let cx = SafeJSContext::from_ptr(cx);\n"

        if self.descriptor.isMaybeCrossOriginObject():
            set += dedent(
                """
                if !<D as DomHelpers<D>>::is_platform_object_same_origin(cx, proxy) {
                    return proxyhandler::report_cross_origin_denial::<D>(cx, id, "define");
                }

                // Safe to enter the Realm of proxy now.
                let _ac = JSAutoRealm::new(*cx, proxy.get());
                """)

        indexedSetter = self.descriptor.operations['IndexedSetter']
        if indexedSetter:
            set += ("let index = get_array_index_from_id(Handle::from_raw(id));\n"
                    "if let Some(index) = index {\n"
                    "    let this = UnwrapProxy::<D>(proxy);\n"
                    "    let this = &*this;\n"
                    f"{CGIndenter(CGProxyIndexedSetter(self.descriptor)).define()}"
                    "    return (*opresult).succeed();\n"
                    "}\n")
        elif self.descriptor.operations['IndexedGetter']:
            set += ("if get_array_index_from_id(Handle::from_raw(id)).is_some() {\n"
                    "    return (*opresult).failNoIndexedSetter();\n"
                    "}\n")

        namedSetter = self.descriptor.operations['NamedSetter']
        if namedSetter:
            if self.descriptor.hasLegacyUnforgeableMembers:
                raise TypeError("Can't handle a named setter on an interface that has "
                                "unforgeables. Figure out how that should work!")
            set += ("if id.is_string() || id.is_int() {\n"
                    f"{CGIndenter(CGProxyNamedSetter(self.descriptor)).define()}"
                    "    return (*opresult).succeed();\n"
                    "}\n")
        elif self.descriptor.supportsNamedProperties():
            set += ("if id.is_string() || id.is_int() {\n"
                    f"{CGIndenter(CGProxyNamedGetter(self.descriptor)).define()}"
                    "    if result.is_some() {\n"
                    "        return (*opresult).fail_no_named_setter();\n"
                    "    }\n"
                    "}\n")
        set += f"return proxyhandler::define_property(*cx, {', '.join(a.name for a in self.args[1:])});"
        return set

    def definition_body(self) -> CGThing:
        return CGGeneric(self.getBody())


class CGDOMJSProxyHandler_delete(CGAbstractExternMethod):
    def __init__(self, descriptor: Descriptor) -> None:
        args = [Argument('*mut JSContext', 'cx'), Argument('RawHandleObject', 'proxy'),
                Argument('RawHandleId', 'id'),
                Argument('*mut ObjectOpResult', 'res')]
        CGAbstractExternMethod.__init__(self, descriptor, "delete", "bool", args, templateArgs=['D: DomTypes'])
        self.descriptor = descriptor

    def getBody(self) -> str:
        set = "let cx = SafeJSContext::from_ptr(cx);\n"

        if self.descriptor.isMaybeCrossOriginObject():
            set += dedent(
                """
                if !<D as DomHelpers<D>>::is_platform_object_same_origin(cx, proxy) {
                    return proxyhandler::report_cross_origin_denial::<D>(cx, id, "delete");
                }

                // Safe to enter the Realm of proxy now.
                let _ac = JSAutoRealm::new(*cx, proxy.get());
                """)

        if self.descriptor.operations['NamedDeleter']:
            if self.descriptor.hasLegacyUnforgeableMembers:
                raise TypeError("Can't handle a deleter on an interface that has "
                                "unforgeables. Figure out how that should work!")
            set += CGProxyNamedDeleter(self.descriptor).define()
        set += f"return proxyhandler::delete(*cx, {', '.join(a.name for a in self.args[1:])});"
        return set

    def definition_body(self) -> CGThing:
        return CGGeneric(self.getBody())


class CGDOMJSProxyHandler_ownPropertyKeys(CGAbstractExternMethod):
    def __init__(self, descriptor: Descriptor) -> None:
        args = [Argument('*mut JSContext', 'cx'),
                Argument('RawHandleObject', 'proxy'),
                Argument('RawMutableHandleIdVector', 'props')]
        CGAbstractExternMethod.__init__(self, descriptor, "own_property_keys", "bool", args,
                                        templateArgs=['D: DomTypes'])
        self.descriptor = descriptor

    def getBody(self) -> str:
        body = dedent(
            """
            let cx = SafeJSContext::from_ptr(cx);
            let unwrapped_proxy = UnwrapProxy::<D>(proxy);
            """)

        if self.descriptor.isMaybeCrossOriginObject():
            body += dedent(
                """
                if !<D as DomHelpers<D>>::is_platform_object_same_origin(cx, proxy) {
                    return proxyhandler::cross_origin_own_property_keys(
                        cx, proxy, CROSS_ORIGIN_PROPERTIES.get(), props
                    );
                }

                // Safe to enter the Realm of proxy now.
                let _ac = JSAutoRealm::new(*cx, proxy.get());
                """)

        if self.descriptor.operations['IndexedGetter']:
            body += dedent(
                """
                for i in 0..(*unwrapped_proxy).Length() {
                    rooted!(in(*cx) let mut rooted_jsid: jsid);
                    int_to_jsid(i as i32, rooted_jsid.handle_mut());
                    AppendToIdVector(props, rooted_jsid.handle());
                }
                """)

        if self.descriptor.supportsNamedProperties():
            body += dedent(
                """
                for name in (*unwrapped_proxy).SupportedPropertyNames() {
                    let cstring = CString::new(name).unwrap();
                    let jsstring = JS_AtomizeAndPinString(*cx, cstring.as_ptr());
                    rooted!(in(*cx) let rooted = jsstring);
                    rooted!(in(*cx) let mut rooted_jsid: jsid);
                    RUST_INTERNED_STRING_TO_JSID(*cx, rooted.handle().get(), rooted_jsid.handle_mut());
                    AppendToIdVector(props, rooted_jsid.handle());
                }
                """)

        body += dedent(
            """
            rooted!(in(*cx) let mut expando = ptr::null_mut::<JSObject>());
            get_expando_object(proxy, expando.handle_mut());
            if !expando.is_null() &&
                !GetPropertyKeys(*cx, expando.handle(), JSITER_OWNONLY | JSITER_HIDDEN | JSITER_SYMBOLS, props) {
                return false;
            }

            true
            """)

        return body

    def definition_body(self) -> CGThing:
        return CGGeneric(self.getBody())


class CGDOMJSProxyHandler_getOwnEnumerablePropertyKeys(CGAbstractExternMethod):
    def __init__(self, descriptor: Descriptor) -> None:
        assert (descriptor.operations["IndexedGetter"]
                and descriptor.interface.getExtendedAttribute("LegacyUnenumerableNamedProperties")
                or descriptor.isMaybeCrossOriginObject())
        args = [Argument('*mut JSContext', 'cx'),
                Argument('RawHandleObject', 'proxy'),
                Argument('RawMutableHandleIdVector', 'props')]
        CGAbstractExternMethod.__init__(self, descriptor,
                                        "getOwnEnumerablePropertyKeys", "bool", args, templateArgs=['D: DomTypes'])
        self.descriptor = descriptor

    def getBody(self) -> str:
        body = dedent(
            """
            let cx = SafeJSContext::from_ptr(cx);
            let unwrapped_proxy = UnwrapProxy::<D>(proxy);
            """)

        if self.descriptor.isMaybeCrossOriginObject():
            body += dedent(
                """
                if !<D as DomHelpers<D>>::is_platform_object_same_origin(cx, proxy) {
                    // There are no enumerable cross-origin props, so we're done.
                    return true;
                }

                // Safe to enter the Realm of proxy now.
                let _ac = JSAutoRealm::new(*cx, proxy.get());
                """)

        if self.descriptor.operations['IndexedGetter']:
            body += dedent(
                """
                for i in 0..(*unwrapped_proxy).Length() {
                    rooted!(in(*cx) let mut rooted_jsid: jsid);
                    int_to_jsid(i as i32, rooted_jsid.handle_mut());
                    AppendToIdVector(props, rooted_jsid.handle());
                }
                """)

        body += dedent(
            """
            rooted!(in(*cx) let mut expando = ptr::null_mut::<JSObject>());
            get_expando_object(proxy, expando.handle_mut());
            if !expando.is_null() &&
                !GetPropertyKeys(*cx, expando.handle(), JSITER_OWNONLY | JSITER_HIDDEN | JSITER_SYMBOLS, props) {
                return false;
            }

            true
            """)

        return body

    def definition_body(self) -> CGThing:
        return CGGeneric(self.getBody())


class CGDOMJSProxyHandler_hasOwn(CGAbstractExternMethod):
    def __init__(self, descriptor: Descriptor) -> None:
        args = [Argument('*mut JSContext', 'cx'), Argument('RawHandleObject', 'proxy'),
                Argument('RawHandleId', 'id'), Argument('*mut bool', 'bp')]
        CGAbstractExternMethod.__init__(self, descriptor, "hasOwn", "bool", args, templateArgs=['D: DomTypes'])
        self.descriptor = descriptor

    def getBody(self) -> str:
        indexedGetter = self.descriptor.operations['IndexedGetter']
        indexed = "let cx = SafeJSContext::from_ptr(cx);\n"

        if self.descriptor.isMaybeCrossOriginObject():
            indexed += dedent(
                """
                if !<D as DomHelpers<D>>::is_platform_object_same_origin(cx, proxy) {
                    return proxyhandler::cross_origin_has_own(
                        cx, proxy, CROSS_ORIGIN_PROPERTIES.get(), id, bp
                    );
                }

                // Safe to enter the Realm of proxy now.
                let _ac = JSAutoRealm::new(*cx, proxy.get());
                """)

        if indexedGetter:
            indexed += ("let index = get_array_index_from_id(Handle::from_raw(id));\n"
                        "if let Some(index) = index {\n"
                        "    let this = UnwrapProxy::<D>(proxy);\n"
                        "    let this = &*this;\n"
                        f"{CGIndenter(CGProxyIndexedGetter(self.descriptor)).define()}\n"
                        "    *bp = result.is_some();\n"
                        "    return true;\n"
                        "}\n\n")

        condition = "id.is_string() || id.is_int()"
        if indexedGetter:
            condition = f"index.is_none() && ({condition})"
        if self.descriptor.supportsNamedProperties():
            named = f"""
if {condition} {{
    let mut has_on_proto = false;
    if !has_property_on_prototype(*cx, proxy_lt, id_lt, &mut has_on_proto) {{
        return false;
    }}
    if !has_on_proto {{
        {CGIndenter(CGProxyNamedGetter(self.descriptor), 8).define()}
        *bp = result.is_some();
        return true;
    }}
}}

"""
        else:
            named = ""

        return f"""{indexed}\
rooted!(in(*cx) let mut expando = ptr::null_mut::<JSObject>());
let proxy_lt = Handle::from_raw(proxy);
let id_lt = Handle::from_raw(id);
get_expando_object(proxy, expando.handle_mut());
if !expando.is_null() {{
    let ok = JS_HasPropertyById(*cx, expando.handle().into(), id, bp);
    if !ok || *bp {{
        return ok;
    }}
}}
{named}\
*bp = false;
true"""

    def definition_body(self) -> CGThing:
        return CGGeneric(self.getBody())


class CGDOMJSProxyHandler_get(CGAbstractExternMethod):
    def __init__(self, descriptor: Descriptor) -> None:
        args = [Argument('*mut JSContext', 'cx'), Argument('RawHandleObject', 'proxy'),
                Argument('RawHandleValue', 'receiver'), Argument('RawHandleId', 'id'),
                Argument('RawMutableHandleValue', 'vp')]
        CGAbstractExternMethod.__init__(self, descriptor, "get", "bool", args, templateArgs=['D: DomTypes'])
        self.descriptor = descriptor

    # https://heycam.github.io/webidl/#LegacyPlatformObjectGetOwnProperty
    def getBody(self) -> str:
        if self.descriptor.isMaybeCrossOriginObject():
            maybeCrossOriginGet = dedent(
                """
                if !<D as DomHelpers<D>>::is_platform_object_same_origin(cx, proxy) {
                    return proxyhandler::cross_origin_get::<D>(cx, proxy, receiver, id, vp);
                }

                // Safe to enter the Realm of proxy now.
                let _ac = JSAutoRealm::new(*cx, proxy.get());
                """)
        else:
            maybeCrossOriginGet = ""
        getFromExpando = """\
rooted!(in(*cx) let mut expando = ptr::null_mut::<JSObject>());
get_expando_object(proxy, expando.handle_mut());
if !expando.is_null() {
    let mut hasProp = false;
    if !JS_HasPropertyById(*cx, expando.handle().into(), id, &mut hasProp) {
        return false;
    }

    if hasProp {
        return JS_ForwardGetPropertyTo(*cx, expando.handle().into(), id, receiver, vp);
    }
}"""

        templateValues = {
            'jsvalRef': 'vp_lt',
            'successCode': 'return true;',
        }

        indexedGetter = self.descriptor.operations['IndexedGetter']
        if indexedGetter:
            getIndexedOrExpando = ("let index = get_array_index_from_id(id_lt);\n"
                                   "if let Some(index) = index {\n"
                                   "    let this = UnwrapProxy::<D>(proxy);\n"
                                   "    let this = &*this;\n"
                                   f"{CGIndenter(CGProxyIndexedGetter(self.descriptor, templateValues)).define()}")
            trimmedGetFromExpando = stripTrailingWhitespace(getFromExpando.replace('\n', '\n    '))
            getIndexedOrExpando += f"""
    // Even if we don't have this index, we don't forward the
    // get on to our expando object.
}} else {{
    {trimmedGetFromExpando}
}}
"""
        else:
            getIndexedOrExpando = f"{getFromExpando}\n"

        if self.descriptor.supportsNamedProperties():
            condition = "id.is_string() || id.is_int()"
            # From step 1:
            #     If O supports indexed properties and P is an array index, then:
            #
            #         3. Set ignoreNamedProps to true.
            if indexedGetter:
                condition = f"index.is_none() && ({condition})"
            getNamed = (f"if {condition} {{\n"
                        f"{CGIndenter(CGProxyNamedGetter(self.descriptor, templateValues)).define()}}}\n")
        else:
            getNamed = ""

        return f"""
//MOZ_ASSERT(!xpc::WrapperFactory::IsXrayWrapper(proxy),
//"Should not have a XrayWrapper here");
let cx = SafeJSContext::from_ptr(cx);

{maybeCrossOriginGet}

let proxy_lt = Handle::from_raw(proxy);
let mut vp_lt = MutableHandle::from_raw(vp);
let id_lt = Handle::from_raw(id);
let receiver_lt = Handle::from_raw(receiver);

{getIndexedOrExpando}
let mut found = false;
if !get_property_on_prototype(*cx, proxy_lt, receiver_lt, id_lt, &mut found, vp_lt.reborrow()) {{
    return false;
}}

if found {{
    return true;
}}
{getNamed}
vp.set(UndefinedValue());
true"""

    def definition_body(self) -> CGThing:
        return CGGeneric(self.getBody())


class CGDOMJSProxyHandler_getPrototype(CGAbstractExternMethod):
    def __init__(self, descriptor: Descriptor) -> None:
        args = [Argument('*mut JSContext', 'cx'), Argument('RawHandleObject', 'proxy'),
                Argument('RawMutableHandleObject', 'proto')]
        CGAbstractExternMethod.__init__(self, descriptor, "getPrototype", "bool", args, templateArgs=["D: DomTypes"])
        assert descriptor.isMaybeCrossOriginObject()
        self.descriptor = descriptor

    def getBody(self) -> str:
        return dedent(
            """
            let cx = SafeJSContext::from_ptr(cx);
            proxyhandler::maybe_cross_origin_get_prototype::<D>(cx, proxy, GetProtoObject::<D>, proto)
            """)

    def definition_body(self) -> CGThing:
        return CGGeneric(self.getBody())


class CGDOMJSProxyHandler_className(CGAbstractExternMethod):
    def __init__(self, descriptor: Descriptor) -> None:
        args = [Argument('*mut JSContext', 'cx'), Argument('RawHandleObject', '_proxy')]
        CGAbstractExternMethod.__init__(self, descriptor, "className", "*const libc::c_char", args, doesNotPanic=True)
        self.descriptor = descriptor

    def getBody(self) -> str:
        return str_to_cstr_ptr(self.descriptor.name)

    def definition_body(self) -> CGThing:
        return CGGeneric(self.getBody())


class CGAbstractClassHook(CGAbstractExternMethod):
    """
    Meant for implementing JSClass hooks, like Finalize or Trace. Does very raw
    'this' unwrapping as it assumes that the unwrapped type is always known.
    """
    def __init__(self, descriptor: Descriptor, name: str, returnType: str, args: list[Argument], doesNotPanic: bool = False) -> None:
        CGAbstractExternMethod.__init__(self, descriptor, name, returnType,
                                        args, templateArgs=['D: DomTypes'])

    def definition_body_prologue(self) -> CGThing:
        return CGGeneric(f"""
let this = native_from_object_static::<{self.descriptor.concreteType}>(obj).unwrap();
""")

    def definition_body(self) -> CGThing:
        return CGList([
            self.definition_body_prologue(),
            self.generate_code(),
        ])

    def generate_code(self) -> CGThing:
        raise NotImplementedError


def finalizeHook(descriptor: Descriptor, hookName: str, context: str) -> str:
    if descriptor.isGlobal():
        release = "finalize_global(obj, this);"
    elif descriptor.weakReferenceable:
        release = "finalize_weak_referenceable(obj, this);"
    else:
        release = "finalize_common(this);"
    return release


class CGClassTraceHook(CGAbstractClassHook):
    """
    A hook to trace through our native object; used for GC and CC
    """
    def __init__(self, descriptor: Descriptor) -> None:
        args = [Argument('*mut JSTracer', 'trc'), Argument('*mut JSObject', 'obj')]
        CGAbstractClassHook.__init__(self, descriptor, TRACE_HOOK_NAME, 'void',
                                     args, doesNotPanic=True)
        self.traceGlobal = descriptor.isGlobal()

    def generate_code(self) -> CGThing:
        body = [CGGeneric("if this.is_null() { return; } // GC during obj creation\n"
                          f"(*this).trace({self.args[0].name});")]
        if self.traceGlobal:
            body += [CGGeneric("trace_global(trc, obj);")]
        return CGList(body, "\n")


class CGClassConstructHook(CGAbstractExternMethod):
    """
    JS-visible constructor for our objects
    """
    def __init__(self, descriptor: Descriptor, constructor: IDLConstructor | None = None) -> None:
        args = [Argument('*mut JSContext', 'cx'), Argument('u32', 'argc'), Argument('*mut JSVal', 'vp')]
        name = CONSTRUCT_HOOK_NAME
        if constructor:
            name += f"_{constructor.identifier.name}"
        else:
            constructor = descriptor.interface.ctor()
            assert constructor
        CGAbstractExternMethod.__init__(self, descriptor, name, 'bool', args, templateArgs=['D: DomTypes'])
        self.constructor = constructor
        self.exposureSet = descriptor.interface.exposureSet

    def definition_body(self) -> CGThing:
        preamble = """let cx = SafeJSContext::from_ptr(cx);
let args = CallArgs::from_vp(vp, argc);
let global = D::GlobalScope::from_object(JS_CALLEE(*cx, vp).to_object());
"""
        if self.constructor.isHTMLConstructor():
            signatures = self.constructor.signatures()
            assert len(signatures) == 1
            constructorCall = f"""
                <D as DomHelpers<D>>::call_html_constructor::<D::{self.descriptor.name}>(
                    cx,
                    &args,
                    &global,
                    PrototypeList::ID::{MakeNativeName(self.descriptor.name)},
                    CreateInterfaceObjects::<D>,
                    CanGc::note()
                )
                """
        else:
            ctorName = GetConstructorNameForReporting(self.descriptor, self.constructor)
            name = self.constructor.identifier.name
            nativeName = MakeNativeName(self.descriptor.binaryNameFor(name, True))

            if len(self.exposureSet) == 1:
                args = [
                    f"global.downcast::<D::{list(self.exposureSet)[0]}>().unwrap()",
                    "Some(desired_proto)",
                    "CanGc::note()"
                ]
            else:
                args = [
                    "global",
                    "Some(desired_proto)",
                    "CanGc::note()"
                ]

            constructor = CGMethodCall(args, nativeName, True, self.descriptor, self.constructor)
            constructorCall = f"""
            call_default_constructor::<D>(
                cx,
                &args,
                &global,
                PrototypeList::ID::{MakeNativeName(self.descriptor.name)},
                \"{ctorName}\",
                CreateInterfaceObjects::<D>,
                |cx: SafeJSContext, args: &CallArgs, global: &D::GlobalScope, desired_proto: HandleObject| {{
                    {constructor.define()}
                }}
            )
                """
        return CGList([CGGeneric(preamble), CGGeneric(constructorCall)])


class CGClassFinalizeHook(CGAbstractClassHook):
    """
    A hook for finalize, used to release our native object.
    """
    def __init__(self, descriptor: Descriptor) -> None:
        args = [Argument('*mut GCContext', '_cx'), Argument('*mut JSObject', 'obj')]
        CGAbstractClassHook.__init__(self, descriptor, FINALIZE_HOOK_NAME,
                                     'void', args)

    def generate_code(self) -> CGThing:
        return CGGeneric(finalizeHook(self.descriptor, self.name, self.args[0].name))


class CGDOMJSProxyHandlerDOMClass(CGThing):
    def __init__(self, descriptor: Descriptor) -> None:
        CGThing.__init__(self)
        self.descriptor = descriptor

    def define(self) -> str:
        return f"""
pub static Class: ThreadUnsafeOnceLock<DOMClass> = ThreadUnsafeOnceLock::new();

pub(crate) fn init_proxy_handler_dom_class<D: DomTypes>() {{
    Class.set({DOMClass(self.descriptor)});
}}
"""


class CGInterfaceTrait(CGThing):
    def __init__(self, descriptor: Descriptor, descriptorProvider: DescriptorProvider) -> None:
        CGThing.__init__(self)

        def attribute_arguments(attribute_type: IDLType,
                                argument: IDLType | None = None,
                                inRealm: bool = False,
                                canGc: bool = False,
                                retval: bool = False
                                ) -> Iterable[tuple[str, str]]:
            if typeNeedsCx(attribute_type, retval):
                yield "cx", "SafeJSContext"

            if argument:
                yield "value", argument_type(descriptor, argument)

            if inRealm:
                yield "_comp", "InRealm"

            if canGc:
                yield "_can_gc", "CanGc"

            if retval and returnTypeNeedsOutparam(attribute_type):
                yield "retval", outparamTypeFromReturnType(attribute_type)

        def members() -> Iterator[tuple[str, Iterable[tuple[str, str]], str, bool]]:
            for m in descriptor.interface.members:
                if (m.isMethod()
                        and not m.isMaplikeOrSetlikeOrIterableMethod()
                        and (not m.isIdentifierLess() or (m.isStringifier() and not m.underlyingAttr))
                        and not m.isDefaultToJSON()):
                    name = CGSpecializedMethod.makeNativeName(descriptor, m)
                    infallible = 'infallible' in descriptor.getExtendedAttributes(m)
                    for idx, (rettype, arguments) in enumerate(m.signatures()):
                        rettype = cast(IDLType, rettype)
                        arguments = cast(list[IDLArgument], arguments)
                        arguments = method_arguments(descriptor, rettype, arguments,
                                                     inRealm=name in descriptor.inRealmMethods,
                                                     canGc=name in descriptor.canGcMethods)
                        rettype = return_type(descriptor, rettype, infallible)
                        yield f"{name}{'_' * idx}", arguments, rettype, m.isStatic()
                elif m.isAttr():
                    name = CGSpecializedGetter.makeNativeName(descriptor, m)
                    infallible = 'infallible' in descriptor.getExtendedAttributes(m, getter=True)
                    yield (name,
                           attribute_arguments(
                               m.type,
                               inRealm=name in descriptor.inRealmMethods,
                               canGc=name in descriptor.canGcMethods,
                               retval=True
                           ),
                           return_type(descriptor, m.type, infallible),
                           m.isStatic())

                    if not m.readonly:
                        name = CGSpecializedSetter.makeNativeName(descriptor, m)
                        infallible = 'infallible' in descriptor.getExtendedAttributes(m, setter=True)
                        if infallible:
                            rettype = "()"
                        else:
                            rettype = "ErrorResult"
                        yield (name,
                               attribute_arguments(
                                   m.type,
                                   m.type,
                                   inRealm=name in descriptor.inRealmMethods,
                                   canGc=name in descriptor.canGcMethods,
                                   retval=False,
                               ),
                               rettype,
                               m.isStatic())

            if descriptor.proxy or descriptor.isGlobal():
                for name, operation in descriptor.operations.items():
                    if not operation or operation.isStringifier():
                        continue

                    assert len(operation.signatures()) == 1
                    rettype, arguments = operation.signatures()[0]

                    infallible = 'infallible' in descriptor.getExtendedAttributes(operation)
                    if operation.isGetter():
                        if not rettype.nullable():
                            rettype = IDLNullableType(rettype.location, rettype)
                        arguments = method_arguments(descriptor, rettype, arguments,
                                                     inRealm=name in descriptor.inRealmMethods,
                                                     canGc=name in descriptor.canGcMethods)

                        # If this interface 'supports named properties', then we
                        # should be able to access 'supported property names'
                        #
                        # WebIDL, Second Draft, section 3.2.4.5
                        # https://heycam.github.io/webidl/#idl-named-properties
                        if operation.isNamed():
                            yield "SupportedPropertyNames", [], "Vec<DOMString>", False
                    else:
                        arguments = method_arguments(descriptor, rettype, arguments,
                                                     inRealm=name in descriptor.inRealmMethods,
                                                     canGc=name in descriptor.canGcMethods)
                    rettype = return_type(descriptor, rettype, infallible)
                    yield name, arguments, rettype, False

        def fmt(arguments: list[tuple[str, str]], leadingComma: bool = True) -> str:
            prefix = "" if not leadingComma else ", "
            return prefix + ", ".join(
                f"r#{name}: {type_}"
                for name, type_ in arguments
            )

        def contains_unsafe_arg(arguments: list[tuple[str, str]]) -> bool:
            if not arguments or len(arguments) == 0:
                return False
            return functools.reduce((lambda x, y: x or y[1] == '*mut JSContext'), arguments, False)

        methods = []
        exposureSet = list(descriptor.interface.exposureSet)
        exposedGlobal = "GlobalScope" if len(exposureSet) > 1 else exposureSet[0]
        hasLength = False
        for name, arguments, rettype, isStatic in members():
            if name == "Length":
                hasLength = True
            arguments = list(arguments)
            unsafe = 'unsafe ' if contains_unsafe_arg(arguments) else ''
            returnType = f" -> {rettype}" if rettype != '()' else ''
            selfArg = "&self" if not isStatic else ""
            extra = [("global", f"&D::{exposedGlobal}")] if isStatic else []
            if arguments and arguments[0][0] == "cx":
                arguments = [arguments[0]] + extra + arguments[1:]
            else:
                arguments = extra + arguments
            methods.append(CGGeneric(
                f"{unsafe}fn {name}({selfArg}"
                f"{fmt(arguments, leadingComma=not isStatic)}){returnType};\n"
            ))

        def ctorMethod(ctor: IDLMethod, baseName: str | None = None) -> Iterator[CGThing]:
            infallible = 'infallible' in descriptor.getExtendedAttributes(ctor)
            for (i, (rettype, arguments)) in enumerate(ctor.signatures()):
                name = (baseName or ctor.identifier.name) + ('_' * i)
                args = list(method_arguments(descriptor, rettype, arguments))
                extra = [
                    ("global", f"&D::{exposedGlobal}"),
                    ("proto", "Option<HandleObject>"),
                    ("can_gc", "CanGc"),
                ]
                if args and args[0][0] == "cx":
                    args = [args[0]] + extra + args[1:]
                else:
                    args = extra + args
                yield CGGeneric(
                    f"fn {name}({fmt(args, leadingComma=False)}) -> "
                    f"{return_type(descriptorProvider, rettype, infallible)};\n"
                )

        ctor = descriptor.interface.ctor()
        if ctor and not ctor.isHTMLConstructor():
            methods.extend(list(ctorMethod(ctor, "Constructor")))

        for ctor in descriptor.interface.legacyFactoryFunctions:
            methods.extend(list(ctorMethod(ctor)))

        if descriptor.operations['IndexedGetter'] and not hasLength:
            methods.append(CGGeneric("fn Length(&self) -> u32;\n"))

        name = descriptor.interface.identifier.name
        self.cgRoot = CGWrapper(CGIndenter(CGList(methods, "")),
                                pre=f"pub trait {name}Methods<D: DomTypes> {{\n",
                                post="}")
        self.empty = not methods

    def define(self) -> str:
        return self.cgRoot.define()


class CGWeakReferenceableTrait(CGThing):
    def __init__(self, descriptor: Descriptor) -> None:
        CGThing.__init__(self)
        assert descriptor.weakReferenceable
        self.code = f"impl WeakReferenceable for {descriptor.interface.identifier.name} {{}}"

    def define(self) -> str:
        return self.code


class CGInitStatics(CGThing):
    def __init__(self, descriptor: Descriptor) -> None:
        CGThing.__init__(self)

        def internal(method: IDLMethod) -> str:
            return descriptor.internalNameFor(method.identifier.name)

        properties = PropertyArrays(descriptor)
        all_names = PropertyArrays.arrayNames()
        arrays = [getattr(properties, name) for name in all_names]
        nonempty = map(lambda x: x.variableName(), filter(lambda x: x.length() != 0, arrays))
        specs = [[
            f'init_{name}_specs::<D>();',
            f'init_{name}_prefs::<D>();',
        ] for name in nonempty]
        flat_specs = [x for xs in specs for x in xs]
        specs = '\n'.join(flat_specs)
        module = f"crate::codegen::GenericBindings::{toBindingPath(descriptor)}"
        relevantMethods = [
            m for m in descriptor.interface.members if m.isMethod()
        ] if not descriptor.interface.isCallback() else []
        allOperations = descriptor.operations.keys()
        relevantOperations = list(map(lambda x: f"__{x.lower()}", filter(lambda o: o != "Stringifier", allOperations)))
        relevantMethods = filter(
            lambda m: internal(m) not in relevantOperations,
            relevantMethods,
        )
        relevantMethods = filter(
            lambda x: (
                not x.isStatic()
                or any([r.isPromise() for r, _ in x.signatures()])
            ),
            relevantMethods
        )

        methods = [f'{module}::init_{internal(m)}_methodinfo::<D>();' for m in relevantMethods]
        getters = [
            f'init_{internal(m)}_getterinfo::<D>();'
            for m in descriptor.interface.members if m.isAttr() and not m.isStatic()
        ]
        setters = [
            f'init_{internal(m)}_setterinfo::<D>();'
            for m in descriptor.interface.members
            if m.isAttr() and (
                not m.readonly
                or m.getExtendedAttribute("PutForwards")
                or m.getExtendedAttribute("Replaceable")
            ) and not m.isStatic()
        ]
        methods = '\n'.join(methods)
        getters = '\n'.join(getters)
        setters = '\n'.join(setters)
        crossorigin = [
            "init_sCrossOriginMethods::<D>();",
            "init_sCrossOriginAttributes::<D>();",
            "init_cross_origin_properties::<D>();"
        ] if descriptor.isMaybeCrossOriginObject() else []
        crossorigin_joined = '\n'.join(crossorigin)
        interface = (
            "init_interface_object::<D>();"
            if descriptor.interface.hasInterfaceObject()
            and not descriptor.interface.isNamespace()
            and not descriptor.interface.isCallback()
            and not descriptor.interface.getExtendedAttribute("Inline")
            else ""
        )
        nonproxy = (
            "init_domjs_class::<D>();"
            if not descriptor.proxy
            and descriptor.concrete
            else ""
        )

        self.code = f"""
        pub(crate) fn init_statics<D: DomTypes>() {{
            {interface}
            {nonproxy}
            {methods}
            {getters}
            {setters}
            {crossorigin_joined}
            {specs}
        }}
        """

    def define(self) -> str:
        return self.code


class CGDescriptor(CGThing):
    def __init__(self, descriptor: Descriptor, config: Configuration, soleDescriptor: bool) -> None:
        CGThing.__init__(self)

        assert not descriptor.concrete or not descriptor.interface.isCallback()

        reexports = []

        def reexportedName(name: str) -> str:
            if name.startswith(descriptor.name):
                return name
            if not soleDescriptor:
                return f'{name} as {descriptor.name}{name}'
            return name

        cgThings = []

        defaultToJSONMethod = None
        unscopableNames = []
        for m in descriptor.interface.members:
            if (m.isMethod()
                    and (not m.isIdentifierLess() or m == descriptor.operations["Stringifier"])):
                if m.getExtendedAttribute("Unscopable"):
                    assert not m.isStatic()
                    unscopableNames.append(m.identifier.name)
                if m.isDefaultToJSON():
                    defaultToJSONMethod = m
                elif m.isStatic():
                    assert descriptor.interface.hasInterfaceObject()
                    cgThings.append(CGStaticMethod(descriptor, m))
                    if m.returnsPromise():
                        cgThings.append(CGStaticMethodJitinfo(m))
                elif not descriptor.interface.isCallback():
                    cgThings.append(CGSpecializedMethod(descriptor, m))
                    if m.returnsPromise():
                        cgThings.append(
                            CGMethodPromiseWrapper(descriptor, m)
                        )
                    cgThings.append(CGMemberJITInfo(descriptor, m))
            elif m.isAttr():
                if m.getExtendedAttribute("Unscopable"):
                    assert not m.isStatic()
                    unscopableNames.append(m.identifier.name)
                if m.isStatic():
                    assert descriptor.interface.hasInterfaceObject()
                    cgThings.append(CGStaticGetter(descriptor, m))
                elif not descriptor.interface.isCallback():
                    cgThings.append(CGSpecializedGetter(descriptor, m))
                    if m.type.isPromise():
                        cgThings.append(
                            CGGetterPromiseWrapper(descriptor, m)
                        )

                if not m.readonly:
                    if m.isStatic():
                        assert descriptor.interface.hasInterfaceObject()
                        cgThings.append(CGStaticSetter(descriptor, m))
                    elif not descriptor.interface.isCallback():
                        cgThings.append(CGSpecializedSetter(descriptor, m))
                elif m.getExtendedAttribute("PutForwards"):
                    cgThings.append(CGSpecializedForwardingSetter(descriptor, m))
                elif m.getExtendedAttribute("Replaceable"):
                    cgThings.append(CGSpecializedReplaceableSetter(descriptor, m))

                if (not m.isStatic() and not descriptor.interface.isCallback()):
                    cgThings.append(CGMemberJITInfo(descriptor, m))

        if defaultToJSONMethod:
            cgThings.append(CGDefaultToJSONMethod(descriptor, defaultToJSONMethod))
            cgThings.append(CGMemberJITInfo(descriptor, defaultToJSONMethod))

        if descriptor.concrete:
            cgThings.append(CGClassFinalizeHook(descriptor))
            cgThings.append(CGClassTraceHook(descriptor))

        # If there are no constant members, don't make a module for constants
        constMembers = [CGConstant(m) for m in descriptor.interface.members if m.isConst()]
        if constMembers:
            cgThings.append(CGNamespace.build([f"{descriptor.name}Constants"],
                                              CGIndenter(CGList(constMembers)),
                                              public=True))
            reexports.append(f'{descriptor.name}Constants')

        if descriptor.proxy:
            cgThings.append(CGDefineProxyHandler(descriptor))

        if descriptor.isMaybeCrossOriginObject():
            cgThings.append(CGCrossOriginProperties(descriptor))

        properties = PropertyArrays(descriptor)

        if defaultToJSONMethod:
            cgThings.append(CGCollectJSONAttributesMethod(descriptor, defaultToJSONMethod))

        if descriptor.concrete:
            if descriptor.proxy:
                # cgThings.append(CGProxyIsProxy(descriptor))
                cgThings.append(CGProxyUnwrap(descriptor))
                cgThings.append(CGDOMJSProxyHandlerDOMClass(descriptor))
                cgThings.append(CGDOMJSProxyHandler_ownPropertyKeys(descriptor))
                if descriptor.interface.getExtendedAttribute("LegacyUnenumerableNamedProperties") or \
                   descriptor.isMaybeCrossOriginObject():
                    cgThings.append(CGDOMJSProxyHandler_getOwnEnumerablePropertyKeys(descriptor))
                cgThings.append(CGDOMJSProxyHandler_getOwnPropertyDescriptor(descriptor))
                cgThings.append(CGDOMJSProxyHandler_className(descriptor))
                cgThings.append(CGDOMJSProxyHandler_get(descriptor))
                cgThings.append(CGDOMJSProxyHandler_hasOwn(descriptor))

                if descriptor.isMaybeCrossOriginObject() or descriptor.operations['IndexedSetter'] or \
                   descriptor.operations['NamedSetter']:
                    cgThings.append(CGDOMJSProxyHandler_defineProperty(descriptor))

                # We want to prevent indexed deleters from compiling at all.
                assert not descriptor.operations['IndexedDeleter']

                if descriptor.isMaybeCrossOriginObject() or descriptor.operations['NamedDeleter']:
                    cgThings.append(CGDOMJSProxyHandler_delete(descriptor))

                if descriptor.isMaybeCrossOriginObject():
                    cgThings.append(CGDOMJSProxyHandler_getPrototype(descriptor))

                # cgThings.append(CGDOMJSProxyHandler(descriptor))
                # cgThings.append(CGIsMethod(descriptor))
                pass
            else:
                cgThings.append(CGDOMJSClass(descriptor))

            if descriptor.isGlobal():
                cgThings.append(CGWrapGlobalMethod(descriptor, properties))
            else:
                cgThings.append(CGWrapMethod(descriptor))
            reexports.append('Wrap')

        haveUnscopables = False
        if not descriptor.interface.isCallback() and not descriptor.interface.isNamespace():
            if unscopableNames:
                haveUnscopables = True
                cgThings.append(
                    CGList([CGGeneric("const unscopable_names: &[&std::ffi::CStr] = &["),
                            CGIndenter(CGList([CGGeneric(str_to_cstr(name)) for
                                               name in unscopableNames], ",\n")),
                            CGGeneric("];\n")], "\n"))

        if not descriptor.interface.isCallback():
            interfaceTrait = CGInterfaceTrait(descriptor, config.getDescriptorProvider())
            cgThings.append(interfaceTrait)
            if not interfaceTrait.empty:
                reexports.append(f'{descriptor.name}Methods')

        legacyWindowAliases = descriptor.interface.legacyWindowAliases
        haveLegacyWindowAliases = len(legacyWindowAliases) != 0
        if haveLegacyWindowAliases:
            cgThings.append(
                CGList([CGGeneric("const legacy_window_aliases: &[&std::ffi::CStr] = &["),
                        CGIndenter(CGList([CGGeneric(str_to_cstr(name)) for
                                           name in legacyWindowAliases], ",\n")),
                        CGGeneric("];\n")], "\n"))

        cgThings.append(CGGeneric(str(properties)))

        if not descriptor.interface.getExtendedAttribute("Inline"):
            if not descriptor.interface.isCallback() and not descriptor.interface.isNamespace():
                cgThings.append(CGGetProtoObjectMethod(descriptor))
                reexports.append('GetProtoObject')
                cgThings.append(CGPrototypeJSClass(descriptor))
            if descriptor.interface.hasInterfaceObject():
                if descriptor.interface.ctor():
                    cgThings.append(CGClassConstructHook(descriptor))
                for ctor in descriptor.interface.legacyFactoryFunctions:
                    cgThings.append(CGClassConstructHook(descriptor, ctor))
                if not descriptor.interface.isCallback():
                    cgThings.append(CGInterfaceObjectJSClass(descriptor))
                if descriptor.shouldHaveGetConstructorObjectMethod():
                    cgThings.append(CGGetConstructorObjectMethod(descriptor))
                    reexports.append('GetConstructorObject')
                if descriptor.register:
                    cgThings.append(CGDefineDOMInterfaceMethod(descriptor))
                    reexports.append('DefineDOMInterface')
                    cgThings.append(CGConstructorEnabled(descriptor))
            cgThings.append(CGCreateInterfaceObjectsMethod(descriptor, properties, haveUnscopables,
                                                           haveLegacyWindowAliases))

        cgThings.append(CGInitStatics(descriptor))

        cgThings = CGList(cgThings, '\n')

        # Add imports
        # These are inside the generated module
        cgThings = CGImports(cgThings, descriptors=[descriptor], callbacks=[],
                             dictionaries=[], enums=[], typedefs=[], imports=[
            'crate::import::module::*',
        ], config=config)

        cgThings = CGWrapper(CGNamespace(toBindingNamespace(descriptor.name),
                                         cgThings, public=True),
                             post='\n')

        if reexports:
            reexports = ', '.join([reexportedName(name) for name in reexports])
            namespace = toBindingNamespace(descriptor.name)
            cgThings = CGList([CGGeneric(f'pub use self::{namespace}::{{{reexports}}};'),
                               cgThings], '\n')

        self.cgRoot = cgThings

    def define(self) -> str:
        return self.cgRoot.define()


class CGNonNamespacedEnum(CGThing):
    def __init__(self, enumName: str, names: list[str], first: int, comment: str = "", deriving: str = "", repr: str = "") -> None:
        # Account for first value
        entries = [f"{names[0]} = {first}"] + names[1:]

        # Append a Last.
        entries.append(f'#[allow(dead_code)] Last = {first + len(entries)}')

        # Indent.
        entries = [f'    {e}' for e in entries]

        # Build the enum body.
        joinedEntries = ',\n'.join(entries)
        enumstr = f"{comment}pub enum {enumName} {{\n{joinedEntries}\n}}\n"
        if repr:
            enumstr = f"#[repr({repr})]\n{enumstr}"
        if deriving:
            enumstr = f"#[derive({deriving})]\n{enumstr}"
        curr = CGGeneric(enumstr)

        # Add some whitespace padding.
        curr = CGWrapper(curr, pre='\n', post='\n')

        # Add the typedef
        # typedef = '\ntypedef %s::%s %s;\n\n' % (namespace, enumName, enumName)
        # curr = CGList([curr, CGGeneric(typedef)])

        # Save the result.
        self.node = curr

    def define(self) -> str:
        return self.node.define()


class CGDictionary(CGThing):
    def __init__(self, dictionary: IDLDictionary, descriptorProvider: DescriptorProvider, config: Configuration) -> None:
        self.dictionary = dictionary
        derivesList = config.getDictConfig(dictionary.identifier.name).get('derives', [])
        self.manualImpls = list(filter(lambda t: traitRequiresManualImpl(t, self.dictionary), derivesList))
        self.derives = list(filter(lambda t: not traitRequiresManualImpl(t, self.dictionary), derivesList))
        if all(CGDictionary(d, descriptorProvider, config).generatable for
               d in CGDictionary.getDictionaryDependencies(dictionary)):
            self.generatable = True
        else:
            self.generatable = False
            # Nothing else to do here
            return

        self.generic, self.genericSuffix = genericsForType(self.dictionary)

        self.memberInfo: list[tuple[IDLArgument, JSToNativeConversionInfo]] = [
            (member,
             getJSToNativeConversionInfo(member.type,
                                         descriptorProvider,
                                         isMember="Dictionary",
                                         defaultValue=member.defaultValue,
                                         exceptionCode="return Err(());\n"))
            for member in dictionary.members]

    def define(self) -> str:
        if not self.generatable:
            return ""
        return f"{self.struct()}\n{self.impl()}"

    def manualImplClone(self) -> str:
        members = []
        for m in self.memberInfo:
            memberName = self.makeMemberName(m[0].identifier.name)
            members += [f"            {memberName}: self.{memberName}.clone(),"]
        if self.dictionary.parent:
            members += ["            parent: parent.clone(),"]
        members = "\n".join(members)
        return f"""
#[allow(clippy::clone_on_copy)]
impl{self.generic} Clone for {self.makeClassName(self.dictionary)}{self.genericSuffix} {{
    fn clone(&self) -> Self {{
        Self {{
{members}
        }}
    }}
}}
"""

    def manualImpl(self, t: str) -> str:
        if t == "Clone":
            return self.manualImplClone()
        raise ValueError(f"Don't know how to impl {t} for dicts.")

    def struct(self) -> str:
        d = self.dictionary
        if d.parent:
            assert isinstance(d.parent, IDLDictionary)
            typeName = f"{self.makeModuleName(d.parent)}::{self.makeClassName(d.parent)}"
            _, parentSuffix = genericsForType(d.parent)
            typeName += parentSuffix
            if type_needs_tracing(d.parent):
                typeName = f"RootedTraceableBox<{typeName}>"
            inheritance = f"    pub parent: {typeName},\n"
        else:
            inheritance = ""
        memberDecls = [f"    pub {self.makeMemberName(m[0].identifier.name)}: {self.getMemberType(m)},"
                       for m in self.memberInfo]

        derive = ["JSTraceable"] + self.derives
        default = ""
        mustRoot = ""
        if self.membersNeedTracing():
            mustRoot = "#[cfg_attr(crown, crown::unrooted_must_root_lint::must_root)]\n"

        # We can't unconditionally derive Default here, because union types can have unique
        # default values provided for each usage. Instead, whenever possible we re-use the empty()
        # method that is generated.
        if not self.hasRequiredFields(self.dictionary):
            if d.parent:
                inheritanceDefault = "        parent: Default::default(),\n"
            else:
                inheritanceDefault = ""
            if not self.membersNeedTracing():
                impl = "        Self::empty()\n"
            else:
                memberDefaults = [f"        {self.makeMemberName(m[0].identifier.name)}: Default::default(),"
                                  for m in self.memberInfo]
                joinedDefaults = '\n'.join(memberDefaults)
                impl = (
                    "        Self {\n"
                    f"            {inheritanceDefault}{joinedDefaults}"
                    "        }\n"
                )

            default = (
                f"impl{self.generic} Default for {self.makeClassName(d)}{self.genericSuffix} {{\n"
                "    fn default() -> Self {\n"
                f"{impl}"
                "    }\n"
                "}\n"
            )

        manualImpls = "\n".join(map(lambda t: self.manualImpl(t), self.manualImpls))
        joinedMemberDecls = '\n'.join(memberDecls)
        return (
            f"#[derive({', '.join(derive)})]\n"
            f"{mustRoot}"
            f"pub struct {self.makeClassName(d)}{self.generic} {{\n"
            f"{inheritance}"
            f"{joinedMemberDecls}\n"
            "}\n"
            f"{manualImpls}"
            f"{default}"
        )

    def impl(self) -> str:
        d = self.dictionary
        if d.parent:
            assert isinstance(d.parent, IDLDictionary)
            initParent = (
                "{\n"
                f"    match {self.makeModuleName(d.parent)}::{self.makeClassName(d.parent)}::new(cx, val, can_gc)? {{\n"
                "        ConversionResult::Success(v) => v,\n"
                "        ConversionResult::Failure(error) => {\n"
                "            throw_type_error(*cx, &error);\n"
                "            return Err(());\n"
                "        }\n"
                "    }\n"
                "}"
            )
        else:
            initParent = ""

        def memberInit(memberInfo: tuple[IDLArgument, JSToNativeConversionInfo]) -> CGThing:
            member, _ = memberInfo
            name = self.makeMemberName(member.identifier.name)
            conversion = self.getMemberConversion(memberInfo, member.type)
            return CGGeneric(f"{name}: {conversion.define()},\n")

        def varInsert(varName: str, dictionaryName: str) -> CGThing:
            insertion = (
                f"rooted!(in(cx) let mut {varName}_js = UndefinedValue());\n"
                f"{varName}.to_jsval(cx, {varName}_js.handle_mut());\n"
                f'set_dictionary_property(SafeJSContext::from_ptr(cx), obj.handle(), "{dictionaryName}", {varName}_js.handle()).unwrap();')
            return CGGeneric(insertion)

        def memberInsert(memberInfo: tuple[IDLArgument, JSToNativeConversionInfo]) -> CGThing:
            member, _ = memberInfo
            name = self.makeMemberName(member.identifier.name)
            if member.optional and not member.defaultValue:
                insertion = CGIfWrapper(f"let Some(ref {name}) = self.{name}",
                                        varInsert(name, member.identifier.name))
            else:
                insertion = CGGeneric(f"let {name} = &self.{name};\n"
                                      f"{varInsert(name, member.identifier.name).define()}")
            return CGGeneric(f"{insertion.define()}\n")

        memberInserts = [memberInsert(m) for m in self.memberInfo]

        if d.parent:
            memberInserts = [CGGeneric("self.parent.to_jsobject(cx, obj.reborrow());\n")] + memberInserts

        selfName = self.makeClassName(d)
        if self.membersNeedTracing():
            actualType = f"RootedTraceableBox<{selfName}{self.genericSuffix}>"
            preInitial = f"let dictionary = RootedTraceableBox::new({selfName} {{\n"
            postInitial = "});\n"
        else:
            actualType = f"{selfName}{self.genericSuffix}"
            preInitial = f"let dictionary = {selfName} {{\n"
            postInitial = "};\n"
        initParent = f"parent: {initParent},\n" if initParent else ""
        memberInits = CGList([memberInit(member) for member in self.memberInfo])

        unsafe_if_necessary = "unsafe"
        if not initParent and not memberInits:
            unsafe_if_necessary = ""
        return (
            f"impl{self.generic} {selfName}{self.genericSuffix} {{\n"
            f"{CGIndenter(CGGeneric(self.makeEmpty()), indentLevel=4).define()}\n"
            "    pub fn new(cx: SafeJSContext, val: HandleValue, can_gc: CanGc) \n"
            f"                      -> Result<ConversionResult<{actualType}>, ()> {{\n"
            f"        {unsafe_if_necessary} {{\n"
            "            let object = if val.get().is_null_or_undefined() {\n"
            "                ptr::null_mut()\n"
            "            } else if val.get().is_object() {\n"
            "                val.get().to_object()\n"
            "            } else {\n"
            "                return Ok(ConversionResult::Failure(\"Value is not an object.\".into()));\n"
            "            };\n"
            "            rooted!(in(*cx) let object = object);\n"
            f"{CGIndenter(CGGeneric(preInitial), indentLevel=8).define()}"
            f"{CGIndenter(CGGeneric(initParent), indentLevel=16).define()}"
            f"{CGIndenter(memberInits, indentLevel=16).define()}"
            f"{CGIndenter(CGGeneric(postInitial), indentLevel=8).define()}"
            "            Ok(ConversionResult::Success(dictionary))\n"
            "        }\n"
            "    }\n"
            "}\n"
            "\n"
            f"impl{self.generic} FromJSValConvertible for {actualType} {{\n"
            "    type Config = ();\n"
            "    unsafe fn from_jsval(cx: *mut JSContext, value: HandleValue, _option: ())\n"
            f"                         -> Result<ConversionResult<{actualType}>, ()> {{\n"
            f"        {selfName}::new(SafeJSContext::from_ptr(cx), value, CanGc::note())\n"
            "    }\n"
            "}\n"
            "\n"
            f"impl{self.generic} {selfName}{self.genericSuffix} {{\n"
            "    #[allow(clippy::wrong_self_convention)]\n"
            "    pub unsafe fn to_jsobject(&self, cx: *mut JSContext, mut obj: MutableHandleObject) {\n"
            f"{CGIndenter(CGList(memberInserts), indentLevel=8).define()}    }}\n"
            "}\n"
            "\n"
            f"impl{self.generic} ToJSValConvertible for {selfName}{self.genericSuffix} {{\n"
            "    unsafe fn to_jsval(&self, cx: *mut JSContext, mut rval: MutableHandleValue) {\n"
            "        rooted!(in(cx) let mut obj = JS_NewObject(cx, ptr::null()));\n"
            "        self.to_jsobject(cx, obj.handle_mut());\n"
            "        rval.set(ObjectOrNullValue(obj.get()))\n"
            "    }\n"
            "}\n"
        )

    def membersNeedTracing(self) -> bool:
        return type_needs_tracing(self.dictionary)

    @staticmethod
    def makeDictionaryName(dictionary: IDLDictionary | IDLWrapperType) -> str:
        if isinstance(dictionary, IDLWrapperType):
            return CGDictionary.makeDictionaryName(dictionary.inner)
        else:
            assert isinstance(dictionary, IDLDictionary)
            return dictionary.identifier.name

    def makeClassName(self, dictionary: IDLDictionary | IDLWrapperType) -> str:
        return self.makeDictionaryName(dictionary)

    @staticmethod
    def makeModuleName(dictionary: IDLDictionary | IDLWrapperType) -> str:
        return getModuleFromObject(dictionary)

    def getMemberType(self, memberInfo: tuple[IDLArgument, JSToNativeConversionInfo]) -> str:
        member, info = memberInfo
        assert info.declType is not None
        declType = info.declType
        if member.optional and not member.defaultValue:
            declType = CGWrapper(info.declType, pre="Option<", post=">")
        return declType.define()

    def getMemberConversion(self, memberInfo: tuple[IDLArgument, JSToNativeConversionInfo], memberType: IDLType) -> CGThing:
        def indent(s: str) -> str:
            return CGIndenter(CGGeneric(s), 12).define()

        member, info = memberInfo
        templateBody = info.template
        default = info.default
        replacements = {"val": "rval.handle()"}
        conversion = string.Template(templateBody).substitute(replacements)

        assert (member.defaultValue is None) == (default is None)
        if not member.optional:
            assert default is None
            default = (f'throw_type_error(*cx, "Missing required member \\"{member.identifier.name}\\".");\n'
                       "return Err(());")
        elif not default:
            default = "None"
            conversion = f"Some({conversion})"

        conversion = (
            "{\n"
            "    rooted!(in(*cx) let mut rval = UndefinedValue());\n"
            "    if get_dictionary_property(*cx, object.handle(), "
            f'"{member.identifier.name}", '
            "rval.handle_mut(), can_gc)? && !rval.is_undefined() {\n"
            f"{indent(conversion)}\n"
            "    } else {\n"
            f"{indent(default)}\n"
            "    }\n"
            "}")

        return CGGeneric(conversion)

    def makeEmpty(self) -> str:
        if self.hasRequiredFields(self.dictionary):
            return ""
        parentTemplate = "parent: %s::%s::empty(),\n"
        fieldTemplate = "%s: %s,\n"
        functionTemplate = (
            "pub fn empty() -> Self {\n"
            "    Self {\n"
            "%s"
            "    }\n"
            "}"
        )
        if self.membersNeedTracing():
            parentTemplate = "dictionary.parent = %s::%s::empty();\n"
            fieldTemplate = "dictionary.%s = %s;\n"
            functionTemplate = (
                "pub fn empty() -> RootedTraceableBox<Self> {\n"
                "    let mut dictionary = RootedTraceableBox::new(Self::default());\n"
                "%s"
                "    dictionary\n"
                "}"
            )
        s = ""
        if self.dictionary.parent:
            assert isinstance(self.dictionary.parent, IDLDictionary)
            s += parentTemplate % (self.makeModuleName(self.dictionary.parent),
                                   self.makeClassName(self.dictionary.parent))
        for member, info in self.memberInfo:
            if not member.optional:
                return ""
            default = info.default
            if not default:
                default = "None"
            s += fieldTemplate % (self.makeMemberName(member.identifier.name), default)
        return functionTemplate % CGIndenter(CGGeneric(s), 12).define()

    def hasRequiredFields(self, dictionary: IDLDictionary) -> bool:
        if dictionary.parent:
            assert isinstance(dictionary.parent, IDLDictionary)
            if self.hasRequiredFields(dictionary.parent):
                return True
        for member in dictionary.members:
            if not member.optional:
                return True
        return False

    @staticmethod
    def makeMemberName(name: str) -> str:
        # Can't use Rust keywords as member names.
        if name in RUST_KEYWORDS:
            return f"{name}_"
        return name

    @staticmethod
    def getDictionaryDependencies(dictionary: IDLDictionary) -> set[IDLDictionary]:
        deps = set()
        if dictionary.parent:
            assert isinstance(dictionary.parent, IDLDictionary)
            deps.add(dictionary.parent)
        for member in dictionary.members:
            if member.type.isDictionary():
                deps.add(member.type.unroll().inner)
        return deps


class CGInitAllStatics(CGAbstractMethod):
    def __init__(self, config: Configuration) -> None:
        docs = "Initialize the static data used by the SpiderMonkey DOM bindings to implement JS interfaces."
        descriptors = (config.getDescriptors(isCallback=False, register=True)
                       + config.getDescriptors(isCallback=True, hasInterfaceObject=True, register=True))
        # FIXME: pass in a valid descriptor somehow
        # pyrefly: ignore  # bad-argument-type
        CGAbstractMethod.__init__(self, None, 'InitAllStatics', 'void', [],
                                  pub=True, docs=docs, templateArgs=["D: DomTypes"])
        self.descriptors = descriptors

    def definition_body(self) -> CGThing:
        return CGList([
            CGGeneric(f"    GenericBindings::{toBindingModuleFileFromDescriptor(desc)}::{toBindingNamespace(desc.name)}"
                      "::init_statics::<D>();")
            for desc in self.descriptors
        ], "\n")


class CGRegisterProxyHandlersMethod(CGAbstractMethod):
    def __init__(self, descriptors: list[Descriptor]) -> None:
        docs = "Create the global vtables used by the generated DOM bindings to implement JS proxies."
        # FIXME: pass in a valid descriptor somehow
        # pyrefly: ignore  # bad-argument-type
        CGAbstractMethod.__init__(self, None, 'RegisterProxyHandlers', 'void', [],
                                  pub=True, docs=docs, templateArgs=["D: DomTypes"])
        self.descriptors = descriptors

    def definition_body(self) -> CGThing:
        body = [CGGeneric("unsafe {")]
        body += [
            CGGeneric(f"proxy_handlers::{desc.name}.store(\n"
                      f"    GenericBindings::{toBindingModuleFile(desc.name)}::{toBindingNamespace(desc.name)}"
                      "::DefineProxyHandler::<D>() as *mut _,\n"
                      "    std::sync::atomic::Ordering::Release,\n"
                      ");")
            for desc in self.descriptors
        ]
        body += [CGGeneric("}")]
        return CGList(body, "\n")


class CGRegisterProxyHandlers(CGThing):
    def __init__(self, config: Configuration) -> None:
        descriptors = config.getDescriptors(proxy=True)
        body = "".join(
            f"    pub(crate) static {desc.name}: std::sync::atomic::AtomicPtr<libc::c_void> =\n"
            "        std::sync::atomic::AtomicPtr::new(std::ptr::null_mut());\n"
            for desc in descriptors
        )
        self.root = CGList([
            CGGeneric(
                "#[allow(non_upper_case_globals)]\n"
                "pub(crate) mod proxy_handlers {\n"
                f"{body}}}\n"
            ),
            CGRegisterProxyHandlersMethod(descriptors),
        ], "\n")

    def define(self) -> str:
        return self.root.define()


class CGStructuredCloneMarker(CGThing):
    """
    Generate a type assertion for inheritance
    """
    def __init__(self, descriptor: Descriptor, marker: str) -> None:
        CGThing.__init__(self)
        self.descriptor = descriptor
        self.marker = marker
        self.marker_lower = marker.lower()

    def define(self) -> str:
        ifaceName = self.descriptor.interface.identifier.name
        return f"""
impl script_bindings::structuredclone::MarkedAs{self.marker}InIdl for {ifaceName} {{
    #[allow(path_statements)]
    fn assert_{self.marker_lower}() {{
        crate::dom::bindings::{self.marker_lower}::assert_{self.marker_lower}::<Self>;
    }}
}}
"""


class CGConcreteBindingRoot(CGThing):
    """
    Root codegen class for binding generation, specialized on the concrete
    type that is used by handwritten code. Re-export all public types from
    the generic bindings with type specialization applied.
    """
    root: CGThing | None
    def __init__(self, config: Configuration, prefix: str, webIDLFile: str) -> None:
        descriptors = config.getDescriptors(webIDLFile=webIDLFile,
                                            hasInterfaceObject=True)
        # We also want descriptors that have an interface prototype object
        # (isCallback=False), but we don't want to include a second copy
        # of descriptors that we also matched in the previous line
        # (hence hasInterfaceObject=False).
        descriptors.extend(config.getDescriptors(webIDLFile=webIDLFile,
                                                 hasInterfaceObject=False,
                                                 isCallback=False,
                                                 register=True))

        dictionaries = config.getDictionaries(webIDLFile=webIDLFile)

        mainCallbacks = config.getCallbacks(webIDLFile=webIDLFile)
        callbackDescriptors = config.getDescriptors(webIDLFile=webIDLFile,
                                                    isCallback=True)

        enums = config.getEnums(webIDLFile)
        typedefs = config.getTypedefs(webIDLFile)

        if not (descriptors or dictionaries or mainCallbacks or callbackDescriptors or enums):
            self.root = None
            return

        originalBinding = f"crate::dom::bindings::codegen::{prefix.replace('/', '::').replace('Concrete', 'Generic')}"

        cgthings = []
        for e in enums:
            enumName = e.identifier.name
            cgthings += [
                CGGeneric(f"pub(crate) use {originalBinding}::{enumName} as {enumName};"),
                CGGeneric(f"pub(crate) use {originalBinding}::{enumName}Values as {enumName}Values;"),
            ]

        cgthings += [CGGeneric(
            f"pub(crate) type {t.identifier.name} = "
            f"{originalBinding}::{t.identifier.name}"
            f"{'::<crate::DomTypeHolder>' if containsDomInterface(t.innerType) else ''};"
        ) for t in typedefs]

        cgthings += [CGGeneric(
            f"pub(crate) type {d.identifier.name} = "
            f"{originalBinding}::{d.identifier.name}"
            f"{'::<crate::DomTypeHolder>' if containsDomInterface(d) else ''};"
        ) for d in dictionaries]

        cgthings += [CGGeneric(
            f"pub(crate) type {c.identifier.name} = "
            f"{originalBinding}::{c.identifier.name}<crate::DomTypeHolder>;"
        ) for c in mainCallbacks]

        cgthings += [CGGeneric(f"pub(crate) use {originalBinding} as GenericBindings;")]
        for d in descriptors:
            ifaceName = d.interface.identifier.name
            cgthings += [
                CGGeneric(
                    f"pub(crate) use {originalBinding}::{firstCap(ifaceName)}_Binding as {firstCap(ifaceName)}_Binding;"
                ),
            ]

            for marker in ["Serializable", "Transferable"]:
                if d.interface.getExtendedAttribute(marker):
                    cgthings += [CGStructuredCloneMarker(d, marker)]

            if d.concrete:
                if not d.interface.isIteratorInterface():
                    cgthings.append(CGAssertInheritance(d))
                else:
                    cgthings.append(CGIteratorDerives(d))

            if (
                (d.concrete or d.hasDescendants())
                and not d.interface.isIteratorInterface()
            ):
                cgthings.append(CGIDLInterface(d))

            if d.interface.isIteratorInterface():
                cgthings.append(CGDomObjectIteratorWrap(d))
            elif d.concrete and not d.isGlobal():
                cgthings.append(CGDomObjectWrap(d))

            if d.weakReferenceable:
                cgthings.append(CGWeakReferenceableTrait(d))

            if not d.interface.isCallback():
                traitName = f"{ifaceName}Methods"
                cgthings += [
                    CGGeneric(f"pub(crate) use self::{firstCap(ifaceName)}_Binding::{traitName} as {traitName};"),
                ]
                if len(descriptors) == 1 and d.concrete:
                    cgthings += [CGGeneric(f"pub(crate) use self::{firstCap(ifaceName)}_Binding::Wrap;")]
                    if d.interface.hasInterfaceObject() and d.shouldHaveGetConstructorObjectMethod():
                        cgthings += [CGGeneric(f"""
pub(crate) fn GetConstructorObject(
    cx: SafeJSContext, global: HandleObject, rval: MutableHandleObject
) {{
    self::{firstCap(ifaceName)}_Binding::GetConstructorObject::<crate::DomTypeHolder>(cx, global, rval)
}}
""")]

            constMembers = [m for m in d.interface.members if m.isConst()]
            if constMembers:
                constants = f"{ifaceName}Constants"
                cgthings += [CGGeneric(f"pub(crate) use {originalBinding}::{constants} as {constants};")]

        for c in callbackDescriptors:
            ifaceName = c.interface.identifier.name
            cgthings += [CGGeneric(
                f"pub(crate) type {ifaceName} = {originalBinding}::{ifaceName}<crate::DomTypeHolder>;"
            )]

        # And make sure we have the right number of newlines at the end
        curr = CGWrapper(CGList(cgthings, "\n\n"), post="\n\n")

        # Add imports
        # These are the global imports (outside of the generated module)
        curr = CGImports(curr, descriptors=[], callbacks=[],
                         dictionaries=[], enums=[], typedefs=[],
                         imports=[
                             'crate::dom::bindings::import::module::*',
                             'crate::dom::types::*'],
                         config=config)

        # Add the auto-generated comment.
        curr = CGWrapper(curr, pre=f"{AUTOGENERATED_WARNING_COMMENT}{ALLOWED_WARNINGS}")

        # Store the final result.
        self.root = curr

    def define(self) -> str:
        if not self.root:
            return ""
        return stripTrailingWhitespace(self.root.define())


class CGBindingRoot(CGThing):
    """
    Root codegen class for binding generation. Instantiate the class, and call
    declare or define to generate header or cpp code (respectively).
    """
    root: CGThing | None
    def __init__(self, config: Configuration, prefix: str, webIDLFile: str) -> None:
        descriptors = config.getDescriptors(webIDLFile=webIDLFile,
                                            hasInterfaceObject=True)
        # We also want descriptors that have an interface prototype object
        # (isCallback=False), but we don't want to include a second copy
        # of descriptors that we also matched in the previous line
        # (hence hasInterfaceObject=False).
        descriptors.extend(config.getDescriptors(webIDLFile=webIDLFile,
                                                 hasInterfaceObject=False,
                                                 isCallback=False,
                                                 register=True))

        dictionaries = config.getDictionaries(webIDLFile=webIDLFile)

        mainCallbacks = config.getCallbacks(webIDLFile=webIDLFile)
        callbackDescriptors = config.getDescriptors(webIDLFile=webIDLFile,
                                                    isCallback=True)

        enums = config.getEnums(webIDLFile)
        typedefs = config.getTypedefs(webIDLFile)

        if not (descriptors or dictionaries or mainCallbacks or callbackDescriptors or enums):
            self.root = None
            return

        # Do codegen for all the enums.
        cgthings: list = [CGEnum(e, config) for e in enums]

        # Do codegen for all the typedefs
        for t in typedefs:
            typeName = getRetvalDeclarationForType(t.innerType, config.getDescriptorProvider())
            name = t.identifier.name
            type = typeName.define()

            if t.innerType.isUnion() and not t.innerType.nullable():
                # Allow using the typedef's name for accessing variants.
                typeDefinition = f"pub use self::{type.replace('<D>', '')} as {name};"
            else:
                generic = "<D>" if containsDomInterface(t.innerType) else ""
                replacedType = type.replace("D::", "<D as DomTypes>::")
                typeDefinition = f"pub type {name}{generic} = {replacedType};"

            cgthings.append(CGGeneric(typeDefinition))

        # Do codegen for all the dictionaries.
        cgthings.extend([CGDictionary(d, config.getDescriptorProvider(), config)
                         for d in dictionaries])

        # Do codegen for all the callbacks.
        cgthings.extend(CGList([CGCallbackFunction(c, config.getDescriptorProvider()),
                                CGCallbackFunctionImpl(c)], "\n")
                        for c in mainCallbacks)

        # Do codegen for all the descriptors
        cgthings.extend([CGDescriptor(x, config, len(descriptors) == 1) for x in descriptors])

        # Do codegen for all the callback interfaces.
        cgthings.extend(CGList(
            [
                CGCallbackInterface(x),
                CGCallbackFunctionImpl(assert_type(x.interface, IDLInterface))
            ],
            "\n"
        ) for x in callbackDescriptors)

        # And make sure we have the right number of newlines at the end
        curr = CGWrapper(CGList(cgthings, "\n\n"), post="\n\n")

        # Add imports
        # These are the global imports (outside of the generated module)
        curr = CGImports(curr, descriptors=callbackDescriptors, callbacks=mainCallbacks,
                         dictionaries=dictionaries, enums=enums, typedefs=typedefs,
                         imports=['crate::import::base::*'], config=config)

        # Add the auto-generated comment.
        curr = CGWrapper(curr, pre=f"{AUTOGENERATED_WARNING_COMMENT}{ALLOWED_WARNINGS}")

        # Store the final result.
        self.root = curr

    def define(self) -> str:
        if not self.root:
            return ""
        return stripTrailingWhitespace(self.root.define())


def type_needs_tracing(t: IDLObject) -> bool:
    assert isinstance(t, IDLObject), (t, type(t))

    if t.isType():
        assert isinstance(t, IDLType)
        if isinstance(t, IDLWrapperType):
            return type_needs_tracing(t.inner)

        if t.nullable():
            assert isinstance(t, IDLNullableType)
            return type_needs_tracing(t.inner)

        if t.isAny():
            return True

        if t.isObject():
            return True

        if t.isSequence() :
            assert isinstance(t, IDLSequenceType)
            return type_needs_tracing(t.inner)

        if t.isUnion():
            assert isinstance(t, IDLUnionType) and t.flatMemberTypes is not None
            return any(type_needs_tracing(member) for member in t.flatMemberTypes)

        if is_typed_array(t):
            return True

        return False

    if t.isDictionary():
        assert isinstance(t, IDLDictionary)
        if t.parent and type_needs_tracing(t.parent):
            return True

        if any(type_needs_tracing(member.type) for member in t.members):
            return True

        return False

    if t.isInterface():
        return False

    if t.isEnum():
        return False

    assert False, (t, type(t))
    return False


def is_typed_array(t: IDLType) -> bool:
    assert isinstance(t, IDLObject), (t, type(t))

    return t.isTypedArray() or t.isArrayBuffer() or t.isArrayBufferView()


def type_needs_auto_root(t: IDLType) -> bool:
    """
    Certain IDL types, such as `sequence<any>` or `sequence<object>` need to be
    traced and wrapped via (Custom)AutoRooter
    """
    assert isinstance(t, IDLObject), (t, type(t))

    if t.isType():
        if t.isSequence() and (t.inner.isAny() or t.inner.isObject()):
            return True
        # SpiderMonkey interfaces, we currently don't support any other except typed arrays
        if is_typed_array(t):
            return True

    return False


DefaultValueType = IDLValue | IDLNullValue | IDLUndefinedValue | IDLDefaultDictionaryValue | IDLEmptySequenceValue


def argument_type(descriptorProvider: DescriptorProvider,
                  ty: IDLType,
                  optional: bool = False,
                  defaultValue: DefaultValueType | None = None,
                  variadic: bool = False
                  ) -> str:
    info = getJSToNativeConversionInfo(
        ty, descriptorProvider, isArgument=True,
        isAutoRooted=type_needs_auto_root(ty))
    declType = info.declType
    assert declType is not None
    if variadic:
        if ty.isGeckoInterface():
            declType = CGWrapper(declType, pre="&[", post="]")
        else:
            declType = CGWrapper(declType, pre="Vec<", post=">")
    elif optional and not defaultValue:
        declType = CGWrapper(declType, pre="Option<", post=">")

    if ty.isDictionary() and not type_needs_tracing(ty):
        declType = CGWrapper(declType, pre="&")

    if type_needs_auto_root(ty):
        declType = CGTemplatedType("CustomAutoRooterGuard", declType)

    assert declType is not None
    return declType.define()


def method_arguments(descriptorProvider: DescriptorProvider,
                     returnType: IDLType,
                     arguments: list[IDLArgument],
                     passJSBits: bool = True,
                     trailing: tuple[str, str] | None = None,
                     inRealm: bool = False,
                     canGc: bool = False
                     ) -> Iterator[tuple[str, str]]:
    if needCx(returnType, arguments, passJSBits):
        yield "cx", "SafeJSContext"

    for argument in arguments:
        ty = argument_type(descriptorProvider, argument.type, argument.optional,
                           argument.defaultValue, argument.variadic)
        yield CGDictionary.makeMemberName(argument.identifier.name), ty

    if trailing:
        yield trailing

    if inRealm:
        yield "_comp", "InRealm"

    if canGc:
        yield "_can_gc", "CanGc"

    if returnTypeNeedsOutparam(returnType):
        yield "rval", outparamTypeFromReturnType(returnType),


def return_type(descriptorProvider: DescriptorProvider, rettype: IDLType, infallible: bool) -> str:
    result = getRetvalDeclarationForType(rettype, descriptorProvider)
    if rettype and returnTypeNeedsOutparam(rettype):
        result = CGGeneric("()")
    if not infallible:
        result = CGWrapper(result, pre="Fallible<", post=">")
    return result.define()


class CGNativeMember(ClassMethod):
    def __init__(self, descriptorProvider: DescriptorProvider, member: IDLMethod, name: str, signature: tuple[IDLType, list[IDLArgument]], extendedAttrs: dict[str, Any],
                 breakAfter: bool = True, passJSBitsAsNeeded: bool = True, visibility: str = "public",
                 unsafe: bool = False) -> None:
        """
        If passJSBitsAsNeeded is false, we don't automatically pass in a
        JSContext* or a JSObject* based on the return and argument types.
        """
        self.descriptorProvider = descriptorProvider
        self.member = member
        self.extendedAttrs = extendedAttrs
        self.passJSBitsAsNeeded = passJSBitsAsNeeded
        breakAfterSelf = "\n" if breakAfter else ""
        ClassMethod.__init__(self, name,
                             self.getReturnType(signature[0]),
                             self.getArgs(signature[0], signature[1]),
                             static=member.isStatic(),
                             # Mark our getters, which are attrs that
                             # have a non-void return type, as const.
                             const=(not member.isStatic() and member.isAttr()
                                    and not signature[0].isUndefined()),
                             breakAfterSelf=breakAfterSelf,
                             unsafe=unsafe,
                             visibility=visibility)

    def getReturnType(self, type: IDLType) -> str:
        infallible = 'infallible' in self.extendedAttrs
        typeDecl = return_type(self.descriptorProvider, type, infallible)
        return typeDecl

    def getArgs(self, returnType: IDLType, argList: list[IDLArgument]) -> list[Argument]:
        return [Argument(arg[1], arg[0]) for arg in method_arguments(self.descriptorProvider,
                                                                     returnType,
                                                                     argList,
                                                                     self.passJSBitsAsNeeded)]


class CGCallback(CGClass):
    def __init__(self, idlObject: IDLCallback, descriptorProvider: DescriptorProvider, baseName: str, methods: list[CallbackMethod]) -> None:
        self.baseName = baseName
        self._deps = idlObject.getDeps()
        name = idlObject.identifier.name
        # For our public methods that needThisHandling we want most of the
        # same args and the same return type as what CallbackMember
        # generates.  So we want to take advantage of all its
        # CGNativeMember infrastructure, but that infrastructure can't deal
        # with templates and most especially template arguments.  So just
        # cheat and have CallbackMember compute all those things for us.
        realMethods = []
        for method in methods:
            if not method.needThisHandling:
                realMethods.append(method)
            else:
                realMethods.extend(self.getMethodImpls(method))
        CGClass.__init__(self, name,
                         bases=[ClassBase(baseName)],
                         constructors=self.getConstructors(),
                         methods=realMethods,
                         templateSpecialization=['D: DomTypes'],
                         decorators="#[derive(JSTraceable, MallocSizeOf, PartialEq)]\n"
                                    "#[cfg_attr(crown, allow(crown::unrooted_must_root))]\n"
                                    "#[cfg_attr(crown, crown::unrooted_must_root_lint::allow_unrooted_interior)]")

    def getConstructors(self) -> list[ClassConstructor]:
        return [ClassConstructor(
            [Argument("SafeJSContext", "aCx"), Argument("*mut JSObject", "aCallback")],
            bodyInHeader=True,
            visibility="pub",
            explicit=False,
            baseConstructors=[
                f"{self.baseName.replace('<D>', '')}::new()"
            ])]

    def getMethodImpls(self, method: CallbackMethod) -> list[ClassMethod]:
        assert method.needThisHandling
        args = list(method.args)
        # Strip out the JSContext*/JSObject* args
        # that got added.
        assert args[0].name == "cx" and args[0].argType == "SafeJSContext"
        assert args[1].name == "aThisObj" and args[1].argType == "HandleValue"
        args = args[2:]
        # Record the names of all the arguments, so we can use them when we call
        # the private method.
        argnames = [arg.name for arg in args] + ["can_gc"]
        argnamesWithThis = ["s.get_context()", "thisValue.handle()"] + argnames
        argnamesWithoutThis = ["s.get_context()", "HandleValue::undefined()"] + argnames
        # Now that we've recorded the argnames for our call to our private
        # method, insert our optional argument for deciding whether the
        # CallSetup should re-throw exceptions on aRv.
        args.append(Argument("ExceptionHandling", "aExceptionHandling",
                             "ReportExceptions"))

        args.append(Argument("CanGc", "can_gc"))
        method.args.append(Argument("CanGc", "can_gc"))

        # And now insert our template argument.
        argsWithoutThis = list(args)
        args.insert(0, Argument("&T", "thisObj"))

        # And the self argument
        method.args.insert(0, Argument(None, "&self"))
        args.insert(0, Argument(None, "&self"))
        argsWithoutThis.insert(0, Argument(None, "&self"))

        setupCall = "let s = CallSetup::<D>::new(self, aExceptionHandling);\n"

        bodyWithThis = (
            f"{setupCall}rooted!(in(*s.get_context()) let mut thisValue: JSVal);\n"
            "let wrap_result = wrap_call_this_value(s.get_context(), thisObj, thisValue.handle_mut());\n"
            "if !wrap_result {\n"
            "    return Err(JSFailed);\n"
            "}\n"
            f"unsafe {{ self.{method.name}({', '.join(argnamesWithThis)}) }}")
        bodyWithoutThis = (
            f"{setupCall}\n"
            f"unsafe {{ self.{method.name}({', '.join(argnamesWithoutThis)}) }}")
        return [ClassMethod(f'{method.name}_', method.returnType, args,
                            bodyInHeader=True,
                            templateArgs=["T: ThisReflector"],
                            body=bodyWithThis,
                            visibility='pub'),
                ClassMethod(f'{method.name}__', method.returnType, argsWithoutThis,
                            bodyInHeader=True,
                            body=bodyWithoutThis,
                            visibility='pub'),
                method]

    def deps(self) -> set[str]:
        return self._deps


# We're always fallible
def callbackGetterName(attr: IDLAttribute, descriptor: Descriptor) -> str:
    return f"Get{MakeNativeName(descriptor.binaryNameFor(attr.identifier.name, attr.isStatic()))}"


def callbackSetterName(attr: IDLAttribute, descriptor: Descriptor) -> str:
    return f"Set{MakeNativeName(descriptor.binaryNameFor(attr.identifier.name, attr.isStatic()))}"


class CGCallbackFunction(CGCallback):
    def __init__(self, callback: IDLCallback, descriptorProvider: DescriptorProvider) -> None:
        CGCallback.__init__(self, callback, descriptorProvider,
                            "CallbackFunction<D>",
                            methods=[CallCallback(callback, descriptorProvider)])

    def getConstructors(self) -> list[ClassConstructor]:
        return CGCallback.getConstructors(self)


class CGCallbackFunctionImpl(CGGeneric):
    def __init__(self, callback: IDLCallback | IDLInterface) -> None:
        type = f"{callback.identifier.name}<D>"
        impl = (f"""
impl<D: DomTypes> CallbackContainer<D> for {type} {{
    unsafe fn new(cx: SafeJSContext, callback: *mut JSObject) -> Rc<{type}> {{
        {type.replace('<D>', '')}::new(cx, callback)
    }}

    fn callback_holder(&self) -> &CallbackObject<D> {{
        self.parent.callback_holder()
    }}
}}

impl<D: DomTypes> ToJSValConvertible for {type} {{
    unsafe fn to_jsval(&self, cx: *mut JSContext, rval: MutableHandleValue) {{
        self.callback().to_jsval(cx, rval);
    }}
}}
""")
        CGGeneric.__init__(self, impl)


class CGCallbackInterface(CGCallback):
    def __init__(self, descriptor: Descriptor) -> None:
        iface = descriptor.interface
        attrs = [m for m in iface.members if m.isAttr() and not m.isStatic()]
        assert not attrs
        methods = [m for m in iface.members
                   if m.isMethod() and not m.isStatic() and not m.isIdentifierLess()]
        methods = [CallbackOperation(m, sig, descriptor) for m in methods
                   for sig in m.signatures()]
        assert not iface.isJSImplemented() or not iface.ctor()
        CGCallback.__init__(self, iface, descriptor, "CallbackInterface<D>", methods)


class FakeMember():
    def __init__(self) -> None:
        pass

    def isStatic(self) -> bool:
        return False

    def isAttr(self) -> bool:
        return False

    def isMethod(self) -> bool:
        return False

    def getExtendedAttribute(self, name: str) -> None:
        return None


class CallbackMember(CGNativeMember):
    def __init__(self, sig: tuple[IDLType, list[IDLArgument]], name: str, descriptorProvider: DescriptorProvider, needThisHandling: bool) -> None:
        """
        needThisHandling is True if we need to be able to accept a specified
        thisObj, False otherwise.
        """

        self.retvalType = sig[0]
        self.originalSig = sig
        args = sig[1]
        self.argCount = len(args)
        if self.argCount > 0:
            # Check for variadic arguments
            lastArg = args[self.argCount - 1]
            if lastArg.variadic:
                self.argCountStr = (
                    f"{self.argCount - 1} + {lastArg.identifier.name}.len()").removeprefix("0 + ")
            else:
                self.argCountStr = f"{self.argCount}"
        self.usingOutparam = returnTypeNeedsOutparam(self.retvalType)
        self.needThisHandling = needThisHandling
        # If needThisHandling, we generate ourselves as private and the caller
        # will handle generating public versions that handle the "this" stuff.
        visibility = "priv" if needThisHandling else "pub"
        # We don't care, for callback codegen, whether our original member was
        # a method or attribute or whatnot.  Just always pass FakeMember()
        # here.
        CGNativeMember.__init__(self, descriptorProvider, FakeMember(),
                                name, (self.retvalType, args),
                                extendedAttrs={},
                                passJSBitsAsNeeded=False,
                                unsafe=needThisHandling,
                                visibility=visibility)
        # We have to do all the generation of our body now, because
        # the caller relies on us throwing if we can't manage it.
        self.exceptionCode = "return Err(JSFailed);\n"
        self.body = self.getImpl()

    @abstractmethod
    def getRvalDecl(self) -> str:
        raise NotImplementedError

    @abstractmethod
    def getCall(self) -> str:
        raise NotImplementedError

    def getImpl(self) -> str:
        argvDecl = (
            "rooted_vec!(let mut argv);\n"
            f"argv.extend((0..{self.argCountStr}).map(|_| Heap::default()));\n"
        ) if self.argCount > 0 else ""  # Avoid weird 0-sized arrays

        # Newlines and semicolons are in the values
        pre = (
            f"{self.getCallSetup()}"
            f"{self.getRvalDecl()}"
            f"{argvDecl}"
        )
        body = (
            f"{self.getArgConversions()}"
            f"{self.getCall()}"
            f"{self.getResultConversion()}"
        )
        return f"{pre}\n{body}"

    def getResultConversion(self) -> str:
        replacements = {
            "val": "rval.handle()",
        }

        info = getJSToNativeConversionInfo(
            self.retvalType,
            self.descriptorProvider,
            exceptionCode=self.exceptionCode,
            # XXXbz we should try to do better here
            sourceDescription="return value")
        template = info.template
        declType = info.declType

        if self.usingOutparam:
            convertType = CGGeneric("")
        else:
            convertType = instantiateJSToNativeConversionTemplate(
                template, replacements, declType, "retval")

        if self.retvalType is None or self.retvalType.isUndefined() or self.usingOutparam:
            retval = "()"
        else:
            retval = "retval"

        return f"{convertType.define()}\nOk({retval})\n"

    def getArgConversions(self) -> str:
        # Just reget the arglist from self.originalSig, because our superclasses
        # just have way to many members they like to clobber, so I can't find a
        # safe member name to store it in.
        arglist = self.originalSig[1]
        argConversions: list[str] = [self.getArgConversion(i, arg) for (i, arg)
                          in enumerate(arglist)]
        # Do them back to front, so our argc modifications will work
        # correctly, because we examine trailing arguments first.
        argConversions.reverse()
        argConversionsCG: list[CGThing] = [CGGeneric(c) for c in argConversions]
        # If arg count is only 1 but it's optional and not default value,
        # argc should be mutable.
        if self.argCount == 1 and not (arglist[0].optional and not arglist[0].defaultValue):
            argConversionsCG.insert(0, self.getArgcDecl(True))
        elif self.argCount > 0:
            argConversionsCG.insert(0, self.getArgcDecl(False))
        # And slap them together.
        return CGList(argConversionsCG, "\n\n").define() + "\n\n"

    def getArgConversion(self, i: int, arg: IDLArgument) -> str:
        argval = arg.identifier.name

        if arg.variadic:
            argval = f"{argval}[idx].get()"
            jsvalIndex = f"{i} + idx"
        else:
            jsvalIndex = f"{i}"

        conversion = wrapForType(
            "argv_root.handle_mut()", result=argval,
            successCode=("{\n"
                         f"let arg = &mut argv[{jsvalIndex.removeprefix('0 + ')}];\n"
                         "*arg = Heap::default();\n"
                         "arg.set(argv_root.get());\n"
                         "}"),
            pre="rooted!(in(*cx) let mut argv_root = UndefinedValue());")
        if arg.variadic:
            conversion = (
                f"for idx in 0..{arg.identifier.name}.len() {{\n"
                f"{CGIndenter(CGGeneric(conversion)).define()}\n}}"
            )
        elif arg.optional and not arg.defaultValue:
            conversion = (
                f"{CGIfWrapper(f'let Some({arg.identifier.name}) = {arg.identifier.name}', CGGeneric(conversion)).define()}"
                f" else if argc == {i + 1} {{\n"
                "    // This is our current trailing argument; reduce argc\n"
                "    argc -= 1;\n"
                "} else {\n"
                f"    argv[{i}] = Heap::default();\n"
                "}"
            )
        return conversion

    def getArgs(self, returnType: IDLType, argList: list[IDLArgument]) -> list[Argument]:
        args = CGNativeMember.getArgs(self, returnType, argList)
        if not self.needThisHandling:
            # Since we don't need this handling, we're the actual method that
            # will be called, so we need an aRethrowExceptions argument.
            args.append(Argument("ExceptionHandling", "aExceptionHandling",
                                 "ReportExceptions"))
            return args
        # We want to allow the caller to pass in a "this" object, as
        # well as a JSContext.
        return [Argument("SafeJSContext", "cx"),
                Argument("HandleValue", "aThisObj")] + args

    def getCallSetup(self) -> str:
        if self.needThisHandling:
            # It's been done for us already
            return ""
        return (
            "CallSetup s(CallbackPreserveColor(), aRv, aExceptionHandling);\n"
            "JSContext* cx = *s.get_context();\n"
            "if (!cx) {\n"
            "    return Err(JSFailed);\n"
            "}\n")

    def getArgcDecl(self, immutable: bool) -> CGThing:
        if immutable:
            return CGGeneric(f"let argc = {self.argCountStr};")
        return CGGeneric(f"let mut argc = {self.argCountStr};")

    @staticmethod
    def ensureASCIIName(idlObject: IDLInterfaceMember) -> None:
        type = "attribute" if idlObject.isAttr() else "operation"
        if re.match("[^\x20-\x7E]", idlObject.identifier.name):
            raise SyntaxError(f'Callback {type} name "{idlObject.identifier.name}" contains non-ASCII '
                              f"characters.  We can't handle that.  {idlObject.location}")
        if re.match('"', idlObject.identifier.name):
            raise SyntaxError(f"Callback {type} name '{idlObject.identifier.name}' contains "
                              "double-quote character.  We can't handle "
                              f"that.  {idlObject.location}")


class CallbackMethod(CallbackMember):
    def __init__(self, sig: tuple[IDLType, list[IDLArgument]], name: str, descriptorProvider: DescriptorProvider, needThisHandling: bool) -> None:
        CallbackMember.__init__(self, sig, name, descriptorProvider,
                                needThisHandling)

    def getRvalDecl(self) -> str:
        if self.usingOutparam:
            return ""
        else:
            return "rooted!(in(*cx) let mut rval = UndefinedValue());\n"

    @abstractmethod
    def getCallableDecl(self) -> str:
        raise NotImplementedError

    @abstractmethod
    def getThisObj(self) -> str:
        raise NotImplementedError

    @abstractmethod
    def getCallGuard(self) -> str:
        raise NotImplementedError

    def getCall(self) -> str:
        if self.argCount > 0:
            argv = "argv.as_ptr() as *const JSVal"
            argc = "argc"
        else:
            argv = "ptr::null_mut()"
            argc = "0"
        suffix = "" if self.usingOutparam else ".handle_mut()"
        return (f"{self.getCallableDecl()}"
                f"rooted!(in(*cx) let rootedThis = {self.getThisObj()});\n"
                f"let ok = {self.getCallGuard()}Call(\n"
                "    *cx, rootedThis.handle(), callable.handle(),\n"
                "    &HandleValueArray {\n"
                f"        length_: {argc} as ::libc::size_t,\n"
                f"        elements_: {argv}\n"
                f"    }}, rval{suffix});\n"
                "maybe_resume_unwind();\n"
                "if !ok {\n"
                "    return Err(JSFailed);\n"
                "}\n")


class CallCallback(CallbackMethod):
    def __init__(self, callback: IDLCallback, descriptorProvider: DescriptorProvider) -> None:
        self.callback = callback
        CallbackMethod.__init__(self, callback.signatures()[0], "Call",
                                descriptorProvider, needThisHandling=True)

    def getThisObj(self) -> str:
        return "aThisObj.get()"

    def getCallableDecl(self) -> str:
        return "rooted!(in(*cx) let callable = ObjectValue(self.callback()));\n"

    def getCallGuard(self) -> str:
        if self.callback._treatNonObjectAsNull:
            return "!IsCallable(self.callback()) || "
        return ""


class CallbackOperationBase(CallbackMethod):
    """
    Common class for implementing various callback operations.
    """
    def __init__(self, signature: tuple[IDLType, list[IDLArgument]], jsName: str, nativeName: str, descriptor: Descriptor, singleOperation: bool) -> None:
        self.singleOperation = singleOperation
        self.methodName = jsName
        CallbackMethod.__init__(self, signature, nativeName, descriptor, singleOperation)

    def getThisObj(self) -> str:
        if not self.singleOperation:
            return "ObjectValue(self.callback())"
        # This relies on getCallableDecl declaring a boolean
        # isCallable in the case when we're a single-operation
        # interface.
        return "if isCallable { aThisObj.get() } else { ObjectValue(self.callback()) }"

    def getCallableDecl(self) -> str:
        getCallableFromProp = f'self.parent.get_callable_property(cx, "{self.methodName}")?'
        if not self.singleOperation:
            return f'rooted!(in(*cx) let callable =\n{getCallableFromProp});\n'
        callable = CGIndenter(
            CGIfElseWrapper('isCallable', CGGeneric('ObjectValue(self.callback())'), CGGeneric(getCallableFromProp))
        ).define()
        return ('let isCallable = IsCallable(self.callback());\n'
                'rooted!(in(*cx) let callable =\n'
                f"{callable});\n")

    def getCallGuard(self) -> str:
        return ""


class CallbackOperation(CallbackOperationBase):
    """
    Codegen actual WebIDL operations on callback interfaces.
    """
    def __init__(self, method: IDLMethod, signature: tuple[IDLType, list[IDLArgument | FakeArgument]], descriptor: Descriptor) -> None:
        self.ensureASCIIName(method)
        jsName = method.identifier.name
        CallbackOperationBase.__init__(self, signature,
                                       jsName,
                                       MakeNativeName(descriptor.binaryNameFor(jsName, False)),
                                       descriptor, descriptor.interface.isSingleOperationInterface())


class CGMaplikeOrSetlikeMethodGenerator(CGGeneric):
    """
    Creates methods for *like interfaces. Unwrapping/wrapping
    will be taken care of by the usual method generation machinery in
    CGMethodCall/CGPerSignatureCall. Functionality is filled in here instead of
    using CGCallGenerator.
    """
    def __init__(self, descriptor: Descriptor, likeable: IDLMaplikeOrSetlikeOrIterableBase, methodName: str) -> None:
        trait: str
        if likeable.isSetlike():
            trait = "Setlike"
        elif likeable.isMaplike():
            trait = "Maplike"
        else:
            raise TypeError("CGMaplikeOrSetlikeMethodGenerator is only for Setlike/Maplike")
        """
        setlike:
            fn size(&self) -> usize;
            fn add(&self, key: Self::Key);
            fn has(&self, key: &Self::Key) -> bool;
            fn clear(&self);
            fn delete(&self, key: &Self::Key) -> bool;
        maplike:
            fn get(&self, key: Self::Key) -> Self::Value;
            fn size(&self) -> usize;
            fn set(&self, key: Self::Key, value: Self::Value);
            fn has(&self, key: &Self::Key) -> bool;
            fn clear(&self);
            fn delete(&self, key: &Self::Key) -> bool;
        like iterable:
            keys/values/entries/forEach
        """
        # like iterables are implemented seperatly as we are actually implementing them
        if methodName in ["keys", "values", "entries", "forEach"]:
            CGIterableMethodGenerator.__init__(self, descriptor, likeable, methodName)
        elif methodName in ["size", "clear"]:  # zero arguments
            CGGeneric.__init__(self, fill(
                """
                let result = ${trt}::${method}(this);
                """,
                trt=trait,
                method=methodName.lower()))
        elif methodName == "add":  # special case one argumet
            CGGeneric.__init__(self, fill(
                """
                ${trt}::${method}(this, arg0);
                // Returns itself per https://webidl.spec.whatwg.org/#es-set-add
                let result = this;
                """,
                trt=trait,
                method=methodName))
        elif methodName in ["has", "delete", "get"]:  # one argument
            CGGeneric.__init__(self, fill(
                """
                let result = ${trt}::${method}(this, arg0);
                """,
                trt=trait,
                method=methodName))
        elif methodName == "set":  # two arguments
            CGGeneric.__init__(self, fill(
                """
                ${trt}::${method}(this, arg0, arg1);
                // Returns itself per https://webidl.spec.whatwg.org/#es-map-set
                let result = this;
                """,
                trt=trait,
                method=methodName))
        else:
            raise TypeError(f"Do not know how to impl *like method: {methodName}")


class CGIterableMethodGenerator(CGGeneric):
    """
    Creates methods for iterable interfaces. Unwrapping/wrapping
    will be taken care of by the usual method generation machinery in
    CGMethodCall/CGPerSignatureCall. Functionality is filled in here instead of
    using CGCallGenerator.
    """
    def __init__(self, descriptor: Descriptor, iterable: IDLMaplikeOrSetlikeOrIterableBase, methodName: str) -> None:
        if methodName == "forEach":
            CGGeneric.__init__(self, fill(
                """
                if !IsCallable(arg0) {
                  throw_type_error(*cx, "Argument 1 of ${ifaceName}.forEach is not callable.");
                  return false;
                }
                rooted!(in(*cx) let arg0 = ObjectValue(arg0));
                rooted!(in(*cx) let mut call_arg1 = UndefinedValue());
                rooted!(in(*cx) let mut call_arg2 = UndefinedValue());
                rooted_vec!(let mut call_args);
                call_args.push(UndefinedValue());
                call_args.push(UndefinedValue());
                call_args.push(ObjectValue(*_obj));
                rooted!(in(*cx) let mut ignoredReturnVal = UndefinedValue());

                // This has to be a while loop since get_iterable_length() may change during
                // the callback, and we need to avoid iterator invalidation.
                //
                // It is possible for this to loop infinitely, but that matches the spec
                // and other browsers.
                //
                // https://heycam.github.io/webidl/#es-forEach
                let mut i = 0;
                while i < (*this).get_iterable_length() {
                  (*this).get_value_at_index(i).to_jsval(*cx, call_arg1.handle_mut());
                  (*this).get_key_at_index(i).to_jsval(*cx, call_arg2.handle_mut());
                  call_args[0] = call_arg1.handle().get();
                  call_args[1] = call_arg2.handle().get();
                  let call_args_handle = HandleValueArray::from(&call_args);
                  if !Call(*cx, arg1, arg0.handle(), &call_args_handle,
                           ignoredReturnVal.handle_mut()) {
                    return false;
                  }

                  i += 1;
                }

                let result = ();
                """,
                ifaceName=descriptor.interface.identifier.name))
            return
        CGGeneric.__init__(self, fill(
            """
            let realm = AlreadyInRealm::assert_for_cx(cx);
            let result = ${iterClass}::new(this, IteratorType::${itrMethod}, InRealm::already(&realm));
            """,
            iterClass=iteratorNativeType(descriptor, True),
            ifaceName=descriptor.interface.identifier.name,
            itrMethod=methodName.title()))


def camel_to_upper_snake(s: str) -> str:
    return "_".join(m.group(0).upper() for m in re.finditer("[A-Z][a-z]*", s))


def process_arg(expr: str, arg: IDLArgument | FakeArgument) -> str:
    if arg.type.isGeckoInterface() and not arg.type.unroll().inner.isCallback():
        if arg.variadic or arg.type.isSequence():
            expr += ".r()"
        elif arg.type.nullable() and arg.optional and not arg.defaultValue:
            expr += ".as_ref().map(Option::as_deref)"
        elif arg.type.nullable() or arg.optional and not arg.defaultValue:
            expr += ".as_deref()"
        else:
            expr = f"&{expr}"
    elif isinstance(arg.type, IDLPromiseType):
        expr = f"&{expr}"
    return expr


class GlobalGenRoots():
    """
    Roots for global codegen.

    To generate code, call the method associated with the target, and then
    call the appropriate define/declare method.
    """

    @staticmethod
    def Globals(config: Configuration) -> CGThing:
        global_descriptors = config.getDescriptors(isGlobal=True)
        flags = [("EMPTY", 0)]
        flags.extend(
            (camel_to_upper_snake(d.name), 2 ** idx)
            for (idx, d) in enumerate(global_descriptors)
        )
        global_flags = CGWrapper(CGIndenter(CGList([
            CGGeneric(f"const {args[0]} = {args[1]};")
            for args in flags
        ], "\n")), pre="#[derive(Clone, Copy)]\npub struct Globals: u8 {\n", post="\n}")
        globals_ = CGWrapper(CGIndenter(global_flags), pre="bitflags::bitflags! {\n", post="\n}")

        return CGList([
            CGGeneric(AUTOGENERATED_WARNING_COMMENT),
            globals_,
        ])

    @staticmethod
    def InterfaceObjectMap(config: Configuration) -> CGThing:
        mods = [
            "crate::dom::bindings::codegen",
            "script_bindings::interfaces::Interface",
        ]
        imports = CGList([CGGeneric(f"use {mod};") for mod in mods], "\n")

        phf = CGGeneric("include!(concat!(env!(\"OUT_DIR\"), \"/InterfaceObjectMapPhf.rs\"));")

        return CGList([
            CGGeneric(AUTOGENERATED_WARNING_COMMENT),
            CGList([imports, phf], "\n\n")
        ])

    @staticmethod
    def InterfaceObjectMapData(config: Configuration) -> CGThing:
        pairs: list[tuple[str, str, str]] = []
        for d in config.getDescriptors(hasInterfaceObject=True, isInline=False):
            binding_mod = toBindingModuleFileFromDescriptor(d)
            binding_ns = toBindingNamespace(d.name)
            pairs.append((d.name, binding_mod, binding_ns))
            for alias in d.interface.legacyWindowAliases:
                pairs.append((alias, binding_mod, binding_ns))
            for ctor in d.interface.legacyFactoryFunctions:
                pairs.append((ctor.identifier.name, binding_mod, binding_ns))
        pairs.sort(key=operator.itemgetter(0))

        def bindingPath(pair: tuple[str, str, str]) -> str:
            return f'codegen::Bindings::{pair[1]}::{pair[2]}'

        mappings = [
            CGGeneric(f'"{pair[0]}": ["{bindingPath(pair)}::DefineDOMInterface::<crate::DomTypeHolder>", '
                      f'"{bindingPath(pair)}::ConstructorEnabled::<crate::DomTypeHolder>"]')
            for pair in pairs
        ]
        return CGWrapper(
            CGList(mappings, ",\n"),
            pre="{\n",
            post="\n}\n")

    @staticmethod
    def PrototypeList(config: Configuration) -> CGThing:
        # Prototype ID enum.
        interfaces = config.getDescriptors(isCallback=False, isNamespace=False)
        protos = [d.name for d in interfaces]
        constructors = sorted([MakeNativeName(d.name)
                               for d in config.getDescriptors(hasInterfaceObject=True)
                               if d.shouldHaveGetConstructorObjectMethod()])

        return CGList([
            CGGeneric(AUTOGENERATED_WARNING_COMMENT),
            CGGeneric(f"pub const PROTO_OR_IFACE_LENGTH: usize = {len(protos) + len(constructors)};\n"),
            CGGeneric(f"pub const MAX_PROTO_CHAIN_LENGTH: usize = {config.maxProtoChainLength};\n\n"),
            CGGeneric("#[allow(clippy::enum_variant_names, dead_code)]"),
            CGNonNamespacedEnum('ID', protos, 0, deriving="PartialEq, Copy, Clone", repr="u16"),
            CGNonNamespacedEnum('Constructor', constructors, len(protos),
                                deriving="PartialEq, Copy, Clone", repr="u16"),
            CGWrapper(CGIndenter(CGList([CGGeneric(f'"{name}"') for name in protos],
                                        ",\n"),
                                 indentLevel=4),
                      pre=f"static INTERFACES: [&str; {len(protos)}] = [\n",
                      post="\n];\n\n"),
            CGGeneric("pub fn proto_id_to_name(proto_id: u16) -> &'static str {\n"
                      "    debug_assert!(proto_id < ID::Last as u16);\n"
                      "    INTERFACES[proto_id as usize]\n"
                      "}\n\n"),
        ])

    @staticmethod
    def RegisterBindings(config: Configuration) -> CGThing:
        # TODO - Generate the methods we want
        code = CGList([
            CGRegisterProxyHandlers(config),
            CGInitAllStatics(config),
        ], "\n")

        return CGImports(code, descriptors=[], callbacks=[], dictionaries=[], enums=[], typedefs=[], imports=[
            'crate::codegen::GenericBindings',
            'crate::DomTypes',
        ], config=config)

    @staticmethod
    def InterfaceTypes(config: Configuration) -> CGThing:
        descriptors = sorted([MakeNativeName(d.name)
                              for d in config.getDescriptors(register=True,
                                                             isCallback=False,
                                                             isIteratorInterface=False)])
        curr = CGList([CGGeneric(f"pub(crate) use crate::dom::{name.lower()}::{MakeNativeName(name)};\n")
                       for name in descriptors])
        curr = CGWrapper(curr, pre=AUTOGENERATED_WARNING_COMMENT)
        return curr

    @staticmethod
    def Bindings(config: Configuration) -> CGThing:

        def leafModule(d: IDLObject) -> str:
            return getModuleFromObject(d).split('::')[-1]

        descriptors = config.getDescriptors(register=True, isIteratorInterface=False)
        descriptors = (set(toBindingModuleFile(d.name) for d in descriptors if d.maybeGetSuperModule() is None)
                       | set(leafModule(d) for d in config.callbacks)
                       | set(leafModule(d) for d in config.getDictionaries()))
        curr = CGList([CGGeneric(
            "#[allow(clippy::derivable_impls)]\n"
            f"pub mod {name};\n"
        ) for name in sorted(descriptors)])
        curr = CGWrapper(curr, pre=AUTOGENERATED_WARNING_COMMENT)
        return curr

    @staticmethod
    def ConcreteInheritTypes(config: Configuration) -> CGThing:
        descriptors = config.getDescriptors(register=True, isCallback=False)
        imports = [CGGeneric("use crate::dom::types::*;\n"),
                   CGGeneric("use script_bindings::codegen::InheritTypes::*;\n"),
                   CGGeneric("use crate::dom::bindings::conversions::{DerivedFrom, get_dom_class};\n"),
                   CGGeneric("use crate::dom::bindings::inheritance::Castable;\n"),
                   CGGeneric("use crate::dom::bindings::reflector::DomObject;\n\n")]
        allprotos = []
        topTypes = []
        hierarchy = defaultdict(list)
        for descriptor in descriptors:
            name = descriptor.name
            chain = descriptor.prototypeChain
            upcast = descriptor.hasDescendants()
            downcast = len(chain) != 1

            if upcast and not downcast:
                topTypes.append(name)

            if not upcast:
                # No other interface will implement DeriveFrom<Foo> for this Foo, so avoid
                # implementing it for itself.
                chain = chain[:-1]

            # Implement `DerivedFrom<Bar>` for `Foo`, for all `Bar` that `Foo` inherits from.
            if chain:
                allprotos.append(CGGeneric(f"impl Castable for {name} {{}}\n"))
            for baseName in chain:
                allprotos.append(CGGeneric(f"impl DerivedFrom<{baseName}> for {name} {{}}\n"))
            if chain:
                allprotos.append(CGGeneric("\n"))

            if downcast:
                assert descriptor.interface.parent is not None
                hierarchy[descriptor.interface.parent.identifier.name].append(name)

        typeIdCode = []

        for base, derived in hierarchy.items():
            if base in topTypes:
                typeIdCode.append(CGGeneric(f"""
impl {base} {{
    #[allow(dead_code)]
    pub(crate) fn type_id(&self) -> &'static {base}TypeId {{
        unsafe {{
            &get_dom_class(self.reflector().get_jsobject().get())
                .unwrap()
                .type_id
                .{base.lower()}
        }}
    }}
}}

"""))

        curr = CGList(imports + typeIdCode + allprotos)
        curr = CGWrapper(curr, pre=AUTOGENERATED_WARNING_COMMENT)
        return curr

    @staticmethod
    def InheritTypes(config: Configuration) -> CGThing:
        descriptors = config.getDescriptors(register=True, isCallback=False)
        topTypes = []
        hierarchy = defaultdict(list)
        for descriptor in descriptors:
            name = descriptor.name
            upcast = descriptor.hasDescendants()
            downcast = len(descriptor.prototypeChain) != 1

            if upcast and not downcast:
                topTypes.append(name)

            if downcast:
                assert descriptor.interface.parent is not None
                hierarchy[descriptor.interface.parent.identifier.name].append(name)

        typeIdCode: list = []
        topTypeVariants = [
            ("ID used by abstract interfaces.", "pub abstract_: ()"),
            ("ID used by interfaces that are not castable.", "pub alone: ()"),
        ]
        topTypeVariants += [
            (f"ID used by interfaces that derive from {typeName}.",
             f"pub {typeName.lower()}: {typeName}TypeId")
            for typeName in topTypes
        ]
        topTypeVariantsAsStrings = [CGGeneric(f"/// {variant[0]}\n{variant[1]},") for variant in topTypeVariants]
        typeIdCode.append(CGWrapper(CGIndenter(CGList(topTypeVariantsAsStrings, "\n"), 4),
                                    pre="#[derive(Copy)]\npub union TopTypeId {\n",
                                    post="\n}\n\n"))

        typeIdCode.append(CGGeneric("""\
impl Clone for TopTypeId {
    fn clone(&self) -> Self { *self }
}

"""))

        def type_id_variant(name: str) -> str:
            # If `name` is present in the hierarchy keys', that means some other interfaces
            # derive from it and this enum variant should have an argument with its own
            # TypeId enum.
            return f"{name}({name}TypeId)" if name in hierarchy else name

        for base, derived in hierarchy.items():
            variants = []
            if config.getDescriptor(base).concrete:
                variants.append(CGGeneric(base))
            variants += [CGGeneric(type_id_variant(derivedName)) for derivedName in derived]
            derives = "Clone, Copy, Debug, PartialEq"
            typeIdCode.append(CGWrapper(CGIndenter(CGList(variants, ",\n"), 4),
                                        pre=f"#[derive({derives})]\npub enum {base}TypeId {{\n",
                                        post="\n}\n\n"))

        curr = CGList(typeIdCode)
        curr = CGWrapper(curr, pre=AUTOGENERATED_WARNING_COMMENT)
        return curr

    @staticmethod
    def ConcreteUnionTypes(config: Configuration) -> CGThing:
        unions = set()
        cgthings = []
        allTypes = getAllTypes(
            config.getDescriptors(), config.getDictionaries(), config.getCallbacks(), config.typedefs
        )
        for (t, descriptor) in allTypes:
            t = t.unroll()
            name = str(t)
            if not t.isUnion() or name in unions:
                continue
            unions.add(name)
            generic = "<crate::DomTypeHolder>" if containsDomInterface(t) else ""
            cgthings += [CGGeneric(f"pub(crate) type {name} = "
                                   f"script_bindings::codegen::GenericUnionTypes::{name}{generic};\n")]
        curr = CGList(cgthings)
        curr = CGWrapper(curr, pre=AUTOGENERATED_WARNING_COMMENT)
        return curr

    @staticmethod
    def UnionTypes(config: Configuration) -> CGThing:

        curr = UnionTypes(config.getDescriptors(),
                          config.getDictionaries(),
                          config.getCallbacks(),
                          config.typedefs,
                          config)

        # Add the auto-generated comment.
        curr = CGWrapper(curr, pre=AUTOGENERATED_WARNING_COMMENT)

        # Done.
        return curr

    @staticmethod
    def DomTypes(config: Configuration) -> CGThing:
        curr = DomTypes(config.getDescriptors(),
                        config.getDescriptorProvider(),
                        config.getDictionaries(),
                        config.getCallbacks(),
                        config.typedefs,
                        config)

        # Add the auto-generated comment.
        curr = CGWrapper(curr, pre=AUTOGENERATED_WARNING_COMMENT)

        # Done.
        return curr

    @staticmethod
    def DomTypeHolder(config: Configuration) -> CGThing:
        curr = DomTypeHolder(config.getDescriptors(),
                             config.getDescriptorProvider(),
                             config.getDictionaries(),
                             config.getCallbacks(),
                             config.typedefs,
                             config)

        # Add the auto-generated comment.
        curr = CGWrapper(curr, pre=AUTOGENERATED_WARNING_COMMENT)

        # Done.
        return curr

    @staticmethod
    def SupportedDomApis(config: Configuration) -> CGThing:
        descriptors = config.getDescriptors(isExposedConditionally=False)

        base_path = os.path.dirname(__file__)
        with open(os.path.join(base_path, 'apis.html.template')) as f:
            base_template = f.read()
        with open(os.path.join(base_path, 'api.html.template')) as f:
            api_template = f.read()
        with open(os.path.join(base_path, 'property.html.template')) as f:
            property_template = f.read()
        with open(os.path.join(base_path, 'interface.html.template')) as f:
            interface_template = f.read()

        apis = []
        interfaces = []
        for descriptor in descriptors:
            props = []
            for m in descriptor.interface.members:
                if PropertyDefiner.getStringAttr(m, 'Pref') or \
                   PropertyDefiner.getStringAttr(m, 'Func') or \
                   PropertyDefiner.getStringAttr(m, 'Exposed') or \
                   m.getExtendedAttribute('SecureContext') or \
                   (m.isMethod() and m.isIdentifierLess()):
                    continue
                bracket = '()' if m.isMethod() else ''
                display = f"{m.identifier.name}{bracket}"
                props += [property_template.replace('${name}', display)]
            name = descriptor.interface.identifier.name
            apis += [(api_template.replace('${interface}', name)
                                  .replace('${properties}', '\n'.join(props)))]
            interfaces += [interface_template.replace('${interface}', name)]

        return CGGeneric((base_template.replace('${apis}', '\n'.join(apis))
                                       .replace('${interfaces}', '\n'.join(interfaces))))
