# Copyright 2019 The Chromium Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

import itertools

import web_idl

from . import name_style
from .blink_v8_bridge import blink_class_name
from .blink_v8_bridge import blink_type_info
from .blink_v8_bridge import make_v8_to_blink_value
from .blink_v8_bridge import make_v8_to_blink_value_variadic
from .blink_v8_bridge import v8_bridge_class_name
from .code_node import EmptyNode
from .code_node import ListNode
from .code_node import SequenceNode
from .code_node import SymbolDefinitionNode
from .code_node import SymbolNode
from .code_node import SymbolScopeNode
from .code_node import TextNode
from .code_node import WeakDependencyNode
from .code_node_cxx import CxxBlockNode
from .code_node_cxx import CxxBreakableBlockNode
from .code_node_cxx import CxxClassDefNode
from .code_node_cxx import CxxFuncDeclNode
from .code_node_cxx import CxxFuncDefNode
from .code_node_cxx import CxxLikelyIfNode
from .code_node_cxx import CxxMultiBranchesNode
from .code_node_cxx import CxxNamespaceNode
from .code_node_cxx import CxxSwitchNode
from .code_node_cxx import CxxUnlikelyIfNode
from .codegen_accumulator import CodeGenAccumulator
from .codegen_context import CodeGenContext
from .codegen_expr import CodeGenExpr
from .codegen_expr import expr_and
from .codegen_expr import expr_from_exposure
from .codegen_expr import expr_or
from .codegen_format import format_template as _format
from .codegen_utils import component_export
from .codegen_utils import component_export_header
from .codegen_utils import enclose_with_header_guard
from .codegen_utils import make_copyright_header
from .codegen_utils import make_forward_declarations
from .codegen_utils import make_header_include_directives
from .codegen_utils import write_code_node_to_file
from .mako_renderer import MakoRenderer
from .package_initializer import package_initializer
from .path_manager import PathManager
from .task_queue import TaskQueue


def _is_none_or_str(arg):
    return arg is None or isinstance(arg, str)


def backward_compatible_api_func(cg_context):
    """
    Returns the Blink function name compatible with the old bindings generator.
    """
    assert isinstance(cg_context, CodeGenContext)

    name = (cg_context.member_like.code_generator_info.property_implemented_as
            or cg_context.member_like.identifier
            or cg_context.property_.identifier)

    if cg_context.attribute_get:
        # modules/webaudio/biquad_filter_node.idl has readonly attribute "Q"
        # and somehow it's implemented as "q" in Blink.
        if name == "Q":
            name = "q"

    if cg_context.attribute_set:
        tokens = name_style.raw.tokenize(name)
        if tokens[0] in ("IDL", "css", "xml"):
            tokens[0] = tokens[0].upper()
        else:
            tokens[0] = tokens[0].capitalize()
        tokens.insert(0, "set")
        name = "".join(tokens)

    if cg_context.indexed_property_getter and not name:
        name = "AnonymousIndexedGetter"
    if cg_context.indexed_property_setter and not name:
        name = "AnonymousIndexedSetter"
    if cg_context.named_property_getter and not name:
        name = "AnonymousNamedGetter"
    if cg_context.named_property_setter and not name:
        name = "AnonymousNamedSetter"
    if cg_context.named_property_deleter and not name:
        name = "AnonymousNamedDeleter"

    return name


def callback_function_name(cg_context,
                           overload_index=None,
                           for_cross_origin=False,
                           no_alloc_direct_call=False):
    assert isinstance(cg_context, CodeGenContext)

    def _cxx_name(name):
        """
        Returns a property name that the bindings generator can use in
        generated code.

        Note that Web IDL allows '-' (hyphen-minus) and '_' (low line) in
        identifiers but C++ does not allow or recommend them.  This function
        encodes these characters.
        """
        # In Python3, we can use str.maketrans and str.translate.
        #
        # We're optimistic about name conflict.  It's highly unlikely that
        # these replacements will cause a conflict.
        assert "Dec45" not in name
        assert "Dec95" not in name
        name = name.replace("-", "Dec45")
        name = name.replace("_", "Dec95")
        return name

    if cg_context.constant:
        property_name = cg_context.property_.identifier
    else:
        property_name = _cxx_name(cg_context.property_.identifier)

    if cg_context.attribute_get:
        kind = "AttributeGet"
    elif cg_context.attribute_set:
        kind = "AttributeSet"
    elif cg_context.constant:
        kind = "Constant"
    elif cg_context.constructor_group:
        if cg_context.is_named_constructor:
            kind = "NamedConstructor"
        else:
            property_name = ""
            kind = "Constructor"
    elif cg_context.exposed_construct:
        if cg_context.is_named_constructor:
            kind = "NamedConstructorProperty"
        elif cg_context.legacy_window_alias:
            kind = "LegacyWindowAlias"
        else:
            kind = "ExposedConstruct"
    elif cg_context.operation_group:
        kind = "Operation"
    elif cg_context.stringifier:
        kind = "Operation"

    if for_cross_origin:
        suffix = "CrossOrigin"
    elif overload_index is not None:
        suffix = "Overload{}".format(overload_index + 1)
    elif no_alloc_direct_call:
        suffix = "NoAllocDirectCallback"
    else:
        suffix = "Callback"

    if cg_context.for_world == CodeGenContext.MAIN_WORLD:
        world_suffix = "ForMainWorld"
    elif cg_context.for_world == CodeGenContext.NON_MAIN_WORLDS:
        world_suffix = "ForNonMainWorlds"
    elif cg_context.for_world == CodeGenContext.ALL_WORLDS:
        world_suffix = ""

    return name_style.func(property_name, kind, suffix, world_suffix)


def constant_name(cg_context):
    assert isinstance(cg_context, CodeGenContext)
    assert cg_context.constant

    property_name = cg_context.property_.identifier.lower()

    return name_style.constant(property_name)


def custom_function_name(cg_context):
    assert isinstance(cg_context, CodeGenContext)

    if cg_context.named_property_getter:
        return "NamedPropertyGetterCustom"
    if cg_context.named_property_setter:
        return "NamedPropertySetterCustom"
    if cg_context.named_property_deleter:
        return "NamedPropertyDeleterCustom"

    if cg_context.attribute_get:
        suffix = "AttributeGetterCustom"
    elif cg_context.attribute_set:
        suffix = "AttributeSetterCustom"
    elif cg_context.operation_group:
        suffix = "MethodCustom"
    else:
        assert False

    return name_style.func(cg_context.property_.identifier, suffix)


# ----------------------------------------------------------------------------
# Callback functions
# ----------------------------------------------------------------------------


def bind_blink_api_arguments(code_node, cg_context):
    assert isinstance(code_node, SymbolScopeNode)
    assert isinstance(cg_context, CodeGenContext)

    if cg_context.attribute_get:
        return

    if cg_context.attribute_set:
        real_type = cg_context.attribute.idl_type.unwrap(typedef=True)
        if real_type.is_enumeration:
            pattern = """\
// https://heycam.github.io/webidl/#dfn-attribute-setter
// step 4.6.1. Let S be ? ToString(V).
const auto&& arg1_value_string =
    NativeValueTraits<IDLStringV2>::NativeValue(
        ${isolate}, ${v8_property_value}, ${exception_state});
if (${exception_state}.HadException())
  return;
// step 4.6.2. If S is not one of the enumeration's values, then return
//   undefined.
const auto arg1_value_maybe_enum = {enum_type}::Create(arg1_value_string);
if (!arg1_value_maybe_enum) {{
  bindings::ReportInvalidEnumSetToAttribute(
      ${isolate}, arg1_value_string, "{enum_type_name}", ${exception_state});
  return;  // Return undefined.
}}
const auto ${arg1_value} = arg1_value_maybe_enum.value();
"""
            text = _format(pattern,
                           enum_type=blink_class_name(
                               real_type.type_definition_object),
                           enum_type_name=real_type.identifier)
            code_node.register_code_symbol(SymbolNode("arg1_value", text))
            return

        name = "arg1_value"
        v8_value = "${v8_property_value}"
        code_node.register_code_symbol(
            make_v8_to_blink_value(name, v8_value,
                                   cg_context.attribute.idl_type))
        return

    for argument in cg_context.function_like.arguments:
        name = name_style.arg_f("arg{}_{}", argument.index + 1,
                                argument.identifier)
        if argument.is_variadic:
            code_node.register_code_symbol(
                make_v8_to_blink_value_variadic(name, "${info}",
                                                argument.index,
                                                argument.idl_type))
        else:
            v8_value = "${{info}}[{}]".format(argument.index)
            code_node.register_code_symbol(
                make_v8_to_blink_value(name,
                                       v8_value,
                                       argument.idl_type,
                                       argument=argument,
                                       cg_context=cg_context))


def bind_callback_local_vars(code_node, cg_context):
    assert isinstance(code_node, SymbolScopeNode)
    assert isinstance(cg_context, CodeGenContext)

    S = SymbolNode
    T = TextNode

    local_vars = []
    template_vars = {}

    local_vars.extend([
        S("blink_property_name",
          ("const AtomicString& ${blink_property_name} = "
           "ToCoreAtomicString(${v8_property_name}.As<v8::String>());")),
        S("class_like_name", ("const char* const ${class_like_name} = "
                              "\"${class_like.identifier}\";")),
        S("current_context", ("v8::Local<v8::Context> ${current_context} = "
                              "${isolate}->GetCurrentContext();")),
        S("current_script_state", ("ScriptState* ${current_script_state} = "
                                   "ScriptState::From(${current_context});")),
        S("isolate", "v8::Isolate* ${isolate} = ${info}.GetIsolate();"),
        S("non_undefined_argument_length",
          ("const int ${non_undefined_argument_length} = "
           "bindings::NonUndefinedArgumentLength(${info});")),
        S("per_context_data", ("V8PerContextData* ${per_context_data} = "
                               "${script_state}->PerContextData();")),
        S("per_isolate_data", ("V8PerIsolateData* ${per_isolate_data} = "
                               "V8PerIsolateData::From(${isolate});")),
        S("property_name",
          "const char* const ${property_name} = \"${property.identifier}\";"),
        S("receiver_context", ("v8::Local<v8::Context> ${receiver_context} = "
                               "${v8_receiver}->CreationContext();")),
        S("receiver_script_state",
          ("ScriptState* ${receiver_script_state} = "
           "ScriptState::From(${receiver_context});")),
    ])

    is_receiver_context = not (
        (cg_context.member_like and cg_context.member_like.is_static)
        or cg_context.constructor)

    # creation_context
    pattern = "const v8::Local<v8::Context>& ${creation_context} = {_1};"
    _1 = "${receiver_context}" if is_receiver_context else "${current_context}"
    local_vars.append(S("creation_context", _format(pattern, _1=_1)))

    # creation_context_object
    text = ("${v8_receiver}"
            if is_receiver_context else "${current_context}->Global()")
    template_vars["creation_context_object"] = T(text)

    # script_state
    pattern = "ScriptState* ${script_state} = {_1};"
    _1 = ("${receiver_script_state}"
          if is_receiver_context else "${current_script_state}")
    local_vars.append(S("script_state", _format(pattern, _1=_1)))

    # execution_context
    pattern = "ExecutionContext* ${execution_context} = {_1};"
    _1 = ("${receiver_execution_context}"
          if is_receiver_context else "${current_execution_context}")
    local_vars.append(S("execution_context", _format(pattern, _1=_1)))
    node = S("current_execution_context",
             ("ExecutionContext* ${current_execution_context} = "
              "ExecutionContext::From(${current_context});"))
    node.accumulate(
        CodeGenAccumulator.require_include_headers([
            "third_party/blink/renderer/core/execution_context/execution_context.h"
        ]))
    local_vars.append(node)
    node = S("receiver_execution_context",
             ("ExecutionContext* ${receiver_execution_context} = "
              "ExecutionContext::From(${receiver_context});"))
    node.accumulate(
        CodeGenAccumulator.require_include_headers([
            "third_party/blink/renderer/core/execution_context/execution_context.h"
        ]))
    local_vars.append(node)

    # execution_context_of_document_tree
    pattern = "ExecutionContext* ${execution_context_of_document_tree} = {_1};"
    if is_receiver_context:
        _1 = "bindings::ExecutionContextFromV8Wrappable(${blink_receiver})"
    else:
        _1 = "${current_execution_context}"
    text = _format(pattern, _1=_1)
    local_vars.append(S("execution_context_of_document_tree", text))

    # exception_state_context_type
    pattern = (
        "const ExceptionState::ContextType ${exception_state_context_type} = "
        "{_1};")
    if cg_context.attribute_get:
        _1 = "ExceptionState::kGetterContext"
    elif cg_context.attribute_set:
        _1 = "ExceptionState::kSetterContext"
    elif cg_context.constructor_group:
        _1 = "ExceptionState::kConstructionContext"
    elif cg_context.indexed_property_getter:
        _1 = "ExceptionState::kIndexedGetterContext"
    elif cg_context.indexed_property_setter:
        _1 = "ExceptionState::kIndexedSetterContext"
    elif cg_context.named_property_getter:
        _1 = "ExceptionState::kNamedGetterContext"
    elif cg_context.named_property_setter:
        _1 = "ExceptionState::kNamedSetterContext"
    elif cg_context.named_property_deleter:
        _1 = "ExceptionState::kNamedDeletionContext"
    else:
        _1 = "ExceptionState::kExecutionContext"
    local_vars.append(
        S("exception_state_context_type", _format(pattern, _1=_1)))

    # exception_state
    pattern = "ExceptionState ${exception_state}({_1});{_2}"
    _1 = ["${isolate}", "${exception_state_context_type}"]
    if cg_context.is_named_constructor:
        _1.append("\"{}\"".format(cg_context.property_.identifier))
    else:
        _1.append("${class_like_name}")
    if (cg_context.property_ and cg_context.property_.identifier
            and not cg_context.constructor_group):
        _1.append("${property_name}")
    _2 = ""
    if cg_context.is_return_type_promise_type:
        _2 = ("\n"
              "ExceptionToRejectPromiseScope reject_promise_scope"
              "(${info}, ${exception_state});")
    local_vars.append(
        S("exception_state", _format(pattern, _1=", ".join(_1), _2=_2)))

    # blink_receiver
    if cg_context.class_like.identifier == "Window":
        # TODO(yukishiino): Window interface should be
        # [ImplementedAs=LocalDOMWindow] instead of [ImplementedAs=DOMWindow],
        # and [CrossOrigin] properties should be implemented specifically with
        # DOMWindow class.  Then, we'll have less hacks.
        if (not cg_context.member_like or
                "CrossOrigin" in cg_context.member_like.extended_attributes):
            text = ("DOMWindow* ${blink_receiver} = "
                    "${class_name}::ToWrappableUnsafe(${v8_receiver});")
        else:
            text = ("LocalDOMWindow* ${blink_receiver} = To<LocalDOMWindow>("
                    "${class_name}::ToWrappableUnsafe(${v8_receiver}));")
    else:
        pattern = ("{_1}* ${blink_receiver} = "
                   "${class_name}::ToWrappableUnsafe(${v8_receiver});")
        _1 = blink_class_name(cg_context.class_like)
        text = _format(pattern, _1=_1)
    local_vars.append(S("blink_receiver", text))

    # v8_property_value
    if cg_context.v8_callback_type == CodeGenContext.V8_FUNCTION_CALLBACK:
        # In case of V8_ACCESSOR_NAME_SETTER_CALLBACK, |v8_property_value| is
        # defined as an argument.  In case of V8_FUNCTION_CALLBACK (of IDL
        # attribute set function), |info[0]| is the value to be set.
        local_vars.append(
            S("v8_property_value",
              "v8::Local<v8::Value> ${v8_property_value} = ${info}[0];"))

    # v8_receiver
    if cg_context.v8_callback_type == CodeGenContext.V8_FUNCTION_CALLBACK:
        # In case of v8::FunctionCallbackInfo, This() is the receiver object.
        local_vars.append(
            S("v8_receiver",
              "v8::Local<v8::Object> ${v8_receiver} = ${info}.This();"))
    else:
        # In case of v8::PropertyCallbackInfo, Holder() is the object that has
        # the property being processed.
        local_vars.append(
            S("v8_receiver",
              "v8::Local<v8::Object> ${v8_receiver} = ${info}.Holder();"))

    # throw_security_error
    template_vars["throw_security_error"] = T(
        "BindingSecurity::FailedAccessCheckFor("
        "${info}.GetIsolate(), "
        "${class_name}::GetWrapperTypeInfo(), "
        "${info}.Holder());")

    code_node.register_code_symbols(local_vars)
    code_node.add_template_vars(template_vars)


def _make_reflect_content_attribute_key(code_node, cg_context):
    assert isinstance(code_node, SymbolScopeNode)
    assert isinstance(cg_context, CodeGenContext)

    name = (cg_context.attribute.extended_attributes.value_of("Reflect")
            or cg_context.attribute.identifier.lower())
    if cg_context.attribute_get and name in ("class", "id", "name"):
        return None

    if cg_context.class_like.identifier.startswith("SVG"):
        namespace = "svg_names"
        code_node.accumulate(
            CodeGenAccumulator.require_include_headers(
                ["third_party/blink/renderer/core/svg_names.h"]))
    else:
        namespace = "html_names"
        code_node.accumulate(
            CodeGenAccumulator.require_include_headers(
                ["third_party/blink/renderer/core/html_names.h"]))
    return "{}::{}".format(namespace, name_style.constant(name, "attr"))


def _make_reflect_accessor_func_name(cg_context):
    assert isinstance(cg_context, CodeGenContext)
    assert cg_context.attribute_get or cg_context.attribute_set

    if cg_context.attribute_get:
        name = (cg_context.attribute.extended_attributes.value_of("Reflect")
                or cg_context.attribute.identifier.lower())
        if name in ("class", "id", "name"):
            return name_style.func("get", name, "attribute")

        if "URL" in cg_context.attribute.extended_attributes:
            return "GetURLAttribute"

    FAST_ACCESSORS = {
        "boolean": ("FastHasAttribute", "SetBooleanAttribute"),
        "long": ("GetIntegralAttribute", "SetIntegralAttribute"),
        "unsigned long": ("GetUnsignedIntegralAttribute",
                          "SetUnsignedIntegralAttribute"),
    }
    idl_type = cg_context.attribute.idl_type.unwrap()
    accessors = FAST_ACCESSORS.get(idl_type.keyword_typename)
    if accessors:
        return accessors[0 if cg_context.attribute_get else 1]

    if (idl_type.is_interface
            and idl_type.type_definition_object.does_implement("Element")):
        if cg_context.attribute_get:
            return "GetElementAttribute"
        else:
            return "SetElementAttribute"

    if idl_type.element_type:
        element_type = idl_type.element_type.unwrap()
        if (element_type.is_interface and
                element_type.type_definition_object.does_implement("Element")):
            if cg_context.attribute_get:
                return "GetElementArrayAttribute"
            else:
                return "SetElementArrayAttribute"

    if cg_context.attribute_get:
        return "FastGetAttribute"
    else:
        return "setAttribute"


def _make_reflect_process_keyword_state(cg_context):
    # https://html.spec.whatwg.org/C/#keywords-and-enumerated-attributes

    assert isinstance(cg_context, CodeGenContext)
    assert cg_context.attribute_get or cg_context.attribute_set

    T = TextNode
    F = lambda *args, **kwargs: T(_format(*args, **kwargs))

    if not cg_context.attribute_get:
        return None

    ext_attrs = cg_context.attribute.extended_attributes
    keywords = ext_attrs.values_of("ReflectOnly")
    missing_default = ext_attrs.value_of("ReflectMissing")
    empty_default = ext_attrs.value_of("ReflectEmpty")
    invalid_default = ext_attrs.value_of("ReflectInvalid")

    def constant(keyword):
        if not keyword:
            return "g_empty_atom"
        return "keywords::{}".format(name_style.constant(keyword))

    branches = CxxMultiBranchesNode()
    branches.accumulate(
        CodeGenAccumulator.require_include_headers(
            ["third_party/blink/renderer/core/keywords.h"]))
    nodes = [
        T("// [ReflectOnly]"),
        T("const AtomicString reflect_value(${return_value}.LowerASCII());"),
        branches,
    ]

    if missing_default is not None:
        branches.append(
            cond="reflect_value.IsNull()",
            body=F("${return_value} = {};", constant(missing_default)))
    elif cg_context.return_type.unwrap(nullable=False).is_nullable:
        branches.append(
            cond="reflect_value.IsNull()",
            body=T("// Null string to IDL null."))

    if empty_default is not None:
        branches.append(
            cond="reflect_value.IsEmpty()",
            body=F("${return_value} = {};", constant(empty_default)))

    expr = " || ".join(
        map(lambda keyword: "reflect_value == {}".format(constant(keyword)),
            keywords))
    branches.append(cond=expr, body=T("${return_value} = reflect_value;"))

    if invalid_default is not None:
        branches.append(
            cond=True,
            body=F("${return_value} = {};", constant(invalid_default)))
    else:
        branches.append(
            cond=True, body=F("${return_value} = {};", constant("")))

    return SequenceNode(nodes)


def _make_blink_api_call(code_node,
                         cg_context,
                         num_of_args=None,
                         overriding_args=None):
    assert isinstance(code_node, SymbolScopeNode)
    assert isinstance(cg_context, CodeGenContext)
    assert num_of_args is None or isinstance(num_of_args, int)
    assert (overriding_args is None
            or (isinstance(overriding_args, (list, tuple))
                and all(isinstance(arg, str) for arg in overriding_args)))

    arguments = []
    ext_attrs = cg_context.member_like.extended_attributes

    values = ext_attrs.values_of("CallWith") + (
        ext_attrs.values_of("GetterCallWith") if cg_context.attribute_get else
        ext_attrs.values_of("SetterCallWith") if cg_context.attribute_set else
        ())
    if "Isolate" in values:
        arguments.append("${isolate}")
    if "ScriptState" in values:
        arguments.append("${script_state}")
    if "ExecutionContext" in values:
        arguments.append("${execution_context}")
    if "Document" in values:
        arguments.append(
            "*bindings::ToDocumentFromExecutionContext(${execution_context})")
    if "ThisValue" in values:
        arguments.append("ScriptValue(${isolate}, ${v8_receiver})")

    code_generator_info = cg_context.member_like.code_generator_info
    is_partial = code_generator_info.defined_in_partial
    if (is_partial and
            not (cg_context.constructor or cg_context.member_like.is_static)):
        arguments.append("*${blink_receiver}")

    if "Reflect" in ext_attrs:  # [Reflect]
        key = _make_reflect_content_attribute_key(code_node, cg_context)
        if key:
            arguments.append(key)

    if overriding_args is not None:
        arguments.extend(overriding_args)
    elif cg_context.attribute_get:
        pass
    elif cg_context.attribute_set:
        arguments.append("${arg1_value}")
    else:
        for index, argument in enumerate(cg_context.function_like.arguments):
            if num_of_args is not None and index == num_of_args:
                break
            name = name_style.arg_f("arg{}_{}", index + 1, argument.identifier)
            arguments.append(_format("${{{}}}", name))

    if cg_context.is_return_by_argument:
        arguments.append("${return_value}")

    if cg_context.may_throw_exception:
        arguments.append("${exception_state}")

    func_name = backward_compatible_api_func(cg_context)
    if cg_context.constructor:
        if cg_context.is_named_constructor:
            func_name = "CreateForJSConstructor"
        else:
            func_name = "Create"
    if "Reflect" in ext_attrs:  # [Reflect]
        func_name = _make_reflect_accessor_func_name(cg_context)

    if (cg_context.constructor or cg_context.member_like.is_static
            or is_partial):
        class_like = cg_context.member_like.owner_mixin or cg_context.class_like
        class_name = (code_generator_info.receiver_implemented_as
                      or name_style.class_(class_like.identifier))
        func_designator = "{}::{}".format(class_name, func_name)
    else:
        func_designator = _format("${blink_receiver}->{}", func_name)

    return _format("{_1}({_2})", _1=func_designator, _2=", ".join(arguments))


def bind_return_value(code_node, cg_context, overriding_args=None):
    assert isinstance(code_node, SymbolScopeNode)
    assert isinstance(cg_context, CodeGenContext)
    assert (overriding_args is None
            or (isinstance(overriding_args, (list, tuple))
                and all(isinstance(arg, str) for arg in overriding_args)))

    T = TextNode
    F = lambda *args, **kwargs: T(_format(*args, **kwargs))

    def create_definition(symbol_node):
        api_calls = []  # Pairs of (num_of_args, api_call_text)
        if overriding_args is None:
            arguments = (cg_context.function_like.arguments
                         if cg_context.function_like else [])
            for index, arg in enumerate(arguments):
                if arg.is_optional and not arg.default_value:
                    api_calls.append((index,
                                      _make_blink_api_call(
                                          code_node, cg_context, index)))
            api_calls.append((None, _make_blink_api_call(
                code_node, cg_context)))
        else:
            api_calls.append((None,
                              _make_blink_api_call(
                                  code_node,
                                  cg_context,
                                  overriding_args=overriding_args)))

        nodes = []
        is_return_type_void = ((not cg_context.return_type
                                or cg_context.return_type.unwrap().is_void) and
                               not cg_context.does_override_idl_return_type)
        if not (is_return_type_void
                or cg_context.does_override_idl_return_type):
            return_type = blink_type_info(cg_context.return_type).value_t
        if len(api_calls) == 1:
            _, api_call = api_calls[0]
            if is_return_type_void:
                nodes.append(F("{};", api_call))
            elif cg_context.is_return_by_argument:
                nodes.append(F("{} ${return_value};", return_type))
                nodes.append(F("{};", api_call))
            elif "ReflectOnly" in cg_context.member_like.extended_attributes:
                # [ReflectOnly]
                nodes.append(F("auto ${return_value} = {};", api_call))
            else:
                nodes.append(F("auto&& ${return_value} = {};", api_call))
        else:
            branches = SequenceNode()
            for index, api_call in api_calls:
                if is_return_type_void or cg_context.is_return_by_argument:
                    assignment = "{};".format(api_call)
                else:
                    assignment = _format("${return_value} = {};", api_call)
                if index is not None:
                    branches.append(
                        CxxLikelyIfNode(
                            cond=_format(
                                "${non_undefined_argument_length} <= {}",
                                index),
                            body=[
                                T(assignment),
                                T("break;"),
                            ]))
                else:
                    branches.append(T(assignment))

            if not is_return_type_void:
                nodes.append(F("{} ${return_value};", return_type))
            nodes.append(CxxBreakableBlockNode(branches))

        if cg_context.may_throw_exception:
            nodes.append(
                CxxUnlikelyIfNode(
                    cond="${exception_state}.HadException()",
                    body=T("return;")))

        if "ReflectOnly" in cg_context.member_like.extended_attributes:
            # [ReflectOnly]
            node = _make_reflect_process_keyword_state(cg_context)
            if node:
                nodes.append(EmptyNode())
                nodes.append(node)

        return SymbolDefinitionNode(symbol_node, nodes)

    code_node.register_code_symbol(
        SymbolNode("return_value", definition_constructor=create_definition))


def make_bindings_trace_event(cg_context):
    assert isinstance(cg_context, CodeGenContext)

    event_name = "{}.{}".format(cg_context.class_like.identifier,
                                cg_context.property_.identifier)
    if cg_context.attribute_get:
        event_name = "{}.{}".format(event_name, "get")
    elif cg_context.attribute_set:
        event_name = "{}.{}".format(event_name, "set")
    elif cg_context.constructor_group and not cg_context.is_named_constructor:
        event_name = "{}.{}".format(cg_context.class_like.identifier,
                                    "constructor")

    return TextNode("BLINK_BINDINGS_TRACE_EVENT(\"{}\");".format(event_name))


def make_check_argument_length(cg_context):
    assert isinstance(cg_context, CodeGenContext)

    T = TextNode
    F = lambda *args, **kwargs: T(_format(*args, **kwargs))

    if cg_context.v8_callback_type != CodeGenContext.V8_FUNCTION_CALLBACK:
        return None

    if cg_context.attribute_get:
        num_of_required_args = 0
    elif cg_context.attribute_set:
        idl_type = cg_context.attribute.idl_type
        if not (idl_type.does_include_nullable_or_dict
                or idl_type.unwrap().is_any or "LegacyTreatNonObjectAsNull" in
                idl_type.unwrap().extended_attributes
                or "PutForwards" in cg_context.attribute.extended_attributes
                or "Replaceable" in cg_context.attribute.extended_attributes):
            # ES undefined in ${v8_property_value} will cause a TypeError
            # anyway, so omit the check against the number of arguments.
            return None
        num_of_required_args = 1
    elif cg_context.function_like:
        num_of_required_args = (
            cg_context.function_like.num_of_required_arguments)
    elif isinstance(cg_context.property_, web_idl.OverloadGroup):
        num_of_required_args = (
            cg_context.property_.min_num_of_required_arguments)
    else:
        assert False

    if num_of_required_args == 0:
        return None

    return CxxUnlikelyIfNode(
        cond=_format("UNLIKELY(${info}.Length() < {})", num_of_required_args),
        body=[
            F(("${exception_state}.ThrowTypeError("
               "ExceptionMessages::NotEnoughArguments"
               "({}, ${info}.Length()));"), num_of_required_args),
            T("return;"),
        ])


def make_check_constructor_call(cg_context):
    assert isinstance(cg_context, CodeGenContext)

    T = TextNode

    node = SequenceNode([
        CxxUnlikelyIfNode(
            cond="!${info}.IsConstructCall()",
            body=T("${exception_state}.ThrowTypeError("
                   "ExceptionMessages::ConstructorCalledAsFunction());\n"
                   "return;")),
    ])
    if not cg_context.is_named_constructor:
        node.append(
            CxxLikelyIfNode(
                cond=("ConstructorMode::Current(${isolate}) == "
                      "ConstructorMode::kWrapExistingObject"),
                body=T("bindings::V8SetReturnValue(${info}, ${v8_receiver});\n"
                       "return;")))
    node.accumulate(
        CodeGenAccumulator.require_include_headers([
            "third_party/blink/renderer/platform/bindings/v8_object_constructor.h"
        ]))
    return node


def make_check_receiver(cg_context):
    assert isinstance(cg_context, CodeGenContext)

    T = TextNode

    if cg_context.member_like.is_static:
        return None

    if (cg_context.attribute and
            "LegacyLenientThis" in cg_context.attribute.extended_attributes):
        return SequenceNode([
            T("// [LegacyLenientThis]"),
            CxxUnlikelyIfNode(
                cond="!${class_name}::HasInstance(${isolate}, ${v8_receiver})",
                body=T("return;")),
        ])

    if cg_context.is_return_type_promise_type:
        return SequenceNode([
            T("// Promise returning function: "
              "Convert a TypeError to a reject promise."),
            CxxUnlikelyIfNode(
                cond="!${class_name}::HasInstance(${isolate}, ${v8_receiver})",
                body=[
                    T("${exception_state}.ThrowTypeError("
                      "\"Illegal invocation\");"),
                    T("return;"),
                ])
        ])

    return None


def make_check_security_of_return_value(cg_context):
    assert isinstance(cg_context, CodeGenContext)

    T = TextNode

    check_security = cg_context.member_like.extended_attributes.value_of(
        "CheckSecurity")
    if check_security != "ReturnValue":
        return None

    web_feature = _format(
        "WebFeature::{}",
        name_style.constant("CrossOrigin", cg_context.class_like.identifier,
                            cg_context.property_.identifier))
    use_counter = _format(
        "UseCounter::Count(${current_execution_context}, {});", web_feature)
    cond = T("!BindingSecurity::ShouldAllowAccessTo("
             "ToLocalDOMWindow(${current_context}), ${return_value}, "
             "BindingSecurity::ErrorReportOption::kDoNotReport)")
    body = [
        T(use_counter),
        T("bindings::V8SetReturnValue(${info}, nullptr);\n"
          "return;"),
    ]
    node = SequenceNode([
        T("// [CheckSecurity=ReturnValue]"),
        CxxUnlikelyIfNode(cond=cond, body=body),
    ])
    node.accumulate(
        CodeGenAccumulator.require_include_headers([
            "third_party/blink/renderer/bindings/core/v8/binding_security.h",
            "third_party/blink/renderer/core/frame/web_feature.h",
            "third_party/blink/renderer/platform/instrumentation/use_counter.h",
        ]))
    return node


def make_cooperative_scheduling_safepoint(cg_context):
    assert isinstance(cg_context, CodeGenContext)

    node = TextNode("scheduler::CooperativeSchedulingManager::Instance()"
                    "->Safepoint();")
    node.accumulate(
        CodeGenAccumulator.require_include_headers([
            "third_party/blink/renderer/platform/scheduler/public/cooperative_scheduling_manager.h"
        ]))
    return node


def make_log_activity(cg_context):
    assert isinstance(cg_context, CodeGenContext)

    target = cg_context.member_like or cg_context.property_
    ext_attrs = target.extended_attributes
    if "LogActivity" not in ext_attrs:
        return None
    target = ext_attrs.value_of("LogActivity")
    if target:
        assert target in ("GetterOnly", "SetterOnly")
        if ((target == "GetterOnly" and not cg_context.attribute_get)
                or (target == "SetterOnly" and not cg_context.attribute_set)):
            return None
    if (cg_context.for_world == cg_context.MAIN_WORLD
            and "LogAllWorlds" not in ext_attrs):
        return None

    pattern = "{_1}${per_context_data} && ${per_context_data}->ActivityLogger()"
    _1 = ""
    if (cg_context.attribute and "PerWorldBindings" not in ext_attrs
            and "LogAllWorlds" not in ext_attrs):
        _1 = "${script_state}->World().IsIsolatedWorld() && "
    cond = _format(pattern, _1=_1)

    pattern = "${per_context_data}->ActivityLogger()->{_1}(\"{_2}.{_3}\"{_4});"
    _2 = cg_context.class_like.identifier
    _3 = cg_context.property_.identifier
    if cg_context.attribute_get:
        _1 = "LogGetter"
        _4 = ""
    elif cg_context.attribute_set:
        _1 = "LogSetter"
        _4 = ", ${v8_property_value}"
    elif cg_context.operation_group:
        _1 = "LogMethod"
        _4 = ", ${info}"
    body = _format(pattern, _1=_1, _2=_2, _3=_3, _4=_4)

    pattern = ("// [LogActivity], [LogAllWorlds]\n" "if ({_1}) {{ {_2} }}")
    node = TextNode(_format(pattern, _1=cond, _2=body))
    node.accumulate(
        CodeGenAccumulator.require_include_headers([
            "third_party/blink/renderer/platform/bindings/v8_dom_activity_logger.h",
            "third_party/blink/renderer/platform/bindings/v8_per_context_data.h",
        ]))
    return node


def _make_overload_dispatcher_per_arg_size(cg_context, items):
    """
    https://heycam.github.io/webidl/#dfn-overload-resolution-algorithm

    Args:
        items: Partial list of an "effective overload set" with the same
            type list size.

    Returns:
        A pair of a resulting CodeNode and a boolean flag that is True if there
        exists a case that overload resolution will fail, i.e. a bailout that
        throws a TypeError is necessary.
    """
    assert isinstance(cg_context, CodeGenContext)
    assert isinstance(items, (list, tuple))
    assert all(
        isinstance(item, web_idl.OverloadGroup.EffectiveOverloadItem)
        for item in items)

    # Variables shared with nested functions
    if len(items) > 1:
        arg_index = web_idl.OverloadGroup.distinguishing_argument_index(items)
    else:
        arg_index = None
    func_like = None
    dispatcher_nodes = SequenceNode()

    # True if there exists a case that overload resolution will fail.
    can_fail = True

    def find_test(item, test):
        # |test| is a callable that takes (t, u) where:
        #   t = the idl_type (in the original form)
        #   u = the unwrapped version of t
        idl_type = item.type_list[arg_index]
        t = idl_type
        u = idl_type.unwrap()
        return test(t, u) or (u.is_union and any(
            [test(m, m.unwrap()) for m in u.flattened_member_types]))

    def find(test):
        for item in items:
            if find_test(item, test):
                return item.function_like
        return None

    def find_all_interfaces():
        result = []  # [(func_like, idl_type), ...]
        for item in items:
            idl_type = item.type_list[arg_index].unwrap()
            if idl_type.is_interface:
                result.append((item.function_like, idl_type))
            if idl_type.is_union:
                for member_type in idl_type.flattened_member_types:
                    if member_type.unwrap().is_interface:
                        result.append((item.function_like,
                                       member_type.unwrap()))
        return result

    def make_node(pattern):
        value = _format("${info}[{}]", arg_index)
        func_name = callback_function_name(cg_context,
                                           func_like.overload_index)
        return TextNode(_format(pattern, value=value, func_name=func_name))

    def dispatch_if(expr):
        if expr is True:
            pattern = "return {func_name}(${info});"
        else:
            pattern = ("if (" + expr + ") {{\n"
                       "  return {func_name}(${info});\n"
                       "}}")
        node = make_node(pattern)
        conditional = expr_from_exposure(func_like.exposure)
        if not conditional.is_always_true:
            node = CxxUnlikelyIfNode(cond=conditional, body=node)
        dispatcher_nodes.append(node)
        return expr is True and conditional.is_always_true

    if len(items) == 1:
        func_like = items[0].function_like
        can_fail = False
        return make_node("return {func_name}(${info});"), can_fail

    # 12.2. If V is undefined, ...
    func_like = find(lambda t, u: t.is_optional)
    if func_like:
        dispatch_if("{value}->IsUndefined()")

    # 12.3. if V is null or undefined, ...
    func_like = find(lambda t, u: t.does_include_nullable_or_dict)
    if func_like:
        dispatch_if("{value}->IsNullOrUndefined()")

    # 12.4. if V is a platform object, ...
    def inheritance_length(func_and_type):
        return (len(func_and_type[1].type_definition_object.
                    inclusive_inherited_interfaces),
                func_and_type[1].type_definition_object.identifier)

    # Attempt to match from most derived to least derived.
    for func_like, idl_type in sorted(
            find_all_interfaces(), key=inheritance_length, reverse=True):
        v8_bridge_name = v8_bridge_class_name(
            idl_type.unwrap().type_definition_object)
        dispatch_if(
            _format("{}::HasInstance(${isolate}, {value})", v8_bridge_name))

    # V8 specific optimization: BufferSource = ArrayBufferView or ArrayBuffer
    is_typedef_name = lambda t, name: t.is_typedef and t.identifier == name
    func_like = find(
        lambda t, u: is_typedef_name(t.unwrap(typedef=False), "BufferSource"))
    if func_like:
        dispatch_if("{value}->IsArrayBufferView() || "
                    "{value}->IsArrayBuffer() || "
                    "{value}->IsSharedArrayBuffer()")
    else:
        # 12.5. if Type(V) is Object, V has an [[ArrayBufferData]] internal
        #   slot, ...
        func_like = find(lambda t, u: u.is_array_buffer)
        if func_like:
            dispatch_if("{value}->IsArrayBuffer() || "
                        "{value}->IsSharedArrayBuffer()")

        # V8 specific optimization: ArrayBufferView
        func_like = find(lambda t, u: u.is_array_buffer_view)
        if func_like:
            dispatch_if("{value}->IsArrayBufferView()")

    # 12.6. if Type(V) is Object, V has a [[DataView]] internal slot, ...
    func_like = find(lambda t, u: u.is_data_view)
    if func_like:
        dispatch_if("{value}->IsDataView()")

    # 12.7. if Type(V) is Object, V has a [[TypedArrayName]] internal slot, ...
    typed_array_types = ("Int8Array", "Int16Array", "Int32Array", "Uint8Array",
                         "Uint16Array", "Uint32Array", "Uint8ClampedArray",
                         "Float32Array", "Float64Array")
    for typed_array_type in typed_array_types:
        func_like = find(lambda t, u: u.keyword_typename == typed_array_type)
        if func_like:
            dispatch_if(_format("{value}->Is{}()", typed_array_type))

    # 12.8. if IsCallable(V) is true, ...
    func_like = find(lambda t, u: u.is_callback_function)
    if func_like:
        dispatch_if("{value}->IsFunction()")

    # 12.9. if Type(V) is Object and ... @@iterator ...
    func_like = find(lambda t, u: u.is_sequence or u.is_frozen_array)
    if func_like:
        dispatch_if("{value}->IsArray() || "  # Excessive optimization
                    "bindings::IsEsIterableObject"
                    "(${isolate}, {value}, ${exception_state})")
        dispatcher_nodes.append(
            CxxUnlikelyIfNode(cond="${exception_state}.HadException()",
                              body=TextNode("return;")))

    # 12.10. if Type(V) is Object and ...
    func_like = find(lambda t, u: u.is_callback_interface or u.is_dictionary or
                     u.is_record or u.is_object)
    if func_like:
        dispatch_if("{value}->IsObject()")

    # 12.11. if Type(V) is Boolean and ...
    func_like = find(lambda t, u: u.is_boolean)
    if func_like:
        dispatch_if("{value}->IsBoolean()")

    # 12.12. if Type(V) is Number and ...
    func_like = find(lambda t, u: u.is_numeric)
    if func_like:
        dispatch_if("{value}->IsNumber()")

    # 12.13. if there is an entry in S that has ... a string type ...
    # 12.14. if there is an entry in S that has ... a numeric type ...
    # 12.15. if there is an entry in S that has ... boolean ...
    # 12.16. if there is an entry in S that has any ...
    func_likes = [
        find(lambda t, u: u.is_enumeration),
        find(lambda t, u: u.is_string),
        find(lambda t, u: u.is_numeric),
        find(lambda t, u: u.is_boolean),
        find(lambda t, u: u.is_any),
    ]
    for func_like in func_likes:
        if func_like:
            if dispatch_if(True):
                can_fail = False
                break

    return dispatcher_nodes, can_fail


def make_overload_dispatcher(cg_context):
    # https://heycam.github.io/webidl/#dfn-overload-resolution-algorithm

    assert isinstance(cg_context, CodeGenContext)

    T = TextNode
    F = lambda *args, **kwargs: T(_format(*args, **kwargs))

    overload_group = cg_context.property_
    items = overload_group.effective_overload_set()
    args_size = lambda item: len(item.type_list)
    items_grouped_by_arg_size = itertools.groupby(
        sorted(items, key=args_size, reverse=True), key=args_size)

    # TODO(yukishiino): Runtime-enabled features should be taken into account
    # when calculating the max argument size.
    max_arg_size = max(map(args_size, items))
    arg_count_def = F("const int arg_count = std::min(${info}.Length(), {});",
                      max_arg_size)

    branches = SequenceNode()
    did_use_break = False
    for arg_size, items in items_grouped_by_arg_size:
        items = list(items)

        node, can_fail = _make_overload_dispatcher_per_arg_size(
            cg_context, items)

        if arg_size > 0:
            node = CxxLikelyIfNode(
                cond="arg_count == {}".format(arg_size),
                body=[node, T("break;") if can_fail else None])
            did_use_break = did_use_break or can_fail

        conditional = expr_or(
            list(
                map(
                    lambda item: expr_from_exposure(item.function_like.exposure
                                                    ), items)))
        if not conditional.is_always_true:
            node = CxxUnlikelyIfNode(cond=conditional, body=node)

        branches.append(node)

    if did_use_break:
        branches = CxxBreakableBlockNode(branches)
    branches = SequenceNode([
        arg_count_def,
        branches,
    ])

    if not did_use_break and arg_size == 0 and conditional.is_always_true:
        return branches

    return SequenceNode([
        branches,
        EmptyNode(),
        make_check_argument_length(cg_context),
        T("${exception_state}.ThrowTypeError"
          "(\"Overload resolution failed.\");\n"
          "return;"),
    ])


def make_report_coop_access(cg_context):
    assert isinstance(cg_context, CodeGenContext)

    if cg_context.class_like.identifier != "Window":
        return None

    ext_attrs = cg_context.member_like.extended_attributes
    if "CrossOrigin" not in ext_attrs:
        return None

    values = ext_attrs.values_of("CrossOrigin")
    if (cg_context.attribute_get and not (not values or "Getter" in values)):
        return None
    elif (cg_context.attribute_set and not ("Setter" in values)):
        return None

    return TextNode("${blink_receiver}->ReportCoopAccess(${property_name});")


def make_report_deprecate_as(cg_context):
    assert isinstance(cg_context, CodeGenContext)

    target = cg_context.member_like or cg_context.property_
    name = target.extended_attributes.value_of("DeprecateAs")
    if not name:
        return None

    pattern = ("// [DeprecateAs]\n"
               "Deprecation::CountDeprecation("
               "${current_execution_context}, WebFeature::k{_1});")
    _1 = name
    node = TextNode(_format(pattern, _1=_1))
    node.accumulate(
        CodeGenAccumulator.require_include_headers(
            ["third_party/blink/renderer/core/frame/deprecation.h"]))
    return node


def _make_measure_web_feature_constant(cg_context):
    assert isinstance(cg_context, CodeGenContext)

    target = cg_context.member_like or cg_context.property_
    ext_attrs = target.extended_attributes

    suffix = ""
    if cg_context.attribute_get:
        suffix = "_AttributeGetter"
    elif cg_context.attribute_set:
        suffix = "_AttributeSetter"
    elif cg_context.constructor:
        suffix = "_Constructor"
    elif cg_context.exposed_construct:
        suffix = "_ConstructorGetter"
    elif cg_context.operation:
        suffix = "_Method"

    name = ext_attrs.value_of("MeasureAs") or ext_attrs.value_of("Measure")
    if name:
        name = "k{}".format(name)
    elif cg_context.constructor:
        name = "kV8{}{}".format(cg_context.class_like.identifier, suffix)
    else:
        name = "kV8{}_{}{}".format(
            cg_context.class_like.identifier,
            name_style.raw.upper_camel_case(cg_context.property_.identifier),
            suffix)

    return "WebFeature::{}".format(name)


def make_report_high_entropy(cg_context):
    assert isinstance(cg_context, CodeGenContext)

    target = cg_context.member_like or cg_context.property_
    ext_attrs = target.extended_attributes
    if cg_context.attribute_set or "HighEntropy" not in ext_attrs:
        return None
    assert "Measure" in ext_attrs or "MeasureAs" in ext_attrs, "{}: {}".format(
        cg_context.idl_location_and_name,
        "[HighEntropy] must be specified with either [Measure] or "
        "[MeasureAs].")

    if ext_attrs.value_of("HighEntropy") == "Direct":
        text = _format(
            "// [HighEntropy=Direct]\n"
            "Dactyloscoper::RecordDirectSurface("
            "${current_execution_context}, {measure_constant}, "
            "${return_value});",
            measure_constant=_make_measure_web_feature_constant(cg_context))
    else:
        text = _format(
            "// [HighEntropy]\n"
            "Dactyloscoper::Record("
            "${current_execution_context}, {measure_constant});",
            measure_constant=_make_measure_web_feature_constant(cg_context))
    node = TextNode(text)
    node.accumulate(
        CodeGenAccumulator.require_include_headers(
            ["third_party/blink/renderer/core/frame/dactyloscoper.h"]))
    return node


def make_report_measure_as(cg_context):
    assert isinstance(cg_context, CodeGenContext)

    target = cg_context.member_like or cg_context.property_
    ext_attrs = target.extended_attributes
    if not ("Measure" in ext_attrs or "MeasureAs" in ext_attrs):
        return None

    text = _format(
        "// [Measure], [MeasureAs]\n"
        "UseCounter::Count(${current_execution_context}, {measure_constant});",
        measure_constant=_make_measure_web_feature_constant(cg_context))
    node = TextNode(text)
    node.accumulate(
        CodeGenAccumulator.require_include_headers([
            "third_party/blink/renderer/core/frame/web_feature.h",
            "third_party/blink/renderer/platform/instrumentation/use_counter.h",
        ]))
    return node


def make_return_value_cache_return_early(cg_context):
    assert isinstance(cg_context, CodeGenContext)

    pred = cg_context.member_like.extended_attributes.value_of(
        "CachedAttribute")
    if pred:
        return TextNode("""\
// [CachedAttribute]
static const V8PrivateProperty::SymbolKey kPrivatePropertyCachedAttribute;
auto&& v8_private_cached_attribute =
    V8PrivateProperty::GetSymbol(${isolate}, kPrivatePropertyCachedAttribute);
if (!${blink_receiver}->""" + pred + """()) {
  v8::Local<v8::Value> v8_value;
  if (!v8_private_cached_attribute.GetOrUndefined(${v8_receiver})
           .ToLocal(&v8_value)) {
    return;
  }
  if (!v8_value->IsUndefined()) {
    bindings::V8SetReturnValue(${info}, v8_value);
    return;
  }
}""")

    if "SaveSameObject" in cg_context.member_like.extended_attributes:
        return TextNode("""\
// [SaveSameObject]
static const V8PrivateProperty::SymbolKey kPrivatePropertySaveSameObject;
auto&& v8_private_save_same_object =
    V8PrivateProperty::GetSymbol(${isolate}, kPrivatePropertySaveSameObject);
{
  v8::Local<v8::Value> v8_value;
  if (!v8_private_save_same_object.GetOrUndefined(${v8_receiver})
           .ToLocal(&v8_value)) {
    return;
  }
  if (!v8_value->IsUndefined()) {
    bindings::V8SetReturnValue(${info}, v8_value);
    return;
  }
}""")


def make_return_value_cache_update_value(cg_context):
    assert isinstance(cg_context, CodeGenContext)

    if "CachedAttribute" in cg_context.member_like.extended_attributes:
        return TextNode("// [CachedAttribute]\n"
                        "v8_private_cached_attribute.Set"
                        "(${v8_receiver}, ${info}.GetReturnValue().Get());")

    if "SaveSameObject" in cg_context.member_like.extended_attributes:
        return TextNode("// [SaveSameObject]\n"
                        "v8_private_save_same_object.Set"
                        "(${v8_receiver}, ${info}.GetReturnValue().Get());")


def make_runtime_call_timer_scope(cg_context, overriding_name=None):
    assert isinstance(cg_context, CodeGenContext)
    assert _is_none_or_str(overriding_name)

    target = cg_context.member_like or cg_context.property_

    suffix = ""
    if cg_context.attribute_get:
        suffix = "_Getter"
    elif cg_context.attribute_set:
        suffix = "_Setter"
    elif cg_context.exposed_construct:
        suffix = "_ConstructorGetterCallback"

    counter = (target and
               target.extended_attributes.value_of("RuntimeCallStatsCounter"))
    if counter:
        macro_name = "RUNTIME_CALL_TIMER_SCOPE"
        counter_name = "RuntimeCallStats::CounterId::k{}{}".format(
            counter, suffix)
    else:
        macro_name = "RUNTIME_CALL_TIMER_SCOPE_DISABLED_BY_DEFAULT"
        counter_name = "\"Blink_{}_{}{}\"".format(
            blink_class_name(cg_context.class_like), overriding_name
            or target.identifier, suffix)

    return TextNode(
        _format(
            "{macro_name}(${info}.GetIsolate(), {counter_name});",
            macro_name=macro_name,
            counter_name=counter_name))


def make_steps_of_ce_reactions(cg_context):
    assert isinstance(cg_context, CodeGenContext)
    assert (cg_context.attribute_set or cg_context.operation
            or cg_context.indexed_property_setter
            or cg_context.named_property_setter
            or cg_context.named_property_deleter)

    if "CEReactions" not in cg_context.member_like.extended_attributes:
        return None

    nodes = [
        TextNode("// [CEReactions]"),
        TextNode("CEReactionsScope ce_reactions_scope;"),
    ]

    nodes[-1].accumulate(
        CodeGenAccumulator.require_include_headers([
            "third_party/blink/renderer/core/html/custom/ce_reactions_scope.h"
        ]))

    # CEReactions scope is not tolerant of V8 exception, so it's necessary to
    # invoke custom element reactions before throwing an exception.  Thus, put
    # an ExceptionState before CEReactions scope.
    nodes.insert(0, WeakDependencyNode(dep_syms=["exception_state"]))

    return SequenceNode(nodes)


def make_steps_of_put_forwards(cg_context):
    assert isinstance(cg_context, CodeGenContext)

    T = TextNode

    return SequenceNode([
        T("// [PutForwards]"),
        T("v8::Local<v8::Value> target;"),
        T("if (!${v8_receiver}->Get(${current_context}, "
          "V8AtomicString(${isolate}, ${property_name}))"
          ".ToLocal(&target)) {\n"
          "  return;\n"
          "}"),
        CxxUnlikelyIfNode(
            cond="!target->IsObject()",
            body=[
                T("${exception_state}.ThrowTypeError("
                  "\"The attribute value is not an object\");"),
                T("return;"),
            ]),
        T("bool did_set;"),
        T("if (!target.As<v8::Object>()->Set(${current_context}, "
          "V8AtomicString(${isolate}, "
          "\"${attribute.extended_attributes.value_of(\"PutForwards\")}\""
          "), ${v8_property_value}).To(&did_set)) {{\n"
          "  return;\n"
          "}}"),
    ])


def make_steps_of_replaceable(cg_context):
    assert isinstance(cg_context, CodeGenContext)

    T = TextNode

    return SequenceNode([
        T("// [Replaceable]"),
        T("bool did_create;"),
        T("if (!${v8_receiver}->CreateDataProperty(${current_context}, "
          "V8AtomicString(${isolate}, ${property_name}), "
          "${v8_property_value}).To(&did_create)) {\n"
          "  return;\n"
          "}"),
    ])


def make_v8_set_return_value(cg_context):
    assert isinstance(cg_context, CodeGenContext)

    T = TextNode
    F = lambda *args, **kwargs: T(_format(*args, **kwargs))

    if cg_context.does_override_idl_return_type:
        return T("bindings::V8SetReturnValue(${info}, ${return_value});")

    if not cg_context.return_type or cg_context.return_type.unwrap().is_void:
        # Request a SymbolNode |return_value| to define itself without
        # rendering any text.
        return T("<% return_value.request_symbol_definition() %>")

    operation = cg_context.operation
    if operation and (operation.is_setter or operation.is_deleter):
        # Blink implementation returns in a type different from the IDL type.
        # Namely, IndexedPropertySetterResult, NamedPropertySetterResult, and
        # NamedPropertyDeleterResult are returned ignoring the operation's
        # return type.
        return T("bindings::V8SetReturnValue(${info}, ${return_value});")

    return_type = cg_context.return_type
    if return_type.is_typedef:
        if return_type.identifier in ("EventHandler",
                                      "OnBeforeUnloadEventHandler",
                                      "OnErrorEventHandler"):
            return T("bindings::V8SetReturnValue(${info}, ${return_value}, "
                     "${isolate}, ${blink_receiver});")

    # [CheckSecurity=ReturnValue]
    #
    # The returned object must be wrapped in its own realm instead of the
    # receiver object's relevant realm or the current realm.
    #
    # [CheckSecurity=ReturnValue] is used only for 'contentDocument' attribute
    # and 'getSVGDocument' operation of HTML{IFrame,Frame,Object,Embed}Element
    # interfaces, and Window.frameElement attribute, so far.
    #
    # All the interfaces above except for Window support 'contentWindow'
    # attribute and that's the global object of the creation context of the
    # returned V8 wrapper.  Window.frameElement is implemented with [Custom]
    # for now and there is no need to support it.
    #
    # Note that the global object has its own context and there is no need to
    # pass the creation context to ToV8.
    if (cg_context.member_like.extended_attributes.value_of("CheckSecurity") ==
            "ReturnValue"):
        return T("""\
// [CheckSecurity=ReturnValue]
bindings::V8SetReturnValue(
    ${info},
    ToV8(${return_value},
         ToV8(${blink_receiver}->contentWindow(),
              v8::Local<v8::Object>(),
              ${isolate}).As<v8::Object>(),
         ${isolate}));\
""")

    return_type = return_type.unwrap(typedef=True)
    return_type_body = return_type.unwrap()

    PRIMITIVE_TYPE_TO_CXX_TYPE = {
        "boolean": "bool",
        "byte": "int8_t",
        "octet": "uint8_t",
        "short": "int16_t",
        "unsigned short": "uint16_t",
        "long": "int32_t",
        "unsigned long": "uint32_t",
        "long long": "int64_t",
        "unsigned long long": "uint64_t",
        "float": "float",
        "unrestricted float": "float",
        "double": "double",
        "unrestricted double": "double",
    }
    cxx_type = PRIMITIVE_TYPE_TO_CXX_TYPE.get(
        return_type_body.keyword_typename)
    if cxx_type:
        return F(
            "bindings::V8SetReturnValue(${info}, ${return_value}, "
            "bindings::V8ReturnValue::PrimitiveType<{cxx_type}>());",
            cxx_type=cxx_type)

    # TODO(yukishiino): Remove |return_type_body.is_enumeration| below once
    # the migration from String to V8Enum type is done.
    if return_type_body.is_string or return_type_body.is_enumeration:
        args = ["${info}", "${return_value}", "${isolate}"]
        if return_type.is_nullable:
            args.append("bindings::V8ReturnValue::kNullable")
        else:
            args.append("bindings::V8ReturnValue::kNonNullable")
        return T("bindings::V8SetReturnValue({});".format(", ".join(args)))

    if return_type_body.is_interface:
        args = ["${info}", "${return_value}"]
        if cg_context.for_world == cg_context.MAIN_WORLD:
            args.append("bindings::V8ReturnValue::kMainWorld")
        elif cg_context.constructor or cg_context.member_like.is_static:
            args.append("${creation_context}")
        else:
            args.append("${blink_receiver}")
        return T("bindings::V8SetReturnValue({});".format(", ".join(args)))

    if return_type.is_frozen_array:
        return T(
            "bindings::V8SetReturnValue("
            "${info}, "
            "ToV8(${return_value}, ${creation_context_object}, ${isolate}), "
            "bindings::V8ReturnValue::kFrozen);")

    if return_type.is_promise:
        return T("bindings::V8SetReturnValue"
                 "(${info}, ${return_value}.V8Value());")

    return T("bindings::V8SetReturnValue(${info}, "
             "ToV8(${return_value}, ${creation_context_object}, ${isolate}));")


def _make_empty_callback_def(cg_context, function_name):
    assert isinstance(cg_context, CodeGenContext)
    assert isinstance(function_name, str)

    if cg_context.v8_callback_type == CodeGenContext.V8_FUNCTION_CALLBACK:
        arg_decls = ["const v8::FunctionCallbackInfo<v8::Value>& info"]
        arg_names = ["info"]
    elif (cg_context.v8_callback_type == CodeGenContext.
          V8_ACCESSOR_NAME_GETTER_CALLBACK):
        arg_decls = [
            "v8::Local<v8::Name> v8_property_name",
            "const v8::PropertyCallbackInfo<v8::Value>& info",
        ]
        arg_names = ["v8_property_name", "info"]
    elif (cg_context.v8_callback_type == CodeGenContext.
          V8_ACCESSOR_NAME_SETTER_CALLBACK):
        arg_decls = [
            "v8::Local<v8::Name> v8_property_name",
            "v8::Local<v8::Value> v8_property_value",
            "const v8::PropertyCallbackInfo<void>& info",
        ]
        arg_names = ["v8_property_name", "v8_property_value", "info"]
    elif (cg_context.v8_callback_type == CodeGenContext.
          V8_GENERIC_NAMED_PROPERTY_SETTER_CALLBACK):
        arg_decls = [
            "v8::Local<v8::Name> v8_property_name",
            "v8::Local<v8::Value> v8_property_value",
            "const v8::PropertyCallbackInfo<v8::Value>& info",
        ]
        arg_names = ["v8_property_name", "v8_property_value", "info"]

    func_def = CxxFuncDefNode(
        name=function_name, arg_decls=arg_decls, return_type="void")
    func_def.set_base_template_vars(cg_context.template_bindings())
    body = func_def.body

    for arg_name in arg_names:
        body.add_template_var(arg_name, arg_name)

    bind_callback_local_vars(body, cg_context)
    if cg_context.attribute or cg_context.function_like:
        bind_blink_api_arguments(body, cg_context)
        bind_return_value(body, cg_context)

    return func_def


def make_attribute_get_callback_def(cg_context, function_name):
    assert isinstance(cg_context, CodeGenContext)
    assert isinstance(function_name, str)

    func_def = _make_empty_callback_def(cg_context, function_name)
    body = func_def.body

    body.extend([
        make_check_receiver(cg_context),
        EmptyNode(),
        make_runtime_call_timer_scope(cg_context),
        make_bindings_trace_event(cg_context),
        make_report_coop_access(cg_context),
        make_report_deprecate_as(cg_context),
        make_report_measure_as(cg_context),
        make_log_activity(cg_context),
        EmptyNode(),
    ])

    if "Getter" in cg_context.property_.extended_attributes.values_of(
            "Custom"):
        text = _format("${class_name}::{}(${info});",
                       custom_function_name(cg_context))
        body.append(TextNode(text))
        return func_def

    body.extend([
        make_return_value_cache_return_early(cg_context),
        EmptyNode(),
        make_check_security_of_return_value(cg_context),
        make_v8_set_return_value(cg_context),
        make_report_high_entropy(cg_context),
        make_return_value_cache_update_value(cg_context),
    ])

    return func_def


def make_attribute_set_callback_def(cg_context, function_name):
    assert isinstance(cg_context, CodeGenContext)
    assert isinstance(function_name, str)

    ext_attrs = cg_context.attribute.extended_attributes
    if cg_context.attribute.is_readonly and not any(
            ext_attr in ext_attrs
            for ext_attr in ("LegacyLenientSetter", "PutForwards",
                             "Replaceable")):
        return None

    func_def = _make_empty_callback_def(cg_context, function_name)
    body = func_def.body

    if "LegacyLenientSetter" in ext_attrs:
        body.append(TextNode("// [LegacyLenientSetter]"))
        return func_def

    body.extend([
        make_check_receiver(cg_context),
        EmptyNode(),
        make_runtime_call_timer_scope(cg_context),
        make_bindings_trace_event(cg_context),
        make_report_deprecate_as(cg_context),
        make_report_measure_as(cg_context),
        make_log_activity(cg_context),
        EmptyNode(),
    ])

    if "Setter" in cg_context.property_.extended_attributes.values_of(
            "Custom"):
        text = _format("${class_name}::{}(${v8_property_value}, ${info});",
                       custom_function_name(cg_context))
        body.append(TextNode(text))
        return func_def

    # Binary size reduction hack
    # 1. Drop the check of argument length although this is a violation of
    #   Web IDL.
    # 2. Leverage the nature of [LegacyTreatNonObjectAsNull] (ES to IDL
    #   conversion never fails).
    if (cg_context.attribute.idl_type.is_typedef
            and (cg_context.attribute.idl_type.identifier in (
                "EventHandler", "OnBeforeUnloadEventHandler",
                "OnErrorEventHandler"))):
        body.extend([
            TextNode("""\
EventListener* event_handler = JSEventHandler::CreateOrNull(
    ${v8_property_value},
    JSEventHandler::HandlerType::k${attribute.idl_type.identifier});\
"""),
        ])
        code_generator_info = cg_context.attribute.code_generator_info
        func_name = name_style.api_func("set", cg_context.attribute.identifier)
        if code_generator_info.defined_in_partial:
            class_name = (code_generator_info.receiver_implemented_as
                          or name_style.class_(
                              cg_context.attribute.owner_mixin.identifier))
            text = _format(
                "{class_name}::{func_name}"
                "(*${blink_receiver}, event_handler);",
                class_name=class_name,
                func_name=func_name)
        else:
            text = _format("${blink_receiver}->{func_name}(event_handler);",
                           func_name=func_name)
        body.append(TextNode(text))
        return func_def

    # Binary size reduction hack
    # When the following conditions are met, the implementation is shared.
    # 1. The attribute is annotated with [CEReactions, Reflect] and not
    #   annotated with other extended attributes having side effect.
    # 2. The interface is implementing Element.
    def optimize_element_cereactions_reflect():
        has_cereactions = False
        has_reflect = False
        for key in ext_attrs.keys():
            if key == "CEReactions":
                has_cereactions = True
            elif key == "Reflect":
                has_reflect = True
            elif key in ("Affects", "DeprecateAs", "Exposed", "LogActivity",
                         "LogAllWorlds", "Measure", "MeasureAs",
                         "ReflectEmpty", "ReflectInvalid", "ReflectMissing",
                         "ReflectOnly", "RuntimeCallStatsCounter",
                         "RuntimeEnabled", "SecureContext", "URL",
                         "Unscopable"):
                pass
            else:
                return None
        if not (has_cereactions and has_reflect):
            return None
        if not cg_context.interface.does_implement("Element"):
            return None
        content_attribute = _make_reflect_content_attribute_key(
            body, cg_context)
        idl_type = cg_context.attribute.idl_type.unwrap(typedef=True)
        if idl_type.is_boolean:
            func_name = "PerformAttributeSetCEReactionsReflectTypeBoolean"
        elif idl_type.type_name == "String":
            func_name = "PerformAttributeSetCEReactionsReflectTypeString"
        elif idl_type.type_name == "StringTreatNullAs":
            func_name = ("PerformAttributeSetCEReactionsReflect"
                         "TypeStringLegacyNullToEmptyString")
        elif idl_type.type_name == "StringOrNull":
            func_name = "PerformAttributeSetCEReactionsReflectTypeStringOrNull"
        else:
            return None
        text = _format(
            "bindings::{func_name}"
            "(${info}, {content_attribute}, "
            "${class_like_name}, ${property_name});",
            func_name=func_name,
            content_attribute=content_attribute)
        return TextNode(text)

    node = optimize_element_cereactions_reflect()
    if node:
        body.append(node)
        return func_def

    body.extend([
        make_check_argument_length(cg_context),
        EmptyNode(),
    ])

    if "PutForwards" in ext_attrs:
        body.append(make_steps_of_put_forwards(cg_context))
        return func_def

    if "Replaceable" in ext_attrs:
        body.append(make_steps_of_replaceable(cg_context))
        return func_def

    body.extend([
        make_steps_of_ce_reactions(cg_context),
        EmptyNode(),
        make_v8_set_return_value(cg_context),
    ])

    return func_def


def make_constant_callback_def(cg_context, function_name):
    assert isinstance(cg_context, CodeGenContext)
    assert isinstance(function_name, str)

    logging_nodes = SequenceNode([
        make_report_deprecate_as(cg_context),
        make_report_measure_as(cg_context),
        make_log_activity(cg_context),
    ])
    if not logging_nodes:
        return None

    func_def = _make_empty_callback_def(cg_context, function_name)
    body = func_def.body

    v8_set_return_value = _format(
        "bindings::V8SetReturnValue(${info}, ${class_name}::Constant::{});",
        constant_name(cg_context))
    body.extend([
        make_runtime_call_timer_scope(cg_context),
        make_bindings_trace_event(cg_context),
        logging_nodes,
        EmptyNode(),
        TextNode(v8_set_return_value),
        make_report_high_entropy(cg_context),
    ])

    return func_def


def make_constant_constant_def(cg_context, constant_name):
    # IDL constant's C++ constant definition
    assert isinstance(cg_context, CodeGenContext)
    assert isinstance(constant_name, str)

    constant_type = blink_type_info(cg_context.constant.idl_type).value_t
    return TextNode("static constexpr {type} {name} = {value};".format(
        type=constant_type,
        name=constant_name,
        value=cg_context.constant.value.literal))


def make_overload_dispatcher_function_def(cg_context, function_name):
    assert isinstance(cg_context, CodeGenContext)
    assert isinstance(function_name, str)

    func_def = _make_empty_callback_def(cg_context, function_name)
    body = func_def.body

    if cg_context.operation_group:
        body.append(make_operation_entry(cg_context))
        body.append(EmptyNode())
        body.append(make_cooperative_scheduling_safepoint(cg_context))
        body.append(EmptyNode())

    if cg_context.constructor_group:
        body.append(make_constructor_entry(cg_context))
        body.append(EmptyNode())

    body.append(make_overload_dispatcher(cg_context))

    return func_def


def make_constructor_entry(cg_context):
    assert isinstance(cg_context, CodeGenContext)

    return SequenceNode([
        make_runtime_call_timer_scope(cg_context),
        make_bindings_trace_event(cg_context),
        EmptyNode(),
        make_check_constructor_call(cg_context),
    ])


def make_constructor_function_def(cg_context, function_name):
    assert isinstance(cg_context, CodeGenContext)
    assert isinstance(function_name, str)

    T = TextNode

    func_def = _make_empty_callback_def(cg_context, function_name)
    body = func_def.body

    if len(cg_context.constructor_group) == 1:
        body.append(make_constructor_entry(cg_context))
        body.append(EmptyNode())

    body.extend([
        make_report_deprecate_as(cg_context),
        make_report_measure_as(cg_context),
        make_log_activity(cg_context),
        EmptyNode(),
        make_check_argument_length(cg_context),
        EmptyNode(),
    ])

    if "HTMLConstructor" in cg_context.constructor.extended_attributes:
        body.append(T("// [HTMLConstructor]"))
        text = _format(
            "V8HTMLConstructor::HtmlConstructor("
            "${info}, *${class_name}::GetWrapperTypeInfo(), "
            "HTMLElementType::{});",
            name_style.constant(cg_context.class_like.identifier))
        body.append(T(text))
        body.accumulate(
            CodeGenAccumulator.require_include_headers([
                "third_party/blink/renderer/bindings/core/v8/v8_html_constructor.h"
            ]))
    else:
        body.append(
            T("v8::Local<v8::Object> v8_wrapper = "
              "${return_value}->AssociateWithWrapper(${isolate}, "
              "${class_name}::GetWrapperTypeInfo(), ${v8_receiver});"))
        body.append(T("bindings::V8SetReturnValue(${info}, v8_wrapper);"))

    return func_def


def make_constructor_callback_def(cg_context, function_name):
    assert isinstance(cg_context, CodeGenContext)
    assert isinstance(function_name, str)

    constructor_group = cg_context.constructor_group

    if len(constructor_group) == 1:
        return make_constructor_function_def(
            cg_context.make_copy(constructor=constructor_group[0]),
            function_name)

    node = SequenceNode()
    for constructor in constructor_group:
        cgc = cg_context.make_copy(constructor=constructor)
        node.extend([
            make_constructor_function_def(
                cgc, callback_function_name(cgc, constructor.overload_index)),
            EmptyNode(),
        ])
    node.append(
        make_overload_dispatcher_function_def(cg_context, function_name))
    return node


def make_exposed_construct_callback_def(cg_context, function_name):
    assert isinstance(cg_context, CodeGenContext)
    assert isinstance(function_name, str)

    func_def = _make_empty_callback_def(cg_context, function_name)
    body = func_def.body

    if (cg_context.exposed_construct.is_interface
            or cg_context.exposed_construct.is_callback_interface):
        tag = "bindings::V8ReturnValue::kInterfaceObject"
    elif cg_context.exposed_construct.is_namespace:
        tag = "bindings::V8ReturnValue::kNamespaceObject"
    else:
        assert False
    v8_set_return_value = _format(
        "bindings::V8SetReturnValue"
        "(${info}, {bridge}::GetWrapperTypeInfo(), {tag});",
        bridge=v8_bridge_class_name(cg_context.exposed_construct),
        tag=tag)
    body.extend([
        make_runtime_call_timer_scope(cg_context),
        make_bindings_trace_event(cg_context),
        make_report_deprecate_as(cg_context),
        make_report_measure_as(cg_context),
        make_log_activity(cg_context),
        EmptyNode(),
        TextNode(v8_set_return_value),
    ])

    return func_def


def make_named_constructor_property_callback_def(cg_context, function_name):
    assert isinstance(cg_context, CodeGenContext)
    assert isinstance(function_name, str)

    func_def = _make_empty_callback_def(cg_context, function_name)
    body = func_def.body

    body.extend([
        make_runtime_call_timer_scope(cg_context),
        make_bindings_trace_event(cg_context),
        make_report_deprecate_as(cg_context),
        make_report_measure_as(cg_context),
        make_log_activity(cg_context),
        EmptyNode(),
    ])

    constructor_group = cg_context.exposed_construct
    assert isinstance(constructor_group, web_idl.ConstructorGroup)
    assert isinstance(constructor_group.owner, web_idl.Interface)
    named_ctor_v8_bridge = v8_bridge_class_name(constructor_group.owner)
    cgc = CodeGenContext(
        interface=constructor_group.owner,
        constructor_group=constructor_group,
        is_named_constructor=True,
        class_name=named_ctor_v8_bridge)
    named_ctor_name = callback_function_name(cgc)
    named_ctor_def = make_constructor_callback_def(cgc, named_ctor_name)

    return_value_cache_return_early = """\
static const V8PrivateProperty::SymbolKey kPrivatePropertyNamedConstructor;
auto&& v8_private_named_constructor =
    V8PrivateProperty::GetSymbol(${isolate}, kPrivatePropertyNamedConstructor);
v8::Local<v8::Value> v8_named_constructor;
if (!v8_private_named_constructor.GetOrUndefined(${v8_receiver})
         .ToLocal(&v8_named_constructor)) {
  return;
}
if (!v8_named_constructor->IsUndefined()) {
  bindings::V8SetReturnValue(${info}, v8_named_constructor);
  return;
}
"""

    pattern = """\
v8::Local<v8::Value> v8_value;
if (!bindings::CreateNamedConstructorFunction(
         ${script_state},
         {callback},
         "{func_name}",
         {func_length},
         {v8_bridge}::GetWrapperTypeInfo())
     .ToLocal(&v8_value)) {
  return;
}
bindings::V8SetReturnValue(${info}, v8_value);
"""
    create_named_constructor_function = _format(
        pattern,
        callback=named_ctor_name,
        func_name=constructor_group.identifier,
        func_length=constructor_group.min_num_of_required_arguments,
        v8_bridge=named_ctor_v8_bridge)

    return_value_cache_update_value = """\
v8_private_named_constructor.Set(${v8_receiver}, v8_value);
"""

    body.extend([
        TextNode(return_value_cache_return_early),
        TextNode(create_named_constructor_function),
        TextNode(return_value_cache_update_value),
    ])

    return SequenceNode([named_ctor_def, EmptyNode(), func_def])


def make_no_alloc_direct_call_callback_def(cg_context, function_name):
    assert isinstance(cg_context, CodeGenContext)
    assert isinstance(function_name, str)

    assert cg_context.operation_group and len(cg_context.operation_group) == 1

    func_like = cg_context.operation_group[0]

    return_type = ("void" if func_like.return_type.is_void else
                   blink_type_info(func_like.return_type).value_t)
    arg_type_and_names = [(blink_type_info(arg.idl_type).value_t,
                           name_style.arg_f("arg{}_{}", index + 1,
                                            arg.identifier))
                          for index, arg in enumerate(func_like.arguments)]
    arg_decls = ["v8::ApiObject arg0_receiver"] + [
        "{} {}".format(arg_type, arg_name)
        for arg_type, arg_name in arg_type_and_names
    ]
    arg_decls.append("v8::FastApiCallbackOptions& arg_callback_options")
    func_def = CxxFuncDefNode(name=function_name,
                              arg_decls=arg_decls,
                              return_type=return_type)
    body = func_def.body

    pattern = """\
ThreadState::NoAllocationScope no_alloc_scope(ThreadState::Current());
v8::Object* v8_receiver = reinterpret_cast<v8::Object*>(&arg0_receiver);
v8::Isolate* isolate = v8_receiver->GetIsolate();
v8::Isolate::DisallowJavascriptExecutionScope no_js_exec_scope(
    isolate,
    v8::Isolate::DisallowJavascriptExecutionScope::CRASH_ON_FAILURE);
{blink_class}* blink_receiver =
    ToScriptWrappable(v8_receiver)->ToImpl<{blink_class}>();
return blink_receiver->{member_func}({blink_arguments}, arg_callback_options);\
"""
    blink_class = blink_class_name(cg_context.interface)
    member_func = backward_compatible_api_func(cg_context)
    blink_arguments = ", ".join(
        [arg_name for arg_type, arg_name in arg_type_and_names])
    body.append(
        TextNode(
            _format(pattern,
                    blink_class=blink_class,
                    member_func=member_func,
                    blink_arguments=blink_arguments)))

    return func_def


def make_operation_entry(cg_context):
    assert isinstance(cg_context, CodeGenContext)

    return SequenceNode([
        make_runtime_call_timer_scope(cg_context),
        make_bindings_trace_event(cg_context),
    ])


def make_operation_function_def(cg_context, function_name):
    assert isinstance(cg_context, CodeGenContext)
    assert isinstance(function_name, str)

    func_def = _make_empty_callback_def(cg_context, function_name)
    body = func_def.body

    if not cg_context.operation_group or len(cg_context.operation_group) == 1:
        body.append(make_operation_entry(cg_context))
        body.append(EmptyNode())

    body.extend([
        make_check_receiver(cg_context),
        EmptyNode(),
        make_report_coop_access(cg_context),
        make_report_deprecate_as(cg_context),
        make_report_measure_as(cg_context),
        make_log_activity(cg_context),
        EmptyNode(),
    ])

    if "Custom" in cg_context.property_.extended_attributes:
        text = _format("${class_name}::{}(${info});",
                       custom_function_name(cg_context))
        body.append(TextNode(text))
        return func_def

    body.extend([
        make_check_argument_length(cg_context),
        EmptyNode(),
        make_steps_of_ce_reactions(cg_context),
        EmptyNode(),
        make_check_security_of_return_value(cg_context),
        make_v8_set_return_value(cg_context),
        make_report_high_entropy(cg_context),
    ])

    return func_def


def make_operation_callback_def(cg_context,
                                function_name,
                                no_alloc_direct_callback_name=None):
    assert isinstance(cg_context, CodeGenContext)
    assert isinstance(function_name, str)

    operation_group = cg_context.operation_group

    assert (not ("Custom" in operation_group.extended_attributes)
            or len(operation_group) == 1)
    assert (not ("NoAllocDirectCall" in operation_group.extended_attributes)
            or len(operation_group) == 1)

    if "NoAllocDirectCall" in operation_group.extended_attributes:
        return ListNode([
            make_operation_function_def(
                cg_context.make_copy(operation=operation_group[0]),
                function_name),
            EmptyNode(),
            make_no_alloc_direct_call_callback_def(
                cg_context.make_copy(operation=operation_group[0]),
                no_alloc_direct_callback_name),
        ])

    if len(operation_group) == 1:
        return make_operation_function_def(
            cg_context.make_copy(operation=operation_group[0]), function_name)

    node = SequenceNode()
    for operation in operation_group:
        cgc = cg_context.make_copy(operation=operation)
        node.extend([
            make_operation_function_def(
                cgc, callback_function_name(cgc, operation.overload_index)),
            EmptyNode(),
        ])
    node.append(
        make_overload_dispatcher_function_def(cg_context, function_name))
    return node


def make_stringifier_callback_def(cg_context, function_name):
    assert isinstance(cg_context, CodeGenContext)
    assert isinstance(function_name, str)

    if cg_context.stringifier.attribute:
        return make_attribute_get_callback_def(
            cg_context.make_copy(
                attribute=cg_context.stringifier.attribute,
                attribute_get=True), function_name)
    elif cg_context.stringifier.operation:
        return make_operation_function_def(
            cg_context.make_copy(operation=cg_context.stringifier.operation),
            function_name)
    assert False


# ----------------------------------------------------------------------------
# Callback functions of indexed and named interceptors
# ----------------------------------------------------------------------------


def _make_interceptor_callback(cg_context, function_name, arg_decls, arg_names,
                               class_name, runtime_call_timer_name):
    assert isinstance(cg_context, CodeGenContext)
    assert isinstance(function_name, str)
    assert isinstance(arg_decls, (list, tuple))
    assert all(isinstance(arg_decl, str) for arg_decl in arg_decls)
    assert isinstance(arg_names, (list, tuple))
    assert all(isinstance(arg_name, str) for arg_name in arg_names)
    assert _is_none_or_str(class_name)
    assert isinstance(runtime_call_timer_name, str)

    func_decl = CxxFuncDeclNode(
        name=function_name,
        arg_decls=arg_decls,
        return_type="void",
        static=True)

    func_def = _make_interceptor_callback_def(cg_context, function_name,
                                              arg_decls, arg_names, class_name,
                                              runtime_call_timer_name)

    return func_decl, func_def


def _make_interceptor_callback_def(cg_context, function_name, arg_decls,
                                   arg_names, class_name,
                                   runtime_call_timer_name):
    assert isinstance(cg_context, CodeGenContext)
    assert isinstance(function_name, str)
    assert isinstance(arg_decls, (list, tuple))
    assert all(isinstance(arg_decl, str) for arg_decl in arg_decls)
    assert isinstance(arg_names, (list, tuple))
    assert all(isinstance(arg_name, str) for arg_name in arg_names)
    assert _is_none_or_str(class_name)
    assert isinstance(runtime_call_timer_name, str)

    func_def = CxxFuncDefNode(
        name=function_name,
        arg_decls=arg_decls,
        return_type="void",
        class_name=class_name)
    func_def.set_base_template_vars(cg_context.template_bindings())
    body = func_def.body
    for arg_name in arg_names:
        body.add_template_var(arg_name, arg_name)
    bind_callback_local_vars(body, cg_context)

    body.extend([
        make_runtime_call_timer_scope(cg_context, runtime_call_timer_name),
        EmptyNode(),
    ])

    return func_def


def make_indexed_property_getter_callback(cg_context, function_name):
    assert isinstance(cg_context, CodeGenContext)
    assert isinstance(function_name, str)

    arg_decls = [
        "uint32_t index",
        "const v8::PropertyCallbackInfo<v8::Value>& info",
    ]
    arg_names = ["index", "info"]

    func_decl, func_def = _make_interceptor_callback(
        cg_context, function_name, arg_decls, arg_names, cg_context.class_name,
        "IndexedPropertyGetter")
    body = func_def.body

    if not cg_context.interface.indexed_and_named_properties.indexed_getter:
        body.append(
            TextNode("""\
v8::Local<v8::String> property_name =
    V8AtomicString(${isolate}, AtomicString::Number(${index}));
${class_name}::NamedPropertyGetterCallback(property_name, ${info});
"""))
        return func_decl, func_def

    bind_return_value(body, cg_context, overriding_args=["${index}"])

    body.extend([
        TextNode("""\
// LegacyPlatformObjectGetOwnProperty
// https://heycam.github.io/webidl/#LegacyPlatformObjectGetOwnProperty
// step 1.2. If index is a supported property index, then:
// step 3. Return OrdinaryGetOwnProperty(O, P).
if (${index} >= ${blink_receiver}->length())
  return;  // Do not intercept.  Fallback to OrdinaryGetOwnProperty.
"""),
        make_v8_set_return_value(cg_context),
    ])

    return func_decl, func_def


def make_indexed_property_setter_callback(cg_context, function_name):
    assert isinstance(cg_context, CodeGenContext)
    assert isinstance(function_name, str)

    arg_decls = [
        "uint32_t index",
        "v8::Local<v8::Value> v8_property_value",
        "const v8::PropertyCallbackInfo<v8::Value>& info",
    ]
    arg_names = ["index", "v8_property_value", "info"]

    func_decl, func_def = _make_interceptor_callback(
        cg_context, function_name, arg_decls, arg_names, cg_context.class_name,
        "IndexedPropertySetter")
    body = func_def.body

    if not cg_context.interface.indexed_and_named_properties.indexed_getter:
        body.append(
            TextNode("""\
v8::Local<v8::String> property_name =
    V8AtomicString(${isolate}, AtomicString::Number(${index}));
${class_name}::NamedPropertySetterCallback(
    property_name, ${v8_property_value}, ${info});
"""))
        return func_decl, func_def

    if not cg_context.indexed_property_setter:
        body.append(
            TextNode("""\
// 3.9.2. [[Set]]
// https://heycam.github.io/webidl/#legacy-platform-object-set
// OrdinarySetWithOwnDescriptor will end up calling DefineOwnProperty,
// which will fail when the receiver object is this legacy platform
// object.
bindings::V8SetReturnValue(${info}, nullptr);
if (${info}.ShouldThrowOnError()) {
  ExceptionState exception_state(${info}.GetIsolate(),
                                 ExceptionState::kIndexedSetterContext,
                                 "${interface.identifier}");
  exception_state.ThrowTypeError(
      "Indexed property setter is not supported.");
}
"""))
        return func_decl, func_def

    bind_return_value(
        body,
        cg_context,
        overriding_args=["${index}", "${blink_property_value}"])
    body.register_code_symbol(
        make_v8_to_blink_value(
            "blink_property_value",
            "${v8_property_value}",
            cg_context.indexed_property_setter.arguments[1].idl_type,
            argument=cg_context.indexed_property_setter.arguments[1]))

    body.extend([
        TextNode("""\
// 3.9.2. [[Set]]
// https://heycam.github.io/webidl/#legacy-platform-object-set
// step 1. If O and Receiver are the same object, then:\
"""),
        CxxLikelyIfNode(cond="${info}.Holder() == ${info}.This()",
                        body=[
                            TextNode("""\
// step 1.1.1. Invoke the indexed property setter with P and V.\
"""),
                            make_steps_of_ce_reactions(cg_context),
                            EmptyNode(),
                            make_v8_set_return_value(cg_context),
                            TextNode("""\
bindings::V8SetReturnValue(${info}, nullptr);
return;"""),
                        ]),
        EmptyNode(),
        TextNode("""\
// Do not intercept.  Fallback to OrdinarySetWithOwnDescriptor.
"""),
    ])

    return func_decl, func_def


def make_indexed_property_deleter_callback(cg_context, function_name):
    assert isinstance(cg_context, CodeGenContext)
    assert isinstance(function_name, str)

    arg_decls = [
        "uint32_t index",
        "const v8::PropertyCallbackInfo<v8::Boolean>& info",
    ]
    arg_names = ["index", "info"]

    func_decl, func_def = _make_interceptor_callback(
        cg_context, function_name, arg_decls, arg_names, cg_context.class_name,
        "IndexedPropertyDeleter")
    body = func_def.body

    if not cg_context.interface.indexed_and_named_properties.indexed_getter:
        body.append(
            TextNode("""\
v8::Local<v8::String> property_name =
    V8AtomicString(${isolate}, AtomicString::Number(${index}));
${class_name}::NamedPropertyDeleterCallback(property_name, ${info});
"""))
        return func_decl, func_def

    body.append(
        TextNode("""\
// 3.9.4. [[Delete]]
// https://heycam.github.io/webidl/#legacy-platform-object-delete
// step 1.2. If index is not a supported property index, then return true.
// step 1.3. Return false.
const bool is_supported = ${index} < ${blink_receiver}->length();
bindings::V8SetReturnValue(${info}, !is_supported);
if (is_supported and ${info}.ShouldThrowOnError()) {
  ExceptionState exception_state(${info}.GetIsolate(),
                                 ExceptionState::kIndexedDeletionContext,
                                 "${interface.identifier}");
  exception_state.ThrowTypeError("Index property deleter is not supported.");
}
"""))

    return func_decl, func_def


def make_indexed_property_definer_callback(cg_context, function_name):
    assert isinstance(cg_context, CodeGenContext)
    assert isinstance(function_name, str)

    arg_decls = [
        "uint32_t index",
        "const v8::PropertyDescriptor& v8_property_desc",
        "const v8::PropertyCallbackInfo<v8::Value>& info",
    ]
    arg_names = ["index", "v8_property_desc", "info"]

    func_decl, func_def = _make_interceptor_callback(
        cg_context, function_name, arg_decls, arg_names, cg_context.class_name,
        "IndexedPropertyDefiner")
    body = func_def.body

    if not cg_context.interface.indexed_and_named_properties.indexed_getter:
        body.append(
            TextNode("""\
v8::Local<v8::String> property_name =
    V8AtomicString(${isolate}, AtomicString::Number(${index}));
${class_name}::NamedPropertyDefinerCallback(
    property_name, ${v8_property_desc}, ${info});
"""))
        return func_decl, func_def

    body.append(
        TextNode("""\
// 3.9.3. [[DefineOwnProperty]]
// https://heycam.github.io/webidl/#legacy-platform-object-defineownproperty
// step 1.1. If the result of calling IsDataDescriptor(Desc) is false, then
//   return false.
if (v8_property_desc.has_get() || v8_property_desc.has_set()) {
  bindings::V8SetReturnValue(${info}, nullptr);
  if (${info}.ShouldThrowOnError()) {
    ExceptionState exception_state(${info}.GetIsolate(),
                                   ExceptionState::kIndexedSetterContext,
                                   "${interface.identifier}");
    exception_state.ThrowTypeError("Accessor properties are not allowed.");
  }
  return;
}
"""))

    if not cg_context.interface.indexed_and_named_properties.indexed_setter:
        body.append(
            TextNode("""\
// step 1.2. If O does not implement an interface with an indexed property
//   setter, then return false.
bindings::V8SetReturnValue(${info}, nullptr);
if (${info}.ShouldThrowOnError()) {
  ExceptionState exception_state(${info}.GetIsolate(),
                                 ExceptionState::kIndexedSetterContext,
                                 "${interface.identifier}");
  exception_state.ThrowTypeError("Index property setter is not supported.");
}
"""))
    else:
        body.append(
            TextNode("""\
// step 1.3. Invoke the indexed property setter with P and Desc.[[Value]].
${class_name}::IndexedPropertySetterCallback(
    ${index}, ${v8_property_desc}.value(), ${info});
"""))

    return func_decl, func_def


def make_indexed_property_descriptor_callback(cg_context, function_name):
    assert isinstance(cg_context, CodeGenContext)
    assert isinstance(function_name, str)

    arg_decls = [
        "uint32_t index",
        "const v8::PropertyCallbackInfo<v8::Value>& info",
    ]
    arg_names = ["index", "info"]

    func_decl, func_def = _make_interceptor_callback(
        cg_context, function_name, arg_decls, arg_names, cg_context.class_name,
        "IndexedPropertyDescriptor")
    body = func_def.body

    if not cg_context.interface.indexed_and_named_properties.indexed_getter:
        body.append(
            TextNode("""\
v8::Local<v8::String> property_name =
    V8AtomicString(${isolate}, AtomicString::Number(${index}));
${class_name}::NamedPropertyDescriptorCallback(property_name, ${info});
"""))
        return func_decl, func_def

    pattern = """\
// LegacyPlatformObjectGetOwnProperty
// https://heycam.github.io/webidl/#LegacyPlatformObjectGetOwnProperty
// step 1.2.3. If operation was defined without an identifier, then set
//   value to the result of performing the steps listed in the interface
//   description to determine the value of an indexed property with index
//   as the index.
// step 1.2.4. Otherwise, operation was defined with an identifier. Set
//   value to the result of performing the steps listed in the description
//   of operation with index as the only argument value.
${class_name}::IndexedPropertyGetterCallback(${index}, ${info});
v8::Local<v8::Value> v8_value = ${info}.GetReturnValue().Get();
// step 1.2. If index is a supported property index, then:
// step 3. Return OrdinaryGetOwnProperty(O, P).
if (v8_value->IsUndefined())
  return;  // Do not intercept.  Fallback to OrdinaryGetOwnProperty.

// step 1.2.6. Set desc.[[Value]] to the result of converting value to an
//   ECMAScript value.
// step 1.2.7. If O implements an interface with an indexed property setter,
//   then set desc.[[Writable]] to true, otherwise set it to false.
// step 1.2.8. Set desc.[[Enumerable]] and desc.[[Configurable]] to true.
v8::PropertyDescriptor desc(v8_value, /*writable=*/{cxx_writable});
desc.set_enumerable(true);
desc.set_configurable(true);
bindings::V8SetReturnValue(${info}, desc);"""
    writable = bool(
        cg_context.interface.indexed_and_named_properties.indexed_setter)
    cxx_writable = "true" if writable else "false"
    body.append(TextNode(_format(pattern, cxx_writable=cxx_writable)))

    return func_decl, func_def


def make_indexed_property_enumerator_callback(cg_context, function_name):
    assert isinstance(cg_context, CodeGenContext)
    assert isinstance(function_name, str)

    if not cg_context.interface.indexed_and_named_properties.indexed_getter:
        return None, None

    arg_decls = ["const v8::PropertyCallbackInfo<v8::Array>& info"]
    arg_names = ["info"]

    func_decl, func_def = _make_interceptor_callback(
        cg_context, function_name, arg_decls, arg_names, cg_context.class_name,
        "IndexedPropertyEnumerator")
    body = func_def.body

    body.append(
        TextNode("""\
// 3.9.6. [[OwnPropertyKeys]]
// https://heycam.github.io/webidl/#legacy-platform-object-ownpropertykeys
// step 2. If O supports indexed properties, then for each index of O's
//   supported property indices, in ascending numerical order, append
//   ! ToString(index) to keys.
uint32_t length = ${blink_receiver}->length();
v8::Local<v8::Array> array =
    bindings::EnumerateIndexedProperties(${isolate}, length);
bindings::V8SetReturnValue(${info}, array);
"""))
    body.accumulate(
        CodeGenAccumulator.require_include_headers([
            "third_party/blink/renderer/bindings/core/v8/generated_code_helper.h"
        ]))

    return func_decl, func_def


def make_named_property_getter_callback(cg_context, function_name):
    assert isinstance(cg_context, CodeGenContext)
    assert isinstance(function_name, str)

    arg_decls = [
        "v8::Local<v8::Name> v8_property_name",
        "const v8::PropertyCallbackInfo<v8::Value>& info",
    ]
    arg_names = ["v8_property_name", "info"]

    func_decl, func_def = _make_interceptor_callback(
        cg_context, function_name, arg_decls, arg_names, cg_context.class_name,
        "NamedPropertyGetter")
    body = func_def.body

    bind_return_value(
        body, cg_context, overriding_args=["${blink_property_name}"])

    if "Custom" in cg_context.named_property_getter.extended_attributes:
        text = _format("${class_name}::{}(${blink_property_name}, ${info});",
                       custom_function_name(cg_context))
        body.append(TextNode(text))
        return func_decl, func_def

    # The named property getter's implementation of Blink is not designed to
    # represent the property existence, and we have to determine the property
    # existence by heuristics.
    type = cg_context.return_type.unwrap()
    if type.is_any or type.is_object:
        not_found_expr = "${return_value}.IsEmpty()"
    elif type.is_string:
        not_found_expr = "${return_value}.IsNull()"
    elif type.is_interface:
        not_found_expr = "!${return_value}"
    elif type.is_union:
        not_found_expr = "${return_value}.IsNull()"
    else:
        assert False

    body.extend([
        TextNode("""\
// LegacyPlatformObjectGetOwnProperty
// https://heycam.github.io/webidl/#LegacyPlatformObjectGetOwnProperty
// step 2.1. If the result of running the named property visibility
//   algorithm with property name P and object O is true, then:\
"""),
        CxxUnlikelyIfNode(
            cond=not_found_expr,
            body=[
                TextNode("// step 3. Return OrdinaryGetOwnProperty(O, P)."),
                TextNode("return;  // Do not intercept."),
            ]),
        TextNode("""\
// step 2.1.3. If operation was defined without an identifier, then set
//   value to the result of performing the steps listed in the interface
//   description to determine the value of a named property with P as the
//   name.
// step 2.1.4. Otherwise, operation was defined with an identifier. Set
//   value to the result of performing the steps listed in the description
//   of operation with P as the only argument value.\
"""),
        make_v8_set_return_value(cg_context),
    ])

    return func_decl, func_def


def make_named_property_setter_callback(cg_context, function_name):
    assert isinstance(cg_context, CodeGenContext)
    assert isinstance(function_name, str)

    arg_decls = [
        "v8::Local<v8::Name> v8_property_name",
        "v8::Local<v8::Value> v8_property_value",
        "const v8::PropertyCallbackInfo<v8::Value>& info",
    ]
    arg_names = ["v8_property_name", "v8_property_value", "info"]

    func_decl, func_def = _make_interceptor_callback(
        cg_context, function_name, arg_decls, arg_names, cg_context.class_name,
        "NamedPropertySetter")
    body = func_def.body

    if not cg_context.named_property_setter:
        body.append(
            TextNode("""\
// 3.9.2. [[Set]]
// https://heycam.github.io/webidl/#legacy-platform-object-set
// step 3. Perform ? OrdinarySetWithOwnDescriptor(O, P, V, Receiver, ownDesc).\
"""))
        if ("LegacyOverrideBuiltIns" in
                cg_context.interface.extended_attributes):
            body.append(
                TextNode("""\
// [LegacyOverrideBuiltIns]
if (${info}.Holder()->GetRealNamedPropertyAttributesInPrototypeChain(
        ${current_context}, ${v8_property_name}).IsJust()) {
  return;  // Fallback to the existing property.
}
"""))
        body.append(
            TextNode("""\
${class_name}::NamedPropertyGetterCallback(${v8_property_name}, ${info});
const bool is_creating = ${info}.GetReturnValue().Get()->IsUndefined();
if (!is_creating) {
  bindings::V8SetReturnValue(${info}, nullptr);
  if (${info}.ShouldThrowOnError()) {
    ExceptionState exception_state(${info}.GetIsolate(),
                                   ExceptionState::kNamedSetterContext,
                                   "${interface.identifier}");
    exception_state.ThrowTypeError(
        "Named property setter is not supported.");
  }
  return;
}

// Do not intercept.  Fallback and let it define a new own property.
"""))
        return func_decl, func_def

    bind_return_value(
        body,
        cg_context,
        overriding_args=["${blink_property_name}", "${blink_property_value}"])
    body.register_code_symbol(
        make_v8_to_blink_value(
            "blink_property_value",
            "${v8_property_value}",
            cg_context.named_property_setter.arguments[1].idl_type,
            argument=cg_context.named_property_setter.arguments[1]))

    if "Custom" in cg_context.named_property_setter.extended_attributes:
        text = _format(
            "${class_name}::{}"
            "(${blink_property_name}, ${v8_property_value}, ${info});",
            custom_function_name(cg_context))
        body.append(TextNode(text))
        return func_decl, func_def

    body.extend([
        TextNode("""\
// 3.9.2. [[Set]]
// https://heycam.github.io/webidl/#legacy-platform-object-set
// step 1. If O and Receiver are the same object, then:\
"""),
        CxxLikelyIfNode(cond="${info}.Holder() == ${info}.This()",
                        body=[
                            TextNode("""\
// step 1.2.1. Invoke the named property setter with P and V.\
"""),
                            make_steps_of_ce_reactions(cg_context),
                            EmptyNode(),
                            make_v8_set_return_value(cg_context),
                            TextNode("""\
% if interface.identifier == "CSSStyleDeclaration":
// CSSStyleDeclaration is abusing named properties.
// Do not intercept if the property is not found.
% else:
bindings::V8SetReturnValue(${info}, nullptr);
% endif
return;"""),
                        ]),
        EmptyNode(),
        TextNode("""\
// Do not intercept.  Fallback to OrdinarySetWithOwnDescriptor.
"""),
    ])

    return func_decl, func_def


def make_named_property_deleter_callback(cg_context, function_name):
    assert isinstance(cg_context, CodeGenContext)
    assert isinstance(function_name, str)

    arg_decls = [
        "v8::Local<v8::Name> v8_property_name",
        "const v8::PropertyCallbackInfo<v8::Boolean>& info",
    ]
    arg_names = ["v8_property_name", "info"]

    func_decl, func_def = _make_interceptor_callback(
        cg_context, function_name, arg_decls, arg_names, cg_context.class_name,
        "NamedPropertyDeleter")
    body = func_def.body

    props = cg_context.interface.indexed_and_named_properties
    if (not cg_context.named_property_deleter
            and "NotEnumerable" in props.named_getter.extended_attributes):
        body.append(
            TextNode("""\
// 3.9.4. [[Delete]]
// https://heycam.github.io/webidl/#legacy-platform-object-delete
// step 2. If O supports named properties, O does not implement an interface
//   with the [Global] extended attribute and the result of calling the
//   named property visibility algorithm with property name P and object O
//   is true, then:
//
// There is no easy way to determine whether the named property is visible
// or not.  Just do not intercept and fallback to the default behavior.
"""))
        return func_decl, func_def

    if not cg_context.named_property_deleter:
        body.append(
            TextNode("""\
// 3.9.4. [[Delete]]
// https://heycam.github.io/webidl/#legacy-platform-object-delete
// step 2. If O supports named properties, O does not implement an interface
//   with the [Global] extended attribute and the result of calling the
//   named property visibility algorithm with property name P and object O
//   is true, then:
// step 2.1. If O does not implement an interface with a named property
//   deleter, then return false.
ExceptionState exception_state(${info}.GetIsolate(),
                               ExceptionState::kNamedDeletionContext,
                               "${interface.identifier}");
bool does_exist = ${blink_receiver}->NamedPropertyQuery(
    ${blink_property_name}, exception_state);
if (exception_state.HadException())
  return;
if (does_exist) {
  bindings::V8SetReturnValue(${info}, false);
  if (${info}.ShouldThrowOnError()) {
    exception_state.ThrowTypeError("Named property deleter is not supported.");
  }
  return;
}

// Do not intercept.
"""))
        return func_decl, func_def

    bind_return_value(
        body, cg_context, overriding_args=["${blink_property_name}"])

    if "Custom" in cg_context.named_property_deleter.extended_attributes:
        text = _format("${class_name}::{}(${blink_property_name}, ${info});",
                       custom_function_name(cg_context))
        body.append(TextNode(text))
        return func_decl, func_def

    body.extend([
        TextNode("""\
// 3.9.4. [[Delete]]
// https://heycam.github.io/webidl/#legacy-platform-object-delete\
"""),
        make_steps_of_ce_reactions(cg_context),
        EmptyNode(),
        make_v8_set_return_value(cg_context),
        TextNode("""\
if (${return_value} == NamedPropertyDeleterResult::kDidNotDelete) {
  if (${info}.ShouldThrowOnError()) {
    ExceptionState exception_state(${info}.GetIsolate(),
                                   ExceptionState::kNamedDeletionContext,
                                   "${interface.identifier}");
    exception_state.ThrowTypeError("Failed to delete a property.");
  }
  return;
}"""),
    ])

    return func_decl, func_def


def make_named_property_definer_callback(cg_context, function_name):
    assert isinstance(cg_context, CodeGenContext)
    assert isinstance(function_name, str)

    arg_decls = [
        "v8::Local<v8::Name> v8_property_name",
        "const v8::PropertyDescriptor& v8_property_desc",
        "const v8::PropertyCallbackInfo<v8::Value>& info",
    ]
    arg_names = ["v8_property_name", "v8_property_desc", "info"]

    func_decl, func_def = _make_interceptor_callback(
        cg_context, function_name, arg_decls, arg_names, cg_context.class_name,
        "NamedPropertyDefiner")
    body = func_def.body

    if cg_context.interface.identifier == "CSSStyleDeclaration":
        body.append(
            TextNode("""\
// CSSStyleDeclaration is abusing named properties.
// Do not intercept.  Fallback to OrdinaryDefineOwnProperty.
"""))
    elif cg_context.interface.identifier in ("HTMLEmbedElement",
                                             "HTMLObjectElement"):
        body.append(
            TextNode("""\
// HTMLEmbedElement and HTMLObjectElement are abusing named properties.
// Do not intercept.  Fallback to OrdinaryDefineOwnProperty.
"""))
    elif not cg_context.interface.indexed_and_named_properties.named_setter:
        body.append(
            TextNode("""\
// 3.9.3. [[DefineOwnProperty]]
// https://heycam.github.io/webidl/#legacy-platform-object-defineownproperty
// step 2.1. Let creating be true if P is not a supported property name, and
//   false otherwise.
// step 2.2.1. If creating is false and O does not implement an interface
//   with a named property setter, then return false.
${class_name}::NamedPropertyGetterCallback(${v8_property_name}, ${info});
const bool is_creating = ${info}.GetReturnValue().Get()->IsUndefined();
if (!is_creating) {
  bindings::V8SetReturnValue(${info}, nullptr);
  if (${info}.ShouldThrowOnError()) {
    ExceptionState exception_state(${info}.GetIsolate(),
                                   ExceptionState::kNamedSetterContext,
                                   "${interface.identifier}");
    exception_state.ThrowTypeError("Named property setter is not supported.");
  }
  return;
}

// Do not intercept.  Fallback to OrdinaryDefineOwnProperty.
"""))
    else:
        body.append(
            TextNode("""\
// 3.9.3. [[DefineOwnProperty]]
// https://heycam.github.io/webidl/#legacy-platform-object-defineownproperty
// step 2.2.2. If O implements an interface with a named property setter,
//   then:
// step 2.2.2.1. If the result of calling IsDataDescriptor(Desc) is false,
//   then return false.
if (v8_property_desc.has_get() || v8_property_desc.has_set()) {
  bindings::V8SetReturnValue(${info}, nullptr);
  if (${info}.ShouldThrowOnError()) {
    ExceptionState exception_state(${info}.GetIsolate(),
                                   ExceptionState::kNamedSetterContext,
                                   "${interface.identifier}");
    exception_state.ThrowTypeError("Accessor properties are not allowed.");
  }
  return;
}

// step 2.2.2.2. Invoke the named property setter with P and Desc.[[Value]].
${class_name}::NamedPropertySetterCallback(
    ${v8_property_name}, ${v8_property_desc}.value(), ${info});
bindings::V8SetReturnValue(${info}, nullptr);
"""))

    return func_decl, func_def


def make_named_property_descriptor_callback(cg_context, function_name):
    assert isinstance(cg_context, CodeGenContext)
    assert isinstance(function_name, str)

    arg_decls = [
        "v8::Local<v8::Name> v8_property_name",
        "const v8::PropertyCallbackInfo<v8::Value>& info",
    ]
    arg_names = ["v8_property_name", "info"]

    func_decl, func_def = _make_interceptor_callback(
        cg_context, function_name, arg_decls, arg_names, cg_context.class_name,
        "NamedPropertyDescriptor")
    body = func_def.body

    body.append(
        TextNode("""\
// LegacyPlatformObjectGetOwnProperty
// https://heycam.github.io/webidl/#LegacyPlatformObjectGetOwnProperty\
"""))

    if ("LegacyOverrideBuiltIns" not in
            cg_context.interface.extended_attributes):
        body.append(
            TextNode("""\
// step 2.1. If the result of running the named property visibility algorithm
//   with property name P and object O is true, then:
if (${v8_receiver}->GetRealNamedPropertyAttributesInPrototypeChain(
        ${current_context}, ${v8_property_name}).IsJust()) {
  return;  // Do not intercept.  Fallback to OrdinaryGetOwnProperty.
}
"""))

    pattern = """\
// step 2.1.3. If operation was defined without an identifier, then set
//   value to the result of performing the steps listed in the interface
//   description to determine the value of a named property with P as the
//   name.
// step 2.1.4. Otherwise, operation was defined with an identifier. Set
//   value to the result of performing the steps listed in the description
//   of operation with P as the only argument value.
${class_name}::NamedPropertyGetterCallback(${v8_property_name}, ${info});
v8::Local<v8::Value> v8_value = ${info}.GetReturnValue().Get();
// step 2.1. If the result of running the named property visibility
//   algorithm with property name P and object O is true, then:
// step 3. Return OrdinaryGetOwnProperty(O, P).
if (v8_value->IsUndefined())
  return;  // Do not intercept.  Fallback to OrdinaryGetOwnProperty.

// step 2.1.6. Set desc.[[Value]] to the result of converting value to an
//   ECMAScript value.
// step 2.1.7. If O implements an interface with a named property setter,
//   then set desc.[[Writable]] to true, otherwise set it to false.
// step 2.1.8. If O implements an interface with the
//   [LegacyUnenumerableNamedProperties] extended attribute, then set
//   desc.[[Enumerable]] to false, otherwise set it to true.
// step 2.1.9. Set desc.[[Configurable]] to true.
v8::PropertyDescriptor desc(v8_value, /*writable=*/{cxx_writable});
desc.set_enumerable({cxx_enumerable});
desc.set_configurable(true);
bindings::V8SetReturnValue(${info}, desc);
"""
    props = cg_context.interface.indexed_and_named_properties
    writable = bool(props.named_setter)
    cxx_writable = "true" if writable else "false"
    enumerable = props.is_named_property_enumerable
    cxx_enumerable = "true" if enumerable else "false"
    body.append(
        TextNode(
            _format(
                pattern,
                cxx_writable=cxx_writable,
                cxx_enumerable=cxx_enumerable)))

    return func_decl, func_def


def make_named_property_query_callback(cg_context, function_name):
    assert isinstance(cg_context, CodeGenContext)
    assert isinstance(function_name, str)

    props = cg_context.interface.indexed_and_named_properties
    if "NotEnumerable" in props.named_getter.extended_attributes:
        return None, None

    arg_decls = [
        "v8::Local<v8::Name> v8_property_name",
        "const v8::PropertyCallbackInfo<v8::Integer>& info",
    ]
    arg_names = ["v8_property_name", "info"]

    func_decl, func_def = _make_interceptor_callback(
        cg_context, function_name, arg_decls, arg_names, cg_context.class_name,
        "NamedPropertyQuery")
    body = func_def.body

    flags = []
    if not props.named_setter:
        flags.append("v8::ReadOnly")
    if not props.is_named_property_enumerable:
        flags.append("v8::DontEnum")
    if not flags:
        flags.append("v8::None")
    if len(flags) == 1:
        property_attribute = flags[0]
    else:
        property_attribute = " | ".join(flags)

    body.extend([
        TextNode("""\
ExceptionState exception_state(${isolate},
                               ExceptionState::kNamedGetterContext,
                               "${interface.identifier}");
bool does_exist = ${blink_receiver}->NamedPropertyQuery(
    ${blink_property_name}, exception_state);
if (!does_exist)
  return;  // Do not intercept.
"""),
        TextNode(
            _format(
                "bindings::V8SetReturnValue"
                "(${info}, uint32_t({property_attribute}));",
                property_attribute=property_attribute)),
    ])

    return func_decl, func_def


def make_named_property_enumerator_callback(cg_context, function_name):
    assert isinstance(cg_context, CodeGenContext)
    assert isinstance(function_name, str)

    props = cg_context.interface.indexed_and_named_properties
    if "NotEnumerable" in props.named_getter.extended_attributes:
        return None, None

    arg_decls = ["const v8::PropertyCallbackInfo<v8::Array>& info"]
    arg_names = ["info"]

    func_decl, func_def = _make_interceptor_callback(
        cg_context, function_name, arg_decls, arg_names, cg_context.class_name,
        "NamedPropertyEnumerator")
    body = func_def.body

    body.append(
        TextNode("""\
// 3.9.6. [[OwnPropertyKeys]]
// https://heycam.github.io/webidl/#legacy-platform-object-ownpropertykeys
// step 3. If O supports named properties, then for each P of O's supported
//   property names that is visible according to the named property
//   visibility algorithm, append P to keys.
Vector<String> blink_property_names;
ExceptionState exception_state(${info}.GetIsolate(),
                               ExceptionState::kEnumerationContext,
                               "${interface.identifier}");
${blink_receiver}->NamedPropertyEnumerator(
    blink_property_names, exception_state);
if (exception_state.HadException())
  return;
bindings::V8SetReturnValue(
    ${info},
    ToV8(blink_property_names, ${creation_context_object}, ${isolate}));
"""))

    return func_decl, func_def


# ----------------------------------------------------------------------------
# Callback functions of interceptors on named properties object
# ----------------------------------------------------------------------------


def make_named_props_obj_indexed_getter_callback(cg_context, function_name):
    assert isinstance(cg_context, CodeGenContext)
    assert isinstance(function_name, str)

    arg_decls = [
        "uint32_t index",
        "const v8::PropertyCallbackInfo<v8::Value>& info",
    ]
    arg_names = ["index", "info"]

    func_def = _make_interceptor_callback_def(
        cg_context, function_name, arg_decls, arg_names, None,
        "NamedPropertiesObject_IndexedPropertyGetter")
    body = func_def.body

    body.append(
        TextNode("""\
v8::Local<v8::String> property_name =
    V8AtomicString(${isolate}, AtomicString::Number(${index}));
NamedPropsObjNamedGetterCallback(property_name, ${info});
"""))

    return func_def


def make_named_props_obj_indexed_deleter_callback(cg_context, function_name):
    assert isinstance(cg_context, CodeGenContext)
    assert isinstance(function_name, str)

    arg_decls = [
        "uint32_t index",
        "const v8::PropertyCallbackInfo<v8::Boolean>& info",
    ]
    arg_names = ["index", "info"]

    func_def = _make_interceptor_callback_def(
        cg_context, function_name, arg_decls, arg_names, None,
        "NamedPropertiesObject_IndexedPropertyDeleter")
    body = func_def.body

    body.append(
        TextNode("""\
bindings::V8SetReturnValue(${info}, false);
if (${info}.ShouldThrowOnError()) {
  ExceptionState exception_state(${info}.GetIsolate(),
                                 ExceptionState::kIndexedDeletionContext,
                                 "${interface.identifier}");
  exception_state.ThrowTypeError("Named property deleter is not supported.");
}
"""))

    return func_def


def make_named_props_obj_indexed_definer_callback(cg_context, function_name):
    assert isinstance(cg_context, CodeGenContext)
    assert isinstance(function_name, str)

    arg_decls = [
        "uint32_t index",
        "const v8::PropertyDescriptor& v8_property_desc",
        "const v8::PropertyCallbackInfo<v8::Value>& info",
    ]
    arg_names = ["index", "v8_property_desc", "info"]

    func_def = _make_interceptor_callback_def(
        cg_context, function_name, arg_decls, arg_names, None,
        "NamedPropertiesObject_IndexedPropertyDefiner")
    body = func_def.body

    body.append(
        TextNode("""\
// 3.6.4.2. [[DefineOwnProperty]]
// https://heycam.github.io/webidl/#named-properties-object-defineownproperty
bindings::V8SetReturnValue(${info}, nullptr);
if (${info}.ShouldThrowOnError()) {
  ExceptionState exception_state(${info}.GetIsolate(),
                                 ExceptionState::kIndexedSetterContext,
                                 "${interface.identifier}");
  exception_state.ThrowTypeError("Named property deleter is not supported.");
}
"""))

    return func_def


def make_named_props_obj_indexed_descriptor_callback(cg_context,
                                                     function_name):
    assert isinstance(cg_context, CodeGenContext)
    assert isinstance(function_name, str)

    arg_decls = [
        "uint32_t index",
        "const v8::PropertyCallbackInfo<v8::Value>& info",
    ]
    arg_names = ["index", "info"]

    func_def = _make_interceptor_callback_def(
        cg_context, function_name, arg_decls, arg_names, None,
        "NamedPropertiesObject_IndexedPropertyDescriptor")
    body = func_def.body

    body.append(
        TextNode("""\
v8::Local<v8::String> property_name =
    V8AtomicString(${isolate}, AtomicString::Number(${index}));
NamedPropsObjNamedDescriptorCallback(property_name, ${info});
"""))

    return func_def


def make_named_props_obj_named_getter_callback(cg_context, function_name):
    assert isinstance(cg_context, CodeGenContext)
    assert isinstance(function_name, str)

    arg_decls = [
        "v8::Local<v8::Name> v8_property_name",
        "const v8::PropertyCallbackInfo<v8::Value>& info",
    ]
    arg_names = ["v8_property_name", "info"]

    func_def = _make_interceptor_callback_def(
        cg_context, function_name, arg_decls, arg_names, None,
        "NamedPropertiesObject_NamedPropertyGetter")
    body = func_def.body

    body.append(
        TextNode("""\
// 3.6.4.1. [[GetOwnProperty]]
// https://heycam.github.io/webidl/#named-properties-object-getownproperty
//
// TODO(yukishiino): Update the following hard-coded call to an appropriate
// one.
V8Window::NamedPropertyGetterCustom(${blink_property_name}, ${info});
"""))

    return func_def


def make_named_props_obj_named_deleter_callback(cg_context, function_name):
    assert isinstance(cg_context, CodeGenContext)
    assert isinstance(function_name, str)

    arg_decls = [
        "v8::Local<v8::Name> v8_property_name",
        "const v8::PropertyCallbackInfo<v8::Boolean>& info",
    ]
    arg_names = ["v8_property_name", "info"]

    func_def = _make_interceptor_callback_def(
        cg_context, function_name, arg_decls, arg_names, None,
        "NamedPropertiesObject_NamedPropertyDeleter")
    body = func_def.body

    body.append(
        TextNode("""\
// 3.6.4.3. [[Delete]]
// https://heycam.github.io/webidl/#named-properties-object-delete
bindings::V8SetReturnValue(${info}, false);
if (${info}.ShouldThrowOnError()) {
  ExceptionState exception_state(${info}.GetIsolate(),
                                 ExceptionState::kNamedDeletionContext,
                                 "${interface.identifier}");
  exception_state.ThrowTypeError("Named property deleter is not supported.");
}
"""))

    return func_def


def make_named_props_obj_named_definer_callback(cg_context, function_name):
    assert isinstance(cg_context, CodeGenContext)
    assert isinstance(function_name, str)

    arg_decls = [
        "v8::Local<v8::Name> v8_property_name",
        "const v8::PropertyDescriptor& v8_property_desc",
        "const v8::PropertyCallbackInfo<v8::Value>& info",
    ]
    arg_names = ["v8_property_name", "v8_property_desc", "info"]

    func_def = _make_interceptor_callback_def(
        cg_context, function_name, arg_decls, arg_names, None,
        "NamedPropertiesObject_NamedPropertyDefiner")
    body = func_def.body

    body.append(
        TextNode("""\
// 3.6.4.2. [[DefineOwnProperty]]
// https://heycam.github.io/webidl/#named-properties-object-defineownproperty
bindings::V8SetReturnValue(${info}, nullptr);
if (${info}.ShouldThrowOnError()) {
  ExceptionState exception_state(${info}.GetIsolate(),
                                 ExceptionState::kNamedSetterContext,
                                 "${interface.identifier}");
  exception_state.ThrowTypeError("Named property setter is not supported.");
}
"""))

    return func_def


def make_named_props_obj_named_descriptor_callback(cg_context, function_name):
    assert isinstance(cg_context, CodeGenContext)
    assert isinstance(function_name, str)

    arg_decls = [
        "v8::Local<v8::Name> v8_property_name",
        "const v8::PropertyCallbackInfo<v8::Value>& info",
    ]
    arg_names = ["v8_property_name", "info"]

    func_def = _make_interceptor_callback_def(
        cg_context, function_name, arg_decls, arg_names, None,
        "NamedPropertiesObject_NamedPropertyDescriptor")
    body = func_def.body

    body.append(
        TextNode("""\
// 3.6.4.1. [[GetOwnProperty]]
// https://heycam.github.io/webidl/#named-properties-object-getownproperty
// step 4. If the result of running the named property visibility algorithm
//   with property name P and object object is true, then:
if (${v8_receiver}->GetRealNamedPropertyAttributesInPrototypeChain(
        ${current_context}, ${v8_property_name}).IsJust()) {
  return;  // Do not intercept.  Fallback to OrdinaryGetOwnProperty.
}

// TODO(yukishiino): Update the following hard-coded call to an appropriate
// one.
V8Window::NamedPropertyGetterCustom(${blink_property_name}, ${info});
v8::Local<v8::Value> v8_value = ${info}.GetReturnValue().Get();
if (v8_value->IsUndefined())
  return;  // Do not intercept.  Fallback to OrdinaryGetOwnProperty.

// step 4.7. If A implements an interface with the
//   [LegacyUnenumerableNamedProperties] extended attribute, then set
//   desc.[[Enumerable]] to false, otherwise set it to true.
// step 4.8. Set desc.[[Writable]] to true and desc.[[Configurable]] to
//   true.
v8::PropertyDescriptor desc(v8_value, /*writable=*/true);
desc.set_enumerable(false);
desc.set_configurable(true);
bindings::V8SetReturnValue(${info}, desc);
"""))

    return func_def


# ----------------------------------------------------------------------------
# Callback functions of cross origin interceptors
# ----------------------------------------------------------------------------


def make_cross_origin_access_check_callback(cg_context, function_name):
    assert isinstance(cg_context, CodeGenContext)
    assert isinstance(function_name, str)

    func_def = CxxFuncDefNode(
        name=function_name,
        arg_decls=[
            "v8::Local<v8::Context> accessing_context",
            "v8::Local<v8::Object> accessed_object",
            "v8::Local<v8::Value> unused_data",
        ],
        return_type="bool")
    func_def.set_base_template_vars(cg_context.template_bindings())
    body = func_def.body
    body.add_template_var("accessing_context", "accessing_context")
    body.add_template_var("accessed_object", "accessed_object")
    bind_callback_local_vars(body, cg_context)

    if cg_context.interface.identifier == "Window":
        blink_class = "DOMWindow"
    else:
        blink_class = blink_class_name(cg_context.interface)
    body.extend([
        TextNode(
            _format(
                "{blink_class}* blink_accessed_object = "
                "${class_name}::ToWrappableUnsafe(${accessed_object});",
                blink_class=blink_class)),
        TextNode("return BindingSecurity::ShouldAllowAccessTo("
                 "ToLocalDOMWindow(${accessing_context}), "
                 "blink_accessed_object, "
                 "BindingSecurity::ErrorReportOption::kDoNotReport);"),
    ])

    return func_def


def make_cross_origin_indexed_getter_callback(cg_context, function_name):
    assert isinstance(cg_context, CodeGenContext)
    assert isinstance(function_name, str)

    arg_decls = [
        "uint32_t index",
        "const v8::PropertyCallbackInfo<v8::Value>& info",
    ]
    arg_names = ["index", "info"]

    func_def = _make_interceptor_callback_def(
        cg_context, function_name, arg_decls, arg_names, None,
        "CrossOriginProperty_IndexedPropertyGetter")
    body = func_def.body

    if cg_context.interface.identifier != "Window":
        body.append(TextNode("${throw_security_error}"))
        return func_def

    bind_return_value(body, cg_context, overriding_args=["${index}"])

    body.extend([
        TextNode("""\
if (${index} >= ${blink_receiver}->length()) {
  ${throw_security_error}
  return;
}
"""),
        make_v8_set_return_value(cg_context),
    ])

    return func_def


def make_cross_origin_indexed_setter_callback(cg_context, function_name):
    assert isinstance(cg_context, CodeGenContext)
    assert isinstance(function_name, str)

    arg_decls = [
        "uint32_t index",
        "v8::Local<v8::Value> v8_property_value",
        "const v8::PropertyCallbackInfo<v8::Value>& info",
    ]
    arg_names = ["index", "v8_property_value", "info"]

    func_def = _make_interceptor_callback_def(
        cg_context, function_name, arg_decls, arg_names, None,
        "CrossOriginProperty_IndexedPropertySetter")
    body = func_def.body

    body.append(TextNode("${throw_security_error}"))

    return func_def


def make_cross_origin_indexed_deleter_callback(cg_context, function_name):
    assert isinstance(cg_context, CodeGenContext)
    assert isinstance(function_name, str)

    arg_decls = [
        "uint32_t index",
        "const v8::PropertyCallbackInfo<v8::Boolean>& info",
    ]
    arg_names = ["index", "info"]

    func_def = _make_interceptor_callback_def(
        cg_context, function_name, arg_decls, arg_names, None,
        "CrossOriginProperty_IndexedPropertyDeleter")
    body = func_def.body

    body.append(TextNode("${throw_security_error}"))

    return func_def


def make_cross_origin_indexed_definer_callback(cg_context, function_name):
    assert isinstance(cg_context, CodeGenContext)
    assert isinstance(function_name, str)

    arg_decls = [
        "uint32_t index",
        "const v8::PropertyDescriptor& v8_property_desc",
        "const v8::PropertyCallbackInfo<v8::Value>& info",
    ]
    arg_names = ["index", "v8_property_desc", "info"]

    func_def = _make_interceptor_callback_def(
        cg_context, function_name, arg_decls, arg_names, None,
        "CrossOriginProperty_IndexedPropertyDefiner")
    body = func_def.body

    body.append(TextNode("${throw_security_error}"))

    return func_def


def make_cross_origin_indexed_descriptor_callback(cg_context, function_name):
    assert isinstance(cg_context, CodeGenContext)
    assert isinstance(function_name, str)

    arg_decls = [
        "uint32_t index",
        "const v8::PropertyCallbackInfo<v8::Value>& info",
    ]
    arg_names = ["index", "info"]

    func_def = _make_interceptor_callback_def(
        cg_context, function_name, arg_decls, arg_names, None,
        "CrossOriginProperty_IndexedPropertyDescriptor")
    body = func_def.body

    if cg_context.interface.identifier != "Window":
        body.append(TextNode("${throw_security_error}"))
        return func_def

    body.append(
        TextNode("""\
CrossOriginIndexedGetterCallback(${index}, ${info});
v8::Local<v8::Value> v8_value = ${info}.GetReturnValue().Get();
if (v8_value->IsUndefined()) {
  // Must have already thrown a SecurityError.
  return;
}

v8::PropertyDescriptor desc(v8_value, /*writable=*/false);
desc.set_enumerable(true);
desc.set_configurable(true);
bindings::V8SetReturnValue(${info}, desc);
"""))

    return func_def


def make_cross_origin_indexed_enumerator_callback(cg_context, function_name):
    assert isinstance(cg_context, CodeGenContext)
    assert isinstance(function_name, str)

    arg_decls = ["const v8::PropertyCallbackInfo<v8::Array>& info"]
    arg_names = ["info"]

    func_def = _make_interceptor_callback_def(
        cg_context, function_name, arg_decls, arg_names, None,
        "CrossOriginProperty_IndexedPropertyEnumerator")
    body = func_def.body

    if cg_context.interface.identifier != "Window":
        return func_def

    body.append(
        TextNode("""\
uint32_t length = ${blink_receiver}->length();
v8::Local<v8::Array> array =
    bindings::EnumerateIndexedProperties(${isolate}, length);
bindings::V8SetReturnValue(${info}, array);
"""))

    return func_def


def make_cross_origin_named_getter_callback(cg_context, function_name):
    assert isinstance(cg_context, CodeGenContext)
    assert isinstance(function_name, str)

    arg_decls = [
        "v8::Local<v8::Name> v8_property_name",
        "const v8::PropertyCallbackInfo<v8::Value>& info",
    ]
    arg_names = ["v8_property_name", "info"]

    func_def = _make_interceptor_callback_def(
        cg_context, function_name, arg_decls, arg_names, None,
        "CrossOriginProperty_NamedPropertyGetter")
    body = func_def.body

    string_case_body = []
    string_case_body.append(
        TextNode("""\
for (const auto& attribute : kCrossOriginAttributeTable) {
  if (${blink_property_name} != attribute.name)
    continue;
  if (UNLIKELY(!attribute.get_value)) {
    ${throw_security_error}
    return;
  }
  attribute.get_value(${v8_property_name}, ${info});
  return;
}
for (const auto& operation : kCrossOriginOperationTable) {
  if (${blink_property_name} != operation.name)
    continue;
  v8::Local<v8::Function> function;
  if (bindings::GetCrossOriginFunction(
          ${info}.GetIsolate(), operation.callback, operation.func_length,
          ${class_name}::GetWrapperTypeInfo())
          .ToLocal(&function)) {
    bindings::V8SetReturnValue(${info}, function);
  }
  return;
}
"""))
    if cg_context.interface.identifier == "Window":
        string_case_body.append(
            TextNode("""\
// Window object's document-tree child browsing context name property set
//
// TODO(yukishiino): Update the following hard-coded call to an appropriate
// one.
V8Window::NamedPropertyGetterCustom(${blink_property_name}, ${info});
if (!${info}.GetReturnValue().Get()->IsUndefined())
  return;
"""))

    body.extend([
        CxxLikelyIfNode(
            cond="${v8_property_name}->IsString()", body=string_case_body),
        EmptyNode(),
        TextNode("""\
// 7.2.3.2 CrossOriginPropertyFallback ( P )
// https://html.spec.whatwg.org/C/#crossoriginpropertyfallback-(-p-)
if (bindings::IsSupportedInCrossOriginPropertyFallback(
        ${info}.GetIsolate(), ${v8_property_name})) {
  return ${info}.GetReturnValue().SetUndefined();
}
${throw_security_error}
"""),
    ])

    return func_def


def make_cross_origin_named_setter_callback(cg_context, function_name):
    assert isinstance(cg_context, CodeGenContext)
    assert isinstance(function_name, str)

    arg_decls = [
        "v8::Local<v8::Name> v8_property_name",
        "v8::Local<v8::Value> v8_property_value",
        "const v8::PropertyCallbackInfo<v8::Value>& info",
    ]
    arg_names = ["v8_property_name", "v8_property_value", "info"]

    func_def = _make_interceptor_callback_def(
        cg_context, function_name, arg_decls, arg_names, None,
        "CrossOriginProperty_NamedPropertySetter")
    body = func_def.body

    string_case_body = []
    string_case_body.append(
        TextNode("""\
for (const auto& attribute : kCrossOriginAttributeTable) {
  if (${blink_property_name} == attribute.name && attribute.set_value) {
    attribute.set_value(${v8_property_name}, ${v8_property_value}, ${info});
    return;
  }
}
"""))

    body.extend([
        CxxLikelyIfNode(
            cond="${v8_property_name}->IsString()", body=string_case_body),
        EmptyNode(),
        TextNode("${throw_security_error}"),
    ])

    return func_def


def make_cross_origin_named_deleter_callback(cg_context, function_name):
    assert isinstance(cg_context, CodeGenContext)
    assert isinstance(function_name, str)

    arg_decls = [
        "v8::Local<v8::Name> v8_property_name",
        "const v8::PropertyCallbackInfo<v8::Boolean>& info",
    ]
    arg_names = ["v8_property_name", "info"]

    func_def = _make_interceptor_callback_def(
        cg_context, function_name, arg_decls, arg_names, None,
        "CrossOriginProperty_NamedPropertyDeleter")
    body = func_def.body

    body.append(TextNode("${throw_security_error}"))

    return func_def


def make_cross_origin_named_definer_callback(cg_context, function_name):
    assert isinstance(cg_context, CodeGenContext)
    assert isinstance(function_name, str)

    arg_decls = [
        "v8::Local<v8::Name> v8_property_name",
        "const v8::PropertyDescriptor& v8_property_desc",
        "const v8::PropertyCallbackInfo<v8::Value>& info",
    ]
    arg_names = ["v8_property_name", "v8_property_desc", "info"]

    func_def = _make_interceptor_callback_def(
        cg_context, function_name, arg_decls, arg_names, None,
        "CrossOriginProperty_NamedPropertyDefiner")
    body = func_def.body

    body.append(TextNode("${throw_security_error}"))

    return func_def


def make_cross_origin_named_descriptor_callback(cg_context, function_name):
    assert isinstance(cg_context, CodeGenContext)
    assert isinstance(function_name, str)

    arg_decls = [
        "v8::Local<v8::Name> v8_property_name",
        "const v8::PropertyCallbackInfo<v8::Value>& info",
    ]
    arg_names = ["v8_property_name", "info"]

    func_def = _make_interceptor_callback_def(
        cg_context, function_name, arg_decls, arg_names, None,
        "CrossOriginProperty_NamedPropertyDescriptor")
    body = func_def.body

    string_case_body = []
    string_case_body.append(
        TextNode("""\
// 7.2.3.4 CrossOriginGetOwnPropertyHelper ( O, P )
// https://html.spec.whatwg.org/C/#crossorigingetownpropertyhelper-(-o,-p-)
for (const auto& attribute : kCrossOriginAttributeTable) {
  if (${blink_property_name} != attribute.name)
    continue;
  v8::Local<v8::Value> get;
  v8::Local<v8::Value> set;
  if (!bindings::GetCrossOriginFunctionOrUndefined(
           ${info}.GetIsolate(), attribute.get_callback, 0,
           ${class_name}::GetWrapperTypeInfo())
           .ToLocal(&get) ||
      !bindings::GetCrossOriginFunctionOrUndefined(
           ${info}.GetIsolate(), attribute.set_callback, 1,
           ${class_name}::GetWrapperTypeInfo())
           .ToLocal(&set)) {
    return;
  }
  v8::PropertyDescriptor desc(get, set);
  desc.set_enumerable(false);
  desc.set_configurable(true);
  bindings::V8SetReturnValue(${info}, desc);
  return;
}
for (const auto& operation : kCrossOriginOperationTable) {
  if (${blink_property_name} != operation.name)
    continue;
  v8::Local<v8::Function> function;
  if (!bindings::GetCrossOriginFunction(
           ${info}.GetIsolate(), operation.callback, operation.func_length,
           ${class_name}::GetWrapperTypeInfo())
           .ToLocal(&function)) {
    return;
  }
  v8::PropertyDescriptor desc(function, /*writable=*/false);
  desc.set_enumerable(false);
  desc.set_configurable(true);
  bindings::V8SetReturnValue(${info}, desc);
  return;
}
"""))
    if cg_context.interface.identifier == "Window":
        string_case_body.append(
            TextNode("""\
// Window object's document-tree child browsing context name property set
//
// TODO(yukishiino): Update the following hard-coded call to an appropriate
// one.
V8Window::NamedPropertyGetterCustom(${blink_property_name}, ${info});
if (!${info}.GetReturnValue().Get()->IsUndefined()) {
  v8::PropertyDescriptor desc(${info}.GetReturnValue().Get(),
                              /*writable=*/false);
  desc.set_enumerable(false);
  desc.set_configurable(true);
  bindings::V8SetReturnValue(${info}, desc);
  return;
}
"""))

    body.extend([
        CxxLikelyIfNode(
            cond="${v8_property_name}->IsString()", body=string_case_body),
        EmptyNode(),
        TextNode("""\
// 7.2.3.2 CrossOriginPropertyFallback ( P )
// https://html.spec.whatwg.org/C/#crossoriginpropertyfallback-(-p-)
if (bindings::IsSupportedInCrossOriginPropertyFallback(
        ${info}.GetIsolate(), ${v8_property_name})) {
  v8::PropertyDescriptor desc(v8::Undefined(${info}.GetIsolate()),
                              /*writable=*/false);
  desc.set_enumerable(false);
  desc.set_configurable(true);
  bindings::V8SetReturnValue(${info}, desc);
  return;
}
${throw_security_error}
"""),
    ])

    return func_def


def make_cross_origin_named_query_callback(cg_context, function_name):
    assert isinstance(cg_context, CodeGenContext)
    assert isinstance(function_name, str)

    arg_decls = [
        "v8::Local<v8::Name> v8_property_name",
        "const v8::PropertyCallbackInfo<v8::Integer>& info",
    ]
    arg_names = ["v8_property_name", "info"]

    func_def = _make_interceptor_callback_def(
        cg_context, function_name, arg_decls, arg_names, None,
        "CrossOriginProperty_NamedPropertyQuery")
    body = func_def.body

    string_case_body = []
    string_case_body.append(
        TextNode("""\
// 7.2.3.4 CrossOriginGetOwnPropertyHelper ( O, P )
// https://html.spec.whatwg.org/C/#crossorigingetownpropertyhelper-(-o,-p-)
for (const auto& attribute : kCrossOriginAttributeTable) {
  if (${blink_property_name} != attribute.name)
    continue;
  int32_t v8_property_attribute = v8::DontEnum;
  if (!attribute.set_callback)
    v8_property_attribute |= v8::ReadOnly;
  bindings::V8SetReturnValue(${info}, v8_property_attribute);
  return;
}
for (const auto& operation : kCrossOriginOperationTable) {
  if (${blink_property_name} != operation.name)
    continue;
  int32_t v8_property_attribute = v8::DontEnum | v8::ReadOnly;
  bindings::V8SetReturnValue(${info}, v8_property_attribute);
  return;
}
"""))

    body.extend([
        CxxLikelyIfNode(
            cond="${v8_property_name}->IsString()", body=string_case_body),
        EmptyNode(),
        TextNode("""\
// 7.2.3.2 CrossOriginPropertyFallback ( P )
// https://html.spec.whatwg.org/C/#crossoriginpropertyfallback-(-p-)
if (bindings::IsSupportedInCrossOriginPropertyFallback(
        ${info}.GetIsolate(), ${v8_property_name})) {
  int32_t v8_property_attribute = v8::DontEnum | v8::ReadOnly;
  bindings::V8SetReturnValue(${info}, v8_property_attribute);
  return;
}
"""),
    ])

    return func_def


def make_cross_origin_named_enumerator_callback(cg_context, function_name):
    assert isinstance(cg_context, CodeGenContext)
    assert isinstance(function_name, str)

    arg_decls = ["const v8::PropertyCallbackInfo<v8::Array>& info"]
    arg_names = ["info"]

    func_def = _make_interceptor_callback_def(
        cg_context, function_name, arg_decls, arg_names, None,
        "CrossOriginProperty_NamedPropertyEnumerator")
    body = func_def.body

    body.append(
        TextNode("""\
bindings::V8SetReturnValue(
    ${info},
    bindings::EnumerateCrossOriginProperties(
        ${isolate},
        kCrossOriginAttributeTable,
        kCrossOriginOperationTable));
"""))

    return func_def


# ----------------------------------------------------------------------------
# Callback functions of same origin interceptors
# ----------------------------------------------------------------------------


def make_same_origin_indexed_getter_callback(cg_context, function_name):
    assert isinstance(cg_context, CodeGenContext)
    assert isinstance(function_name, str)

    arg_decls = [
        "uint32_t index",
        "const v8::PropertyCallbackInfo<v8::Value>& info",
    ]
    arg_names = ["index", "info"]

    func_def = _make_interceptor_callback_def(
        cg_context, function_name, arg_decls, arg_names, None,
        "SameOriginProperty_IndexedPropertyGetter")
    body = func_def.body

    bind_return_value(body, cg_context, overriding_args=["${index}"])

    body.extend([
        TextNode("""\
if (${index} >= ${blink_receiver}->length()) {
  return;
}
"""),
        make_v8_set_return_value(cg_context),
    ])

    return func_def


def make_same_origin_indexed_setter_callback(cg_context, function_name):
    assert isinstance(cg_context, CodeGenContext)
    assert isinstance(function_name, str)

    arg_decls = [
        "uint32_t index",
        "v8::Local<v8::Value> v8_property_value",
        "const v8::PropertyCallbackInfo<v8::Value>& info",
    ]
    arg_names = ["index", "v8_property_value", "info"]

    func_def = _make_interceptor_callback_def(
        cg_context, function_name, arg_decls, arg_names, None,
        "SameOriginProperty_IndexedPropertySetter")
    body = func_def.body

    body.append(
        TextNode("""\
bindings::V8SetReturnValue(${info}, nullptr);
if (${info}.ShouldThrowOnError()) {
  ExceptionState exception_state(${info}.GetIsolate(),
                                 ExceptionState::kIndexedSetterContext,
                                 "${interface.identifier}");
  exception_state.ThrowTypeError(
      "Indexed property setter is not supported.");
}
"""))

    return func_def


def make_same_origin_indexed_deleter_callback(cg_context, function_name):
    assert isinstance(cg_context, CodeGenContext)
    assert isinstance(function_name, str)

    arg_decls = [
        "uint32_t index",
        "const v8::PropertyCallbackInfo<v8::Boolean>& info",
    ]
    arg_names = ["index", "info"]

    func_def = _make_interceptor_callback_def(
        cg_context, function_name, arg_decls, arg_names, None,
        "SameOriginProperty_IndexedPropertyDeleter")
    body = func_def.body

    body.append(
        TextNode("""\
// 7.4.9 [[Delete]] ( P )
// https://html.spec.whatwg.org/C/#windowproxy-delete
const bool is_supported = ${index} < ${blink_receiver}->length();
bindings::V8SetReturnValue(${info}, !is_supported);
if (is_supported and ${info}.ShouldThrowOnError()) {
  ExceptionState exception_state(${info}.GetIsolate(),
                                 ExceptionState::kIndexedDeletionContext,
                                 "${interface.identifier}");
  exception_state.ThrowTypeError("Index property deleter is not supported.");
}
"""))

    return func_def


def make_same_origin_indexed_definer_callback(cg_context, function_name):
    assert isinstance(cg_context, CodeGenContext)
    assert isinstance(function_name, str)

    arg_decls = [
        "uint32_t index",
        "const v8::PropertyDescriptor& v8_property_desc",
        "const v8::PropertyCallbackInfo<v8::Value>& info",
    ]
    arg_names = ["index", "v8_property_desc", "info"]

    func_def = _make_interceptor_callback_def(
        cg_context, function_name, arg_decls, arg_names, None,
        "SameOriginProperty_IndexedPropertyDefiner")
    body = func_def.body

    body.append(
        TextNode("""\
// 7.4.6 [[DefineOwnProperty]] ( P, Desc )
// https://html.spec.whatwg.org/C/#windowproxy-defineownproperty
bindings::V8SetReturnValue(${info}, nullptr);
if (${info}.ShouldThrowOnError()) {
  ExceptionState exception_state(${info}.GetIsolate(),
                                 ExceptionState::kIndexedSetterContext,
                                 "${interface.identifier}");
  exception_state.ThrowTypeError("Index property setter is not supported.");
}
"""))

    return func_def


def make_same_origin_indexed_descriptor_callback(cg_context, function_name):
    assert isinstance(cg_context, CodeGenContext)
    assert isinstance(function_name, str)

    arg_decls = [
        "uint32_t index",
        "const v8::PropertyCallbackInfo<v8::Value>& info",
    ]
    arg_names = ["index", "info"]

    func_def = _make_interceptor_callback_def(
        cg_context, function_name, arg_decls, arg_names, None,
        "SameOriginProperty_IndexedPropertyDescriptor")
    body = func_def.body

    body.append(
        TextNode("""\
// 7.4.5 [[GetOwnProperty]] ( P )
// https://html.spec.whatwg.org/C/#windowproxy-getownproperty
SameOriginIndexedGetterCallback(${index}, ${info});
v8::Local<v8::Value> v8_value = ${info}.GetReturnValue().Get();
if (v8_value->IsUndefined()) {
  return;  // Do not intercept.
}

v8::PropertyDescriptor desc(v8_value, /*writable=*/false);
desc.set_enumerable(true);
desc.set_configurable(true);
bindings::V8SetReturnValue(${info}, desc);
"""))

    return func_def


def make_same_origin_indexed_enumerator_callback(cg_context, function_name):
    assert isinstance(cg_context, CodeGenContext)
    assert isinstance(function_name, str)

    arg_decls = ["const v8::PropertyCallbackInfo<v8::Array>& info"]
    arg_names = ["info"]

    func_def = _make_interceptor_callback_def(
        cg_context, function_name, arg_decls, arg_names, None,
        "SameOriginProperty_IndexedPropertyEnumerator")
    body = func_def.body

    body.append(
        TextNode("""\
uint32_t length = ${blink_receiver}->length();
v8::Local<v8::Array> array =
    bindings::EnumerateIndexedProperties(${isolate}, length);
bindings::V8SetReturnValue(${info}, array);
"""))

    return func_def


# ----------------------------------------------------------------------------
# Installer functions
# ----------------------------------------------------------------------------

# FN = function name
FN_INSTALL_INTERFACE_TEMPLATE = name_style.func("InstallInterfaceTemplate")
FN_INSTALL_UNCONDITIONAL_PROPS = name_style.func(
    "InstallUnconditionalProperties")
FN_INSTALL_CONTEXT_INDEPENDENT_PROPS = name_style.func(
    "InstallContextIndependentProperties")
FN_INSTALL_CONTEXT_DEPENDENT_PROPS = name_style.func(
    "InstallContextDependentProperties")

# TP = trampoline name
TP_INSTALL_INTERFACE_TEMPLATE = name_style.member_var(
    "install_interface_template_func")
TP_INSTALL_UNCONDITIONAL_PROPS = name_style.member_var(
    "install_unconditional_props_func")
TP_INSTALL_CONTEXT_INDEPENDENT_PROPS = name_style.member_var(
    "install_context_independent_props_func")
TP_INSTALL_CONTEXT_DEPENDENT_PROPS = name_style.member_var(
    "install_context_dependent_props_func")


def bind_installer_local_vars(code_node, cg_context):
    assert isinstance(code_node, SymbolScopeNode)
    assert isinstance(cg_context, CodeGenContext)

    S = SymbolNode

    local_vars = []

    local_vars.extend([
        S("is_in_secure_context",
          ("const bool ${is_in_secure_context} = "
           "${execution_context}->IsSecureContext();")),
        S("isolate", "v8::Isolate* ${isolate} = ${v8_context}->GetIsolate();"),
        S("script_state",
          "ScriptState* ${script_state} = ScriptState::From(${v8_context});"),
        S("wrapper_type_info",
          ("const WrapperTypeInfo* const ${wrapper_type_info} = "
           "${class_name}::GetWrapperTypeInfo();")),
    ])

    if cg_context.interface:
        local_vars.extend([
            S("interface_function_template",
              ("v8::Local<v8::FunctionTemplate> "
               "${interface_function_template} = "
               "${interface_template}.As<v8::FunctionTemplate>();")),
            S("instance_object_template",
              ("v8::Local<v8::ObjectTemplate> ${instance_object_template} = "
               "${interface_function_template}->InstanceTemplate();")),
            S("instance_template",
              ("v8::Local<v8::Template> ${instance_template} = "
               "${instance_object_template};")),
            S("prototype_object_template",
              ("v8::Local<v8::ObjectTemplate> ${prototype_object_template} = "
               "${interface_function_template}->PrototypeTemplate();")),
            S("prototype_template",
              ("v8::Local<v8::Template> ${prototype_template} = "
               "${prototype_object_template};")),
            S("signature", ("v8::Local<v8::Signature> ${signature} = "
                            "v8::Signature::New(${isolate}, "
                            "${interface_function_template});")),
        ])
    elif cg_context.namespace:
        local_vars.extend([
            S("namespace_object_template",
              ("v8::Local<v8::ObjectTemplate> "
               "${namespace_object_template} = "
               "${interface_template}.As<v8::ObjectTemplate>();")),
            S("instance_template",
              "v8::Local<v8::Template> ${instance_template};"),
            S("prototype_template",
              "v8::Local<v8::Template> ${prototype_template};"),
            S("signature", "v8::Local<v8::Signature> ${signature};"),
        ])
    elif cg_context.callback_interface:
        local_vars.extend([
            S("interface_function_template",
              ("v8::Local<v8::FunctionTemplate> "
               "${interface_function_template} = "
               "${interface_template}.As<v8::FunctionTemplate>();")),
            S("instance_template",
              "v8::Local<v8::Template> ${instance_template};"),
            S("prototype_template",
              "v8::Local<v8::Template> ${prototype_template};"),
            S("signature", "v8::Local<v8::Signature> ${signature};"),
        ])

    # context_feature_settings
    node = S("context_feature_settings",
             ("const ContextFeatureSettings* ${context_feature_settings} = "
              "ContextFeatureSettings::From("
              "${execution_context}, "
              "ContextFeatureSettings::CreationMode::kDontCreateIfNotExists"
              ");"))
    node.accumulate(
        CodeGenAccumulator.require_include_headers([
            "third_party/blink/renderer/core/context_features/context_feature_settings.h"
        ]))
    local_vars.append(node)

    # execution_context
    node = S("execution_context", ("ExecutionContext* ${execution_context} = "
                                   "ExecutionContext::From(${script_state});"))
    node.accumulate(
        CodeGenAccumulator.require_include_headers([
            "third_party/blink/renderer/core/execution_context/execution_context.h"
        ]))
    local_vars.append(node)

    # parent_interface_template
    pattern = (
        "v8::Local<v8::FunctionTemplate> ${parent_interface_template}{_1};")
    interface = cg_context.interface
    if not interface:
        _1 = ""
    elif (interface and "Global" in interface.extended_attributes
          and interface.indexed_and_named_properties
          and interface.indexed_and_named_properties.has_named_properties):
        # https://heycam.github.io/webidl/#named-properties-object
        _1 = " = ${npo_interface_template}"  # npo = named properties object
    elif interface.inherited:
        _1 = (" = ${wrapper_type_info}->parent_class"
              "->GetV8ClassTemplate(${isolate}, ${world})"
              ".As<v8::FunctionTemplate>()")
    else:
        _1 = ""
    local_vars.append(S("parent_interface_template", _format(pattern, _1=_1)))

    # npo_interface_template
    # npo = named properties object
    text = """\
// Named properties object
v8::Local<v8::FunctionTemplate> ${npo_interface_template} =
    v8::FunctionTemplate::New(${isolate});
v8::Local<v8::ObjectTemplate> ${npo_prototype_template} =
    ${npo_interface_template}->PrototypeTemplate();
${npo_interface_template}->Inherit(
    ${wrapper_type_info}->parent_class
    ->GetV8ClassTemplate(${isolate}, ${world}).As<v8::FunctionTemplate>());
${npo_prototype_template}->SetImmutableProto();
${npo_prototype_template}->Set(
    v8::Symbol::GetToStringTag(${isolate}),
    V8AtomicString(${isolate}, "${interface.identifier}Properties"),
    static_cast<v8::PropertyAttribute>(v8::ReadOnly | v8::DontEnum));
// Make the named properties object look like the global object.  Note that
// the named properties object is _not_ a prototype object, plus, we'd like
// the named properties object to behave just like the global object (= the
// wrapper object of the global object) from the point of view of named
// properties.
// https://heycam.github.io/webidl/#named-properties-object
${npo_prototype_template}->SetInternalFieldCount(
    kV8DefaultWrapperInternalFieldCount);
"""
    local_vars.append(S("npo_interface_template", text))
    local_vars.append(
        S("npo_prototype_template",
          "<% npo_interface_template.request_symbol_definition() %>"))

    # Arguments have priority over local vars.
    template_vars = code_node.template_vars
    for symbol_node in local_vars:
        if symbol_node.name not in template_vars:
            code_node.register_code_symbol(symbol_node)


def _make_property_entry_cross_origin_check(property_,
                                            is_get=False,
                                            is_set=False):
    constants = {
        False: "unsigned(IDLMemberInstaller::FlagCrossOriginCheck::kCheck)",
        True:
        "unsigned(IDLMemberInstaller::FlagCrossOriginCheck::kDoNotCheck)",
    }
    if property_.is_static:
        return constants[True]
    if "CrossOrigin" not in property_.extended_attributes:
        return constants[False]
    values = property_.extended_attributes.values_of("CrossOrigin")
    if is_get:
        return constants[not values or "Getter" in values]
    elif is_set:
        return constants["Setter" in values]
    else:
        return constants[True]


def _make_property_entry_location(property_):
    if hasattr(property_, "is_static") and property_.is_static:
        return "unsigned(IDLMemberInstaller::FlagLocation::kInterface)"
    if "Global" in property_.owner.extended_attributes:
        return "unsigned(IDLMemberInstaller::FlagLocation::kInstance)"
    if "LegacyUnforgeable" in property_.extended_attributes:
        return "unsigned(IDLMemberInstaller::FlagLocation::kInstance)"
    return "unsigned(IDLMemberInstaller::FlagLocation::kPrototype)"


def _make_property_entry_receiver_check(property_):
    if ("LegacyLenientThis" in property_.extended_attributes
            or property_.is_static
            or (isinstance(property_, web_idl.Attribute)
                and property_.idl_type.unwrap().is_promise)
            or (isinstance(property_, web_idl.OverloadGroup)
                and property_[0].return_type.unwrap().is_promise)):
        return "unsigned(IDLMemberInstaller::FlagReceiverCheck::kDoNotCheck)"
    else:
        return "unsigned(IDLMemberInstaller::FlagReceiverCheck::kCheck)"


def _make_property_entry_v8_c_function(entry):
    if entry.no_alloc_direct_callback_name is None:
        return None
    return "v8::CFunction::MakeWithFallbackSupport({})".format(
        entry.no_alloc_direct_callback_name)


def _make_property_entry_v8_cached_accessor(property_):
    return "unsigned(V8PrivateProperty::CachedAccessor::{})".format(
        property_.extended_attributes.value_of("CachedAccessor") or "kNone")


def _make_property_entry_v8_property_attribute(property_):
    values = []
    if "NotEnumerable" in property_.extended_attributes:
        values.append("v8::DontEnum")
    if "LegacyUnforgeable" in property_.extended_attributes:
        if not isinstance(property_, web_idl.Attribute):
            values.append("v8::ReadOnly")
        values.append("v8::DontDelete")
    if not values:
        values.append("v8::None")
    if len(values) == 1:
        return "unsigned({})".format(values[0])
    else:
        return "unsigned({})".format(" | ".join(values))


def _make_property_entry_v8_side_effect(property_):
    if property_.extended_attributes.value_of("Affects") == "Nothing":
        return "unsigned(v8::SideEffectType::kHasNoSideEffect)"
    else:
        return "unsigned(v8::SideEffectType::kHasSideEffect)"


def _make_property_entry_world(world):
    if world == CodeGenContext.MAIN_WORLD:
        return "unsigned(IDLMemberInstaller::FlagWorld::kMainWorld)"
    if world == CodeGenContext.NON_MAIN_WORLDS:
        return "unsigned(IDLMemberInstaller::FlagWorld::kNonMainWorlds)"
    if world == CodeGenContext.ALL_WORLDS:
        return "unsigned(IDLMemberInstaller::FlagWorld::kAllWorlds)"
    assert False


def _make_attribute_registration_table(table_name, attribute_entries):
    assert isinstance(table_name, str)
    assert isinstance(attribute_entries, (list, tuple))
    assert all(
        isinstance(entry, _PropEntryAttribute) for entry in attribute_entries)

    T = TextNode

    entry_nodes = []
    for entry in attribute_entries:
        pattern = ("{{"
                   "\"{property_name}\", "
                   "{attribute_get_callback}, "
                   "{attribute_set_callback}, "
                   "{v8_property_attribute}, "
                   "{location}, "
                   "{world}, "
                   "{receiver_check}, "
                   "{cross_origin_check_for_get}, "
                   "{cross_origin_check_for_set}, "
                   "{v8_side_effect}, "
                   "{v8_cached_accessor}"
                   "}},")
        text = _format(
            pattern,
            property_name=entry.property_.identifier,
            attribute_get_callback=entry.attr_get_callback_name,
            attribute_set_callback=(entry.attr_set_callback_name or "nullptr"),
            v8_property_attribute=_make_property_entry_v8_property_attribute(
                entry.property_),
            location=_make_property_entry_location(entry.property_),
            world=_make_property_entry_world(entry.world),
            receiver_check=_make_property_entry_receiver_check(
                entry.property_),
            cross_origin_check_for_get=(
                _make_property_entry_cross_origin_check(entry.property_,
                                                        is_get=True)),
            cross_origin_check_for_set=(
                _make_property_entry_cross_origin_check(entry.property_,
                                                        is_set=True)),
            v8_side_effect=_make_property_entry_v8_side_effect(
                entry.property_),
            v8_cached_accessor=_make_property_entry_v8_cached_accessor(
                entry.property_))
        entry_nodes.append(T(text))

    return ListNode([
        T("static const IDLMemberInstaller::AttributeConfig " + table_name +
          "[] = {"),
        ListNode(entry_nodes),
        T("};"),
    ])


def _make_constant_callback_registration_table(table_name, constant_entries):
    assert isinstance(table_name, str)
    assert isinstance(constant_entries, (list, tuple))
    assert all(
        isinstance(entry, _PropEntryConstant)
        and isinstance(entry.const_callback_name, str)
        for entry in constant_entries)

    T = TextNode

    entry_nodes = []
    for entry in constant_entries:
        pattern = ("{{" "\"{property_name}\", " "{constant_callback}" "}},")
        text = _format(
            pattern,
            property_name=entry.property_.identifier,
            constant_callback=entry.const_callback_name)
        entry_nodes.append(T(text))

    return ListNode([
        T("static const IDLMemberInstaller::ConstantCallbackConfig " +
          table_name + "[] = {"),
        ListNode(entry_nodes),
        T("};"),
    ])


def _make_constant_value_registration_table(table_name, constant_entries):
    assert isinstance(table_name, str)
    assert isinstance(constant_entries, (list, tuple))
    assert all(
        isinstance(entry, _PropEntryConstant)
        and entry.const_callback_name is None for entry in constant_entries)

    T = TextNode

    entry_nodes = []
    for entry in constant_entries:
        pattern = ("{{"
                   "\"{property_name}\", "
                   "{constant_value}"
                   "}},")
        text = _format(pattern,
                       property_name=entry.property_.identifier,
                       constant_value=entry.const_constant_name)
        entry_nodes.append(T(text))

    return ListNode([
        T("static const IDLMemberInstaller::ConstantValueConfig " +
          table_name + "[] = {"),
        ListNode(entry_nodes),
        T("};"),
    ])


def _make_exposed_construct_registration_table(table_name,
                                               exposed_construct_entries):
    assert isinstance(table_name, str)
    assert isinstance(exposed_construct_entries, (list, tuple))
    assert all(
        isinstance(entry, _PropEntryExposedConstruct)
        for entry in exposed_construct_entries)

    T = TextNode

    entry_nodes = []
    for entry in exposed_construct_entries:
        pattern = ("{{"
                   "\"{property_name}\", "
                   "{exposed_construct_callback}"
                   "}}, ")
        text = _format(pattern,
                       property_name=entry.property_.identifier,
                       exposed_construct_callback=entry.prop_callback_name)
        entry_nodes.append(T(text))

    return ListNode([
        T("static const IDLMemberInstaller::ExposedConstructConfig " +
          table_name + "[] = {"),
        ListNode(entry_nodes),
        T("};"),
    ])


def _make_operation_registration_table(table_name, operation_entries):
    assert isinstance(table_name, str)
    assert isinstance(operation_entries, (list, tuple))
    assert all(
        isinstance(entry, _PropEntryOperationGroup)
        for entry in operation_entries)

    T = TextNode

    no_alloc_direct_call_count = 0
    for entry in operation_entries:
        if entry.no_alloc_direct_callback_name:
            no_alloc_direct_call_count += 1
    assert (no_alloc_direct_call_count == 0
            or no_alloc_direct_call_count == len(operation_entries))
    no_alloc_direct_call_enabled = no_alloc_direct_call_count > 0

    entry_nodes = []
    for entry in operation_entries:
        pattern = ("{{"
                   "\"{property_name}\", "
                   "{operation_callback}, "
                   "{function_length}, "
                   "{v8_property_attribute}, "
                   "{location}, "
                   "{world}, "
                   "{receiver_check}, "
                   "{cross_origin_check}, "
                   "{v8_side_effect}"
                   "}}, ")
        if no_alloc_direct_call_enabled:
            pattern = "{{" + pattern + "{v8_c_function}}}, "
        text = _format(
            pattern,
            property_name=entry.property_.identifier,
            operation_callback=entry.op_callback_name,
            function_length=entry.op_func_length,
            v8_property_attribute=_make_property_entry_v8_property_attribute(
                entry.property_),
            location=_make_property_entry_location(entry.property_),
            world=_make_property_entry_world(entry.world),
            receiver_check=_make_property_entry_receiver_check(
                entry.property_),
            cross_origin_check=_make_property_entry_cross_origin_check(
                entry.property_),
            v8_side_effect=_make_property_entry_v8_side_effect(
                entry.property_),
            v8_c_function=_make_property_entry_v8_c_function(entry))
        entry_nodes.append(T(text))

    table_decl_before_name = (
        "static const IDLMemberInstaller::OperationConfig")
    if no_alloc_direct_call_enabled:
        table_decl_before_name = (
            "static const "
            "IDLMemberInstaller::NoAllocDirectCallOperationConfig")
    return ListNode([
        T(table_decl_before_name + " " + table_name + "[] = {"),
        ListNode(entry_nodes),
        T("};"),
    ])


class _PropEntryBase(object):
    def __init__(self, is_context_dependent, exposure_conditional, world,
                 property_):
        assert isinstance(is_context_dependent, bool)
        assert isinstance(exposure_conditional, CodeGenExpr)

        self.is_context_dependent = is_context_dependent
        self.exposure_conditional = exposure_conditional
        self.world = world
        self.property_ = property_


class _PropEntryAttribute(_PropEntryBase):
    def __init__(self, is_context_dependent, exposure_conditional, world,
                 attribute, attr_get_callback_name, attr_set_callback_name):
        assert isinstance(attr_get_callback_name, str)
        assert _is_none_or_str(attr_set_callback_name)

        _PropEntryBase.__init__(self, is_context_dependent,
                                exposure_conditional, world, attribute)
        self.attr_get_callback_name = attr_get_callback_name
        self.attr_set_callback_name = attr_set_callback_name


class _PropEntryConstant(_PropEntryBase):
    def __init__(self, is_context_dependent, exposure_conditional, world,
                 constant, const_callback_name, const_constant_name):
        assert _is_none_or_str(const_callback_name)
        assert isinstance(const_constant_name, str)

        _PropEntryBase.__init__(self, is_context_dependent,
                                exposure_conditional, world, constant)
        self.const_callback_name = const_callback_name
        self.const_constant_name = const_constant_name


class _PropEntryConstructorGroup(_PropEntryBase):
    def __init__(self, is_context_dependent, exposure_conditional, world,
                 constructor_group, ctor_callback_name, ctor_func_length):
        assert isinstance(ctor_callback_name, str)
        assert isinstance(ctor_func_length, int)

        _PropEntryBase.__init__(self, is_context_dependent,
                                exposure_conditional, world, constructor_group)
        self.ctor_callback_name = ctor_callback_name
        self.ctor_func_length = ctor_func_length


class _PropEntryExposedConstruct(_PropEntryBase):
    def __init__(self, is_context_dependent, exposure_conditional, world,
                 exposed_construct, prop_callback_name):
        assert isinstance(prop_callback_name, str)

        _PropEntryBase.__init__(self, is_context_dependent,
                                exposure_conditional, world, exposed_construct)
        self.prop_callback_name = prop_callback_name


class _PropEntryOperationGroup(_PropEntryBase):
    def __init__(self,
                 is_context_dependent,
                 exposure_conditional,
                 world,
                 operation_group,
                 op_callback_name,
                 op_func_length,
                 no_alloc_direct_callback_name=None):
        assert isinstance(op_callback_name, str)
        assert isinstance(op_func_length, int)

        _PropEntryBase.__init__(self, is_context_dependent,
                                exposure_conditional, world, operation_group)
        self.op_callback_name = op_callback_name
        self.op_func_length = op_func_length
        self.no_alloc_direct_callback_name = no_alloc_direct_callback_name


def make_property_entries_and_callback_defs(cg_context, attribute_entries,
                                            constant_entries,
                                            constructor_entries,
                                            exposed_construct_entries,
                                            operation_entries):
    """
    Creates intermediate objects to help property installation and also makes
    code nodes of callback functions.

    Args:
        attribute_entries:
        constructor_entries:
        exposed_construct_entries:
        operation_entries:
            Output parameters to store the intermediate objects.
    """
    assert isinstance(cg_context, CodeGenContext)
    assert isinstance(attribute_entries, list)
    assert isinstance(constant_entries, list)
    assert isinstance(constructor_entries, list)
    assert isinstance(exposed_construct_entries, list)
    assert isinstance(operation_entries, list)

    class_like = cg_context.class_like
    interface = cg_context.interface
    global_names = class_like.extended_attributes.values_of("Global")

    callback_def_nodes = ListNode()

    def iterate(members, callback):
        for member in members:
            is_context_dependent = member.exposure.is_context_dependent(
                global_names)
            exposure_conditional = expr_from_exposure(
                member.exposure,
                global_names=global_names,
                may_use_feature_selector=True)

            if "PerWorldBindings" in member.extended_attributes:
                worlds = (CodeGenContext.MAIN_WORLD,
                          CodeGenContext.NON_MAIN_WORLDS)
            else:
                worlds = (CodeGenContext.ALL_WORLDS, )

            for world in worlds:
                callback(member, is_context_dependent, exposure_conditional,
                         world)

    def process_attribute(attribute, is_context_dependent,
                          exposure_conditional, world):
        if "CSSProperty" in attribute.extended_attributes:
            return  # [CSSProperty] will be installed in a special manner.

        cgc_attr = cg_context.make_copy(attribute=attribute, for_world=world)
        cgc = cgc_attr.make_copy(attribute_get=True)
        attr_get_callback_name = callback_function_name(cgc)
        attr_get_callback_node = make_attribute_get_callback_def(
            cgc, attr_get_callback_name)
        cgc = cgc_attr.make_copy(attribute_set=True)
        attr_set_callback_name = callback_function_name(cgc)
        attr_set_callback_node = make_attribute_set_callback_def(
            cgc, attr_set_callback_name)
        if attr_set_callback_node is None:
            attr_set_callback_name = None

        callback_def_nodes.extend([
            attr_get_callback_node,
            EmptyNode(),
            attr_set_callback_node,
            EmptyNode(),
        ])

        attribute_entries.append(
            _PropEntryAttribute(
                is_context_dependent=is_context_dependent,
                exposure_conditional=exposure_conditional,
                world=world,
                attribute=attribute,
                attr_get_callback_name=attr_get_callback_name,
                attr_set_callback_name=attr_set_callback_name))

    def process_constant(constant, is_context_dependent, exposure_conditional,
                         world):
        cgc = cg_context.make_copy(
            constant=constant,
            for_world=world,
            v8_callback_type=CodeGenContext.V8_ACCESSOR_NAME_GETTER_CALLBACK)
        const_callback_name = callback_function_name(cgc)
        const_callback_node = make_constant_callback_def(
            cgc, const_callback_name)
        if const_callback_node is None:
            const_callback_name = None
        # IDL constant's C++ constant name
        const_constant_name = _format("${class_name}::Constant::{}",
                                      constant_name(cgc))

        callback_def_nodes.extend([
            const_callback_node,
            EmptyNode(),
        ])

        constant_entries.append(
            _PropEntryConstant(
                is_context_dependent=is_context_dependent,
                exposure_conditional=exposure_conditional,
                world=world,
                constant=constant,
                const_callback_name=const_callback_name,
                const_constant_name=const_constant_name))

    def process_constructor_group(constructor_group, is_context_dependent,
                                  exposure_conditional, world):
        cgc = cg_context.make_copy(
            constructor_group=constructor_group, for_world=world)
        ctor_callback_name = callback_function_name(cgc)
        ctor_callback_node = make_constructor_callback_def(
            cgc, ctor_callback_name)

        callback_def_nodes.extend([
            ctor_callback_node,
            EmptyNode(),
        ])

        constructor_entries.append(
            _PropEntryConstructorGroup(
                is_context_dependent=is_context_dependent,
                exposure_conditional=exposure_conditional,
                world=world,
                constructor_group=constructor_group,
                ctor_callback_name=ctor_callback_name,
                ctor_func_length=(
                    constructor_group.min_num_of_required_arguments)))

    def process_exposed_construct(exposed_construct, is_context_dependent,
                                  exposure_conditional, world):
        if isinstance(exposed_construct, web_idl.LegacyWindowAlias):
            cgc = cg_context.make_copy(
                exposed_construct=exposed_construct.original,
                legacy_window_alias=exposed_construct,
                for_world=world,
                v8_callback_type=CodeGenContext.
                V8_ACCESSOR_NAME_GETTER_CALLBACK)
        elif ("LegacyNoInterfaceObject" in
              exposed_construct.extended_attributes):
            return  # Skip due to [LegacyNoInterfaceObject].
        else:
            cgc = cg_context.make_copy(
                exposed_construct=exposed_construct,
                for_world=world,
                v8_callback_type=CodeGenContext.
                V8_ACCESSOR_NAME_GETTER_CALLBACK)
        prop_callback_name = callback_function_name(cgc)
        prop_callback_node = make_exposed_construct_callback_def(
            cgc, prop_callback_name)

        callback_def_nodes.extend([
            prop_callback_node,
            EmptyNode(),
        ])

        exposed_construct_entries.append(
            _PropEntryExposedConstruct(
                is_context_dependent=is_context_dependent,
                exposure_conditional=exposure_conditional,
                world=world,
                exposed_construct=exposed_construct,
                prop_callback_name=prop_callback_name))

    def process_named_constructor_group(named_constructor_group,
                                        is_context_dependent,
                                        exposure_conditional, world):
        cgc = cg_context.make_copy(
            exposed_construct=named_constructor_group,
            is_named_constructor=True,
            for_world=world,
            v8_callback_type=CodeGenContext.V8_ACCESSOR_NAME_GETTER_CALLBACK)
        prop_callback_name = callback_function_name(cgc)
        prop_callback_node = make_named_constructor_property_callback_def(
            cgc, prop_callback_name)

        callback_def_nodes.extend([
            prop_callback_node,
            EmptyNode(),
        ])

        exposed_construct_entries.append(
            _PropEntryExposedConstruct(
                is_context_dependent=is_context_dependent,
                exposure_conditional=exposure_conditional,
                world=world,
                exposed_construct=named_constructor_group,
                prop_callback_name=prop_callback_name))

    def process_operation_group(operation_group, is_context_dependent,
                                exposure_conditional, world):
        cgc = cg_context.make_copy(
            operation_group=operation_group, for_world=world)
        op_callback_name = callback_function_name(cgc)
        no_alloc_direct_callback_name = (
            callback_function_name(cgc, no_alloc_direct_call=True)
            if "NoAllocDirectCall" in operation_group.extended_attributes else
            None)
        op_callback_node = make_operation_callback_def(
            cgc,
            op_callback_name,
            no_alloc_direct_callback_name=no_alloc_direct_callback_name)

        callback_def_nodes.extend([
            op_callback_node,
            EmptyNode(),
        ])

        operation_entries.append(
            _PropEntryOperationGroup(
                is_context_dependent=is_context_dependent,
                exposure_conditional=exposure_conditional,
                world=world,
                operation_group=operation_group,
                op_callback_name=op_callback_name,
                op_func_length=operation_group.min_num_of_required_arguments,
                no_alloc_direct_callback_name=no_alloc_direct_callback_name))

    def process_stringifier(_, is_context_dependent, exposure_conditional,
                            world):
        cgc = cg_context.make_copy(
            stringifier=interface.stringifier, for_world=world)
        op_callback_name = callback_function_name(cgc)
        op_callback_node = make_stringifier_callback_def(cgc, op_callback_name)

        callback_def_nodes.extend([
            op_callback_node,
            EmptyNode(),
        ])

        operation_entries.append(
            _PropEntryOperationGroup(
                is_context_dependent=is_context_dependent,
                exposure_conditional=exposure_conditional,
                world=world,
                operation_group=cgc.property_,
                op_callback_name=op_callback_name,
                op_func_length=0))

    iterate(class_like.attributes, process_attribute)
    iterate(class_like.constants, process_constant)
    if interface:
        iterate(interface.constructor_groups, process_constructor_group)
        iterate(interface.exposed_constructs, process_exposed_construct)
        iterate(interface.legacy_window_aliases, process_exposed_construct)
        named_constructor_groups = [
            group for construct in interface.exposed_constructs
            for group in construct.named_constructor_groups
            if construct.named_constructor_groups
        ]
        iterate(named_constructor_groups, process_named_constructor_group)
    if not class_like.is_callback_interface:
        iterate(class_like.operation_groups, process_operation_group)
    if interface and interface.stringifier:
        iterate([interface.stringifier.operation], process_stringifier)
    collectionlike = interface and (interface.iterable or interface.maplike
                                    or interface.setlike)
    if collectionlike:

        def should_define(target):
            if not target[0].is_optionally_defined:
                return True
            return all(target.identifier != member.identifier
                       for member in itertools.chain(
                           interface.attributes, interface.constants,
                           interface.operation_groups))

        iterate(collectionlike.attributes, process_attribute)
        iterate(
            filter(should_define, collectionlike.operation_groups),
            process_operation_group)

    return callback_def_nodes


def _make_install_prototype_object(cg_context):
    assert isinstance(cg_context, CodeGenContext)

    nodes = []

    class_like = cg_context.class_like
    interface = cg_context.interface

    unscopables = []
    is_unscopable = lambda member: "Unscopable" in member.extended_attributes
    unscopables.extend(filter(is_unscopable, class_like.attributes))
    unscopables.extend(filter(is_unscopable, class_like.operations))
    if unscopables:
        nodes.extend([
            TextNode("""\
// [Unscopable]
// 3.7.3. Interface prototype object
// https://heycam.github.io/webidl/#interface-prototype-object
// step 10. If interface has any member declared with the [Unscopable]
//   extended attribute, then:\
"""),
            ListNode([
                TextNode("static constexpr const char* "
                         "kUnscopablePropertyNames[] = {"),
                ListNode([
                    TextNode("\"{}\", ".format(member.identifier))
                    for member in unscopables
                ]),
                TextNode("};"),
            ]),
            TextNode("""\
bindings::InstallUnscopablePropertyNames(
    ${isolate}, ${v8_context}, ${prototype_object}, kUnscopablePropertyNames);
"""),
        ])

    if "LegacyNoInterfaceObject" in class_like.extended_attributes:
        nodes.append(
            TextNode("""\
// [LegacyNoInterfaceObject]
// 3.7.3. Interface prototype object
// https://heycam.github.io/webidl/#interface-prototype-object
// step 13. If the [LegacyNoInterfaceObject] extended attribute was not
//   specified on interface, then:
//
// V8 defines "constructor" property on the prototype object by default.
${prototype_object}->Delete(
    ${v8_context}, V8AtomicString(${isolate}, "constructor")).ToChecked();
"""))

    collectionlike = interface and (interface.iterable or interface.maplike
                                    or interface.setlike)
    if collectionlike:
        property_name = None
        for operation_group in collectionlike.operation_groups:
            if operation_group[0].is_iterator:
                property_name = operation_group.identifier
                break
        if property_name:
            pattern = """\
// @@iterator == "{property_name}"
{{
  v8::Local<v8::Value> v8_value = ${prototype_object}->Get(
      ${v8_context}, V8AtomicString(${isolate}, "{property_name}"))
      .ToLocalChecked();
  ${prototype_object}->DefineOwnProperty(
      ${v8_context}, v8::Symbol::GetIterator(${isolate}), v8_value,
      v8::DontEnum).ToChecked();
}}
"""
            nodes.append(
                TextNode(_format(pattern, property_name=property_name)))

    if class_like.identifier == "FileSystemDirectoryHandle":
        pattern = """\
// Temporary @@asyncIterator support for FileSystemDirectoryHandle
// TODO(https://crbug.com/1087157): Replace with proper bindings support.
// @@asyncIterator == "{property_name}"
{{
  v8::Local<v8::Value> v8_value = ${prototype_object}->Get(
      ${v8_context}, V8AtomicString(${isolate}, "{property_name}"))
      .ToLocalChecked();
  ${prototype_object}->DefineOwnProperty(
      ${v8_context}, v8::Symbol::GetAsyncIterator(${isolate}), v8_value,
      v8::DontEnum).ToChecked();
}}
"""
        nodes.append(TextNode(_format(pattern, property_name="entries")))

    if ("Global" in class_like.extended_attributes
            and class_like.indexed_and_named_properties
            and class_like.indexed_and_named_properties.has_named_properties):
        nodes.append(
            TextNode("""\
// https://heycam.github.io/webidl/#named-properties-object
// V8 defines "constructor" property on the prototype object by default.
// Named properties object is currently implemented as a prototype object
// (implemented with v8::FunctionTemplate::PrototypeTemplate()).
${prototype_object}->GetPrototype().As<v8::Object>()->Delete(
    ${v8_context}, V8AtomicString(${isolate}, "constructor")).ToChecked();
"""))

    return SequenceNode(nodes) if nodes else None


def make_install_interface_template(cg_context, function_name, class_name,
                                    trampoline_var_name, constructor_entries,
                                    supplemental_install_node,
                                    install_unconditional_func_name,
                                    install_context_independent_func_name):
    """
    Returns:
        A triplet of CodeNode of:
        - function declaration
        - function definition
        - trampoline function definition (from the API class to the
          implementation class), which is supposed to be defined inline
    """
    assert isinstance(cg_context, CodeGenContext)
    assert isinstance(function_name, str)
    assert _is_none_or_str(class_name)
    assert _is_none_or_str(trampoline_var_name)
    assert isinstance(constructor_entries, (list, tuple))
    assert all(
        isinstance(entry, _PropEntryConstructorGroup)
        for entry in constructor_entries)
    assert isinstance(supplemental_install_node, SequenceNode)
    assert _is_none_or_str(install_unconditional_func_name)
    assert _is_none_or_str(install_context_independent_func_name)

    T = TextNode

    class_like = cg_context.class_like
    interface = cg_context.interface

    arg_decls = [
        "v8::Isolate* isolate",
        "const DOMWrapperWorld& world",
        "v8::Local<v8::Template> interface_template",
    ]
    return_type = "void"

    if trampoline_var_name is None:
        trampoline_def = None
    else:
        trampoline_def = CxxFuncDefNode(
            name=function_name,
            arg_decls=arg_decls,
            return_type=return_type,
            static=True)
        trampoline_def.body.append(
            TextNode(
                _format("return {}(isolate, world, interface_template);",
                        trampoline_var_name)))

    func_decl = CxxFuncDeclNode(
        name=function_name,
        arg_decls=arg_decls,
        return_type=return_type,
        static=True)

    func_def = CxxFuncDefNode(
        name=function_name,
        arg_decls=arg_decls,
        return_type=return_type,
        class_name=class_name)
    func_def.set_base_template_vars(cg_context.template_bindings())

    body = func_def.body
    body.add_template_vars({
        "isolate": "isolate",
        "world": "world",
        "interface_template": "interface_template",
    })
    bind_installer_local_vars(body, cg_context)

    if cg_context.interface:
        body.extend([
            T("bindings::SetupIDLInterfaceTemplate("
              "${isolate}, ${wrapper_type_info}, "
              "${instance_object_template}, "
              "${prototype_object_template}, "
              "${interface_function_template}, "
              "${parent_interface_template});"),
            EmptyNode(),
        ])
    elif cg_context.namespace:
        body.extend([
            T("bindings::SetupIDLNamespaceTemplate("
              "${isolate}, ${wrapper_type_info}, "
              "${namespace_object_template});"),
            EmptyNode(),
        ])
    elif cg_context.callback_interface:
        body.extend([
            T("bindings::SetupIDLCallbackInterfaceTemplate("
              "${isolate}, ${wrapper_type_info}, "
              "${interface_function_template});"),
            EmptyNode(),
        ])
    else:
        assert False

    for entry in constructor_entries:
        set_callback = _format(
            "${interface_function_template}->SetCallHandler({});",
            entry.ctor_callback_name)
        set_length = _format("${interface_function_template}->SetLength({});",
                             entry.ctor_func_length)
        if entry.world == CodeGenContext.MAIN_WORLD:
            body.append(
                CxxLikelyIfNode(
                    cond="${world}.IsMainWorld()",
                    body=[T(set_callback), T(set_length)]))
        elif entry.world == CodeGenContext.NON_MAIN_WORLDS:
            body.append(
                CxxLikelyIfNode(
                    cond="!${world}.IsMainWorld()",
                    body=[T(set_callback), T(set_length)]))
        elif entry.world == CodeGenContext.ALL_WORLDS:
            body.extend([T(set_callback), T(set_length)])
        else:
            assert False
        body.append(EmptyNode())

    body.extend([
        supplemental_install_node,
        EmptyNode(),
    ])

    if class_like.identifier == "CSSStyleDeclaration":
        css_properties = list(
            filter(lambda attr: "CSSProperty" in attr.extended_attributes,
                   class_like.attributes))
        if css_properties:
            prop_name_list = "".join(
                map(lambda attr: "\"{}\", ".format(attr.identifier),
                    css_properties))
            body.append(
                T("""\
// CSSStyleDeclaration-specific settings
// [CSSProperty]
{
  static constexpr const char* kCssProperties[] = {
""" + prop_name_list + """
  };
  bindings::InstallCSSPropertyAttributes(
      ${isolate}, ${world},
      ${instance_template}, ${prototype_template}, ${interface_template},
      ${signature}, kCssProperties);
}
"""))

    if class_like.identifier == "DOMException":
        body.append(
            T("""\
// DOMException-specific settings
// https://heycam.github.io/webidl/#es-DOMException-specialness
{
  v8::Local<v8::FunctionTemplate> intrinsic_error_prototype_interface_template =
      v8::FunctionTemplate::New(${isolate}, nullptr, v8::Local<v8::Value>(),
                                v8::Local<v8::Signature>(), 0,
                                v8::ConstructorBehavior::kThrow);
  intrinsic_error_prototype_interface_template->SetIntrinsicDataProperty(
      V8AtomicString(${isolate}, "prototype"), v8::kErrorPrototype);
  ${interface_function_template}->Inherit(
      intrinsic_error_prototype_interface_template);
}
"""))

    if class_like.identifier == "FileSystemDirectoryIterator":
        body.append(
            T("""\
// Temporary @@asyncIterator support for FileSystemDirectoryHandle
// TODO(https://crbug.com/1087157): Replace with proper bindings support.
{
  v8::Local<v8::FunctionTemplate>
      intrinsic_iterator_prototype_interface_template =
      v8::FunctionTemplate::New(${isolate}, nullptr, v8::Local<v8::Value>(),
                                v8::Local<v8::Signature>(), 0,
                                v8::ConstructorBehavior::kThrow);
  intrinsic_iterator_prototype_interface_template->SetIntrinsicDataProperty(
      V8AtomicString(${isolate}, "prototype"), v8::kAsyncIteratorPrototype);
  ${interface_function_template}->Inherit(
      intrinsic_iterator_prototype_interface_template);
}
"""))

    if class_like.identifier == "HTMLAllCollection":
        body.append(
            T("""\
// HTMLAllCollection-specific settings
// https://html.spec.whatwg.org/C/#the-htmlallcollection-interface
${instance_object_template}->SetCallAsFunctionHandler(
    ${class_name}::LegacyCallCustom);
${instance_object_template}->MarkAsUndetectable();
"""))

    if class_like.identifier == "Iterator":
        body.append(
            T("""\
// Iterator-specific settings
// https://heycam.github.io/webidl/#es-iterator-prototype-object
{
  v8::Local<v8::FunctionTemplate>
      intrinsic_iterator_prototype_interface_template =
      v8::FunctionTemplate::New(${isolate}, nullptr, v8::Local<v8::Value>(),
                                v8::Local<v8::Signature>(), 0,
                                v8::ConstructorBehavior::kThrow);
  intrinsic_iterator_prototype_interface_template->SetIntrinsicDataProperty(
      V8AtomicString(${isolate}, "prototype"), v8::kIteratorPrototype);
  ${interface_function_template}->Inherit(
      intrinsic_iterator_prototype_interface_template);
}
"""))

    if class_like.identifier == "Location":
        body.append(
            T("""\
// Location-specific settings
// https://html.spec.whatwg.org/C/#the-location-interface
// To create a Location object, run these steps:
// step 3. Let valueOf be location's relevant
//   Realm.[[Intrinsics]].[[%ObjProto_valueOf%]].
// step 3. Perform ! location.[[DefineOwnProperty]]("valueOf",
//   { [[Value]]: valueOf, [[Writable]]: false, [[Enumerable]]: false,
//     [[Configurable]]: false }).
${instance_template}->SetIntrinsicDataProperty(
    V8AtomicString(${isolate}, "valueOf"),
    v8::kObjProto_valueOf,
    static_cast<v8::PropertyAttribute>(
        v8::ReadOnly | v8::DontEnum | v8::DontDelete));
// step 4. Perform ! location.[[DefineOwnProperty]](@@toPrimitive,
//   { [[Value]]: undefined, [[Writable]]: false, [[Enumerable]]: false,
//     [[Configurable]]: false }).
${instance_template}->Set(
    v8::Symbol::GetToPrimitive(${isolate}),
    v8::Undefined(${isolate}),
    static_cast<v8::PropertyAttribute>(
        v8::ReadOnly | v8::DontEnum | v8::DontDelete));
// 7.7.4.2 [[SetPrototypeOf]] ( V )
// https://html.spec.whatwg.org/C/#location-setprototypeof
${instance_object_template}->SetImmutableProto();
${prototype_object_template}->SetImmutableProto();
"""))

    if (interface and interface.indexed_and_named_properties
            and interface.indexed_and_named_properties.indexed_getter
            and "Global" not in interface.extended_attributes):
        body.append(
            T("""\
// @@iterator for indexed properties
// https://heycam.github.io/webidl/#define-the-iteration-methods
${prototype_template}->SetIntrinsicDataProperty(
    v8::Symbol::GetIterator(${isolate}), v8::kArrayProto_values, v8::DontEnum);
"""))
    if interface and interface.iterable and not interface.iterable.key_type:
        body.append(
            T("""\
// Value iterator's properties
// https://heycam.github.io/webidl/#define-the-iteration-methods
${prototype_template}->SetIntrinsicDataProperty(
    V8AtomicString(${isolate}, "entries"), v8::kArrayProto_entries, v8::None);
${prototype_template}->SetIntrinsicDataProperty(
    V8AtomicString(${isolate}, "keys"), v8::kArrayProto_keys, v8::None);
${prototype_template}->SetIntrinsicDataProperty(
    V8AtomicString(${isolate}, "values"), v8::kArrayProto_values, v8::None);
${prototype_template}->SetIntrinsicDataProperty(
    V8AtomicString(${isolate}, "forEach"), v8::kArrayProto_forEach, v8::None);
"""))

    if interface and "IsCodeLike" in interface.extended_attributes:
        body.append(
            CxxUnlikelyIfNode(
                cond="RuntimeEnabledFeatures::TrustedTypesUseCodeLikeEnabled()",
                body=[
                    TextNode("// [IsCodeLike]"),
                    TextNode("${instance_object_template}->SetCodeLike();"),
                ]))

    if "Global" in class_like.extended_attributes:
        body.append(
            TextNode("""\
// [Global]
// 3.7.1. [[SetPrototypeOf]]
// https://heycam.github.io/webidl/#platform-object-setprototypeof
${instance_object_template}->SetImmutableProto();
${prototype_object_template}->SetImmutableProto();
"""))
    elif interface and any("Global" in derived.extended_attributes
                           for derived in interface.deriveds):
        body.append(
            TextNode("""\
// [Global] - prototype object in the prototype chain of global objects
// 3.7.1. [[SetPrototypeOf]]
// https://heycam.github.io/webidl/#platform-object-setprototypeof
${prototype_object_template}->SetImmutableProto();
"""))

    func_call_pattern = ("{}(${isolate}, ${world}, ${instance_template}, "
                         "${prototype_template}, ${interface_template});")
    if install_unconditional_func_name:
        func_call = _format(func_call_pattern, install_unconditional_func_name)
        body.append(T(func_call))
    if install_context_independent_func_name:
        func_call = _format(func_call_pattern,
                            install_context_independent_func_name)
        body.append(T(func_call))

    return func_decl, func_def, trampoline_def


class PropInstallMode(object):
    class Mode(int):
        pass

    UNCONDITIONAL = Mode(0)
    CONTEXT_INDEPENDENT = Mode(1)
    CONTEXT_DEPENDENT = Mode(2)
    V8_CONTEXT_SNAPSHOT = Mode(3)


def make_install_properties(cg_context, function_name, class_name,
                            prop_install_mode, trampoline_var_name,
                            attribute_entries, constant_entries,
                            exposed_construct_entries, operation_entries):
    """
    Returns:
        A triplet of CodeNode of:
        - function declaration
        - function definition
        - trampoline function definition (from the API class to the
          implementation class), which is supposed to be defined inline
    """
    assert isinstance(cg_context, CodeGenContext)
    assert isinstance(function_name, str)
    assert _is_none_or_str(class_name)
    assert isinstance(prop_install_mode, PropInstallMode.Mode)
    assert _is_none_or_str(trampoline_var_name)
    assert isinstance(attribute_entries, (list, tuple))
    assert all(
        isinstance(entry, _PropEntryAttribute) for entry in attribute_entries)
    assert isinstance(constant_entries, (list, tuple))
    assert all(
        isinstance(entry, _PropEntryConstant) for entry in constant_entries)
    assert isinstance(exposed_construct_entries, (list, tuple))
    assert all(
        isinstance(entry, _PropEntryExposedConstruct)
        for entry in exposed_construct_entries)
    assert isinstance(operation_entries, (list, tuple))
    assert all(
        isinstance(entry, _PropEntryOperationGroup)
        for entry in operation_entries)

    if prop_install_mode == PropInstallMode.CONTEXT_DEPENDENT:
        install_prototype_object_node = _make_install_prototype_object(
            cg_context)
    else:
        install_prototype_object_node = None

    if not (attribute_entries or constant_entries or exposed_construct_entries
            or operation_entries or install_prototype_object_node):
        if prop_install_mode != PropInstallMode.V8_CONTEXT_SNAPSHOT:
            return None, None, None

    if prop_install_mode in (PropInstallMode.UNCONDITIONAL,
                             PropInstallMode.CONTEXT_INDEPENDENT):
        arg_decls = [
            "v8::Isolate* isolate",
            "const DOMWrapperWorld& world",
            "v8::Local<v8::Template> instance_template",
            "v8::Local<v8::Template> prototype_template",
            "v8::Local<v8::Template> interface_template",
        ]
        arg_names = [
            "isolate",
            "world",
            "instance_template",
            "prototype_template",
            "interface_template",
        ]
    elif prop_install_mode == PropInstallMode.CONTEXT_DEPENDENT:
        arg_decls = [
            "v8::Local<v8::Context> context",
            "const DOMWrapperWorld& world",
            "v8::Local<v8::Object> instance_object",
            "v8::Local<v8::Object> prototype_object",
            "v8::Local<v8::Object> interface_object",
            "v8::Local<v8::Template> interface_template",
            "FeatureSelector feature_selector",
        ]
        arg_names = [
            "context",
            "world",
            "instance_object",
            "prototype_object",
            "interface_object",
            "interface_template",
            "feature_selector",
        ]
    elif prop_install_mode == PropInstallMode.V8_CONTEXT_SNAPSHOT:
        arg_decls = [
            "v8::Local<v8::Context> context",
            "const DOMWrapperWorld& world",
            "v8::Local<v8::Object> instance_object",
            "v8::Local<v8::Object> prototype_object",
            "v8::Local<v8::Object> interface_object",
            "v8::Local<v8::Template> interface_template",
        ]
        arg_names = [
            "context",
            "world",
            "instance_object",
            "prototype_object",
            "interface_object",
            "interface_template",
        ]
    return_type = "void"

    is_per_context_install = (
        prop_install_mode in (PropInstallMode.CONTEXT_DEPENDENT,
                              PropInstallMode.V8_CONTEXT_SNAPSHOT))

    if trampoline_var_name is None:
        trampoline_def = None
    else:
        trampoline_def = CxxFuncDefNode(
            name=function_name,
            arg_decls=arg_decls,
            return_type=return_type,
            static=True)
        text = _format(
            "return {func}({args});",
            func=trampoline_var_name,
            args=", ".join(arg_names))
        trampoline_def.body.append(TextNode(text))

    func_decl = CxxFuncDeclNode(name=function_name,
                                arg_decls=arg_decls,
                                return_type=return_type,
                                static=bool(class_name))

    func_def = CxxFuncDefNode(
        name=function_name,
        arg_decls=arg_decls,
        return_type=return_type,
        class_name=class_name)
    func_def.set_base_template_vars(cg_context.template_bindings())

    body = func_def.body
    for arg_name in arg_names:
        if arg_name == "context":  # 'context' is reserved by Mako.
            body.add_template_var("v8_context", "context")
        else:
            body.add_template_var(arg_name, arg_name)
    bind_installer_local_vars(body, cg_context)

    body.extend([
        TextNode("using bindings::IDLMemberInstaller;"),
        EmptyNode(),
    ])

    if (is_per_context_install
            and "Global" in cg_context.class_like.extended_attributes):
        body.extend([
            CxxLikelyIfNode(cond="${instance_object}.IsEmpty()",
                            body=[
                                TextNode("""\
${instance_object} = ${v8_context}->Global()->GetPrototype().As<v8::Object>();\
"""),
                            ]),
            EmptyNode(),
        ])

    if install_prototype_object_node:
        body.extend([
            CxxLikelyIfNode(cond="${feature_selector}.IsAll()",
                            body=[install_prototype_object_node]),
            EmptyNode(),
        ])

    def group_by_condition(entries):
        unconditional_entries = []
        conditional_to_entries = {}
        for entry in entries:
            if entry.exposure_conditional.is_always_true:
                unconditional_entries.append(entry)
            else:
                conditional_to_entries.setdefault(entry.exposure_conditional,
                                                  []).append(entry)
        return unconditional_entries, conditional_to_entries

    def install_properties(table_name, target_entries, make_table_func,
                           installer_call_text):
        unconditional_entries, conditional_to_entries = group_by_condition(
            target_entries)
        if unconditional_entries:
            body.append(
                CxxBlockNode([
                    make_table_func(table_name, unconditional_entries),
                    TextNode(installer_call_text),
                ]))
            body.append(EmptyNode())
        for conditional, entries in conditional_to_entries.items():
            body.append(
                CxxUnlikelyIfNode(
                    cond=conditional,
                    body=[
                        make_table_func(table_name, entries),
                        TextNode(installer_call_text),
                    ]))
        body.append(EmptyNode())

    if is_per_context_install:
        pattern = ("{install_func}("
                   "${isolate}, ${world}, "
                   "${instance_object}, "
                   "${prototype_object}, "
                   "${interface_object}, "
                   "${signature}, {table_name});")
    else:
        pattern = ("{install_func}("
                   "${isolate}, ${world}, "
                   "${instance_template}, "
                   "${prototype_template}, "
                   "${interface_template}, "
                   "${signature}, {table_name});")

    table_name = "kAttributeTable"
    installer_call_text = _format(
        pattern,
        install_func="IDLMemberInstaller::InstallAttributes",
        table_name=table_name)
    install_properties(table_name, attribute_entries,
                       _make_attribute_registration_table, installer_call_text)

    table_name = "kConstantCallbackTable"
    installer_call_text = _format(
        pattern,
        install_func="IDLMemberInstaller::InstallConstants",
        table_name=table_name)
    constant_callback_entries = list(
        filter(lambda entry: entry.const_callback_name, constant_entries))
    install_properties(table_name, constant_callback_entries,
                       _make_constant_callback_registration_table,
                       installer_call_text)

    table_name = "kConstantValueTable"
    installer_call_text = _format(
        pattern,
        install_func="IDLMemberInstaller::InstallConstants",
        table_name=table_name)
    constant_value_entries = list(
        filter(lambda entry: not entry.const_callback_name, constant_entries))
    install_properties(table_name, constant_value_entries,
                       _make_constant_value_registration_table,
                       installer_call_text)

    table_name = "kExposedConstructTable"
    installer_call_text = _format(
        pattern,
        install_func="IDLMemberInstaller::InstallExposedConstructs",
        table_name=table_name)
    install_properties(table_name, exposed_construct_entries,
                       _make_exposed_construct_registration_table,
                       installer_call_text)

    table_name = "kOperationTable"
    installer_call_text = _format(
        pattern,
        install_func="IDLMemberInstaller::InstallOperations",
        table_name=table_name)
    entries = list(
        filter(lambda entry: not entry.no_alloc_direct_callback_name,
               operation_entries))
    install_properties(table_name, entries, _make_operation_registration_table,
                       installer_call_text)
    entries = list(
        filter(lambda entry: entry.no_alloc_direct_callback_name,
               operation_entries))
    install_properties(table_name, entries, _make_operation_registration_table,
                       installer_call_text)

    return func_decl, func_def, trampoline_def


def make_indexed_and_named_property_callbacks_and_install_node(cg_context):
    """
    Implements non-ordinary internal methods of legacy platform objects.
    https://heycam.github.io/webidl/#es-legacy-platform-objects

    Also implements the same origin case of indexed access to WindowProxy
    objects just same as indexed properties of legacy platform objects.
    https://html.spec.whatwg.org/C/#the-windowproxy-exotic-object
    """

    assert isinstance(cg_context, CodeGenContext)

    F = lambda *args, **kwargs: TextNode(_format(*args, **kwargs))

    func_decls = ListNode()
    func_defs = ListNode()
    install_node = SequenceNode()

    interface = cg_context.interface
    if not (interface and interface.indexed_and_named_properties
            and "Global" not in interface.extended_attributes):
        return func_decls, func_defs, install_node
    props = interface.indexed_and_named_properties

    def add_callback(func_decl, func_def):
        func_decls.append(func_decl)
        if func_def:
            func_defs.append(func_def)
            func_defs.append(EmptyNode())

    def most_derived_interface(*interfaces):
        key = lambda interface: len(interface.inclusive_inherited_interfaces)
        return sorted(filter(None, interfaces), key=key)[-1]

    cg_context = cg_context.make_copy(
        v8_callback_type=CodeGenContext.V8_OTHER_CALLBACK)

    if props.own_named_getter:
        add_callback(*make_named_property_getter_callback(
            cg_context.make_copy(named_property_getter=props.named_getter),
            "NamedPropertyGetterCallback"))
        add_callback(*make_named_property_setter_callback(
            cg_context.make_copy(named_property_setter=props.named_setter),
            "NamedPropertySetterCallback"))
        add_callback(*make_named_property_deleter_callback(
            cg_context.make_copy(named_property_deleter=props.named_deleter),
            "NamedPropertyDeleterCallback"))
        add_callback(*make_named_property_definer_callback(
            cg_context, "NamedPropertyDefinerCallback"))
        add_callback(*make_named_property_descriptor_callback(
            cg_context, "NamedPropertyDescriptorCallback"))
        add_callback(*make_named_property_query_callback(
            cg_context, "NamedPropertyQueryCallback"))
        add_callback(*make_named_property_enumerator_callback(
            cg_context, "NamedPropertyEnumeratorCallback"))

    if props.named_getter:
        impl_bridge = v8_bridge_class_name(
            most_derived_interface(
                props.named_getter.owner, props.named_setter
                and props.named_setter.owner, props.named_deleter
                and props.named_deleter.owner))
        flags = ["v8::PropertyHandlerFlags::kOnlyInterceptStrings"]
        if "LegacyOverrideBuiltIns" not in interface.extended_attributes:
            flags.append("v8::PropertyHandlerFlags::kNonMasking")
        if (props.named_getter.extended_attributes.value_of("Affects") ==
                "Nothing"):
            flags.append("v8::PropertyHandlerFlags::kHasNoSideEffect")
        property_handler_flags = (
            "static_cast<v8::PropertyHandlerFlags>({})".format(" | ".join(
                map(lambda flag: "int32_t({})".format(flag), flags))))
        pattern = """\
// Named interceptors
${instance_object_template}->SetHandler(
    v8::NamedPropertyHandlerConfiguration(
        {impl_bridge}::NamedPropertyGetterCallback,
        {impl_bridge}::NamedPropertySetterCallback,
% if "NotEnumerable" not in \
interface.indexed_and_named_properties.named_getter.extended_attributes:
        {impl_bridge}::NamedPropertyQueryCallback,
% else:
        nullptr,  // query
% endif
        {impl_bridge}::NamedPropertyDeleterCallback,
% if "NotEnumerable" not in \
interface.indexed_and_named_properties.named_getter.extended_attributes:
        {impl_bridge}::NamedPropertyEnumeratorCallback,
% else:
        nullptr,  // enumerator
% endif
        {impl_bridge}::NamedPropertyDefinerCallback,
        {impl_bridge}::NamedPropertyDescriptorCallback,
        v8::Local<v8::Value>(),
        {property_handler_flags}));"""
        install_node.append(
            F(pattern,
              impl_bridge=impl_bridge,
              property_handler_flags=property_handler_flags))

    if props.own_indexed_getter or props.own_named_getter:
        add_callback(*make_indexed_property_getter_callback(
            cg_context.make_copy(indexed_property_getter=props.indexed_getter),
            "IndexedPropertyGetterCallback"))
        add_callback(*make_indexed_property_setter_callback(
            cg_context.make_copy(indexed_property_setter=props.indexed_setter),
            "IndexedPropertySetterCallback"))
        add_callback(*make_indexed_property_deleter_callback(
            cg_context, "IndexedPropertyDeleterCallback"))
        add_callback(*make_indexed_property_definer_callback(
            cg_context, "IndexedPropertyDefinerCallback"))
        add_callback(*make_indexed_property_descriptor_callback(
            cg_context, "IndexedPropertyDescriptorCallback"))
        add_callback(*make_indexed_property_enumerator_callback(
            cg_context, "IndexedPropertyEnumeratorCallback"))

    if props.indexed_getter or props.named_getter:
        impl_bridge = v8_bridge_class_name(
            most_derived_interface(
                props.indexed_getter and props.indexed_getter.owner,
                props.indexed_setter and props.indexed_setter.owner,
                props.named_getter and props.named_getter.owner,
                props.named_setter and props.named_setter.owner,
                props.named_deleter and props.named_deleter.owner))
        flags = []
        if (props.indexed_getter and props.indexed_getter.extended_attributes.
                value_of("Affects") == "Nothing"):
            flags.append("v8::PropertyHandlerFlags::kHasNoSideEffect")
        else:
            flags.append("v8::PropertyHandlerFlags::kNone")
        property_handler_flags = flags[0]
        pattern = """\
// Indexed interceptors
${instance_object_template}->SetHandler(
    v8::IndexedPropertyHandlerConfiguration(
        {impl_bridge}::IndexedPropertyGetterCallback,
        {impl_bridge}::IndexedPropertySetterCallback,
        nullptr,  // query
        {impl_bridge}::IndexedPropertyDeleterCallback,
% if interface.indexed_and_named_properties.indexed_getter:
        {impl_bridge}::IndexedPropertyEnumeratorCallback,
% else:
        nullptr,  // enumerator
% endif
        {impl_bridge}::IndexedPropertyDefinerCallback,
        {impl_bridge}::IndexedPropertyDescriptorCallback,
        v8::Local<v8::Value>(),
        {property_handler_flags}));"""
        install_node.append(
            F(pattern,
              impl_bridge=impl_bridge,
              property_handler_flags=property_handler_flags))

    func_defs.accumulate(
        CodeGenAccumulator.require_include_headers([
            "third_party/blink/renderer/bindings/core/v8/v8_set_return_value_for_core.h"
        ]))

    return func_decls, func_defs, install_node


def make_named_properties_object_callbacks_and_install_node(cg_context):
    """
    Implements non-ordinary internal methods of named properties objects.
    https://heycam.github.io/webidl/#named-properties-object
    """

    assert isinstance(cg_context, CodeGenContext)

    callback_defs = []
    install_node = SequenceNode()

    interface = cg_context.interface
    if not (interface and interface.indexed_and_named_properties
            and interface.indexed_and_named_properties.named_getter
            and "Global" in interface.extended_attributes):
        return callback_defs, install_node

    cg_context = cg_context.make_copy(
        v8_callback_type=CodeGenContext.V8_OTHER_CALLBACK)

    func_defs = [
        make_named_props_obj_named_getter_callback(
            cg_context, "NamedPropsObjNamedGetterCallback"),
        make_named_props_obj_named_deleter_callback(
            cg_context, "NamedPropsObjNamedDeleterCallback"),
        make_named_props_obj_named_definer_callback(
            cg_context, "NamedPropsObjNamedDefinerCallback"),
        make_named_props_obj_named_descriptor_callback(
            cg_context, "NamedPropsObjNamedDescriptorCallback"),
        make_named_props_obj_indexed_getter_callback(
            cg_context, "NamedPropsObjIndexedGetterCallback"),
        make_named_props_obj_indexed_deleter_callback(
            cg_context, "NamedPropsObjIndexedDeleterCallback"),
        make_named_props_obj_indexed_definer_callback(
            cg_context, "NamedPropsObjIndexedDefinerCallback"),
        make_named_props_obj_indexed_descriptor_callback(
            cg_context, "NamedPropsObjIndexedDescriptorCallback"),
    ]
    for func_def in func_defs:
        callback_defs.append(func_def)
        callback_defs.append(EmptyNode())

    text = """\
// Named interceptors
${npo_prototype_template}->SetHandler(
    v8::NamedPropertyHandlerConfiguration(
        NamedPropsObjNamedGetterCallback,
        nullptr,  // setter
        nullptr,  // query
        NamedPropsObjNamedDeleterCallback,
        nullptr,  // enumerator
        NamedPropsObjNamedDefinerCallback,
        NamedPropsObjNamedDescriptorCallback,
        v8::Local<v8::Value>(),
        static_cast<v8::PropertyHandlerFlags>(
            int32_t(v8::PropertyHandlerFlags::kNonMasking) |
            int32_t(v8::PropertyHandlerFlags::kOnlyInterceptStrings))));
// Indexed interceptors
${npo_prototype_template}->SetHandler(
    v8::IndexedPropertyHandlerConfiguration(
        NamedPropsObjIndexedGetterCallback,
        nullptr,  // setter
        nullptr,  // query
        NamedPropsObjIndexedDeleterCallback,
        nullptr,  // enumerator
        NamedPropsObjIndexedDefinerCallback,
        NamedPropsObjIndexedDescriptorCallback,
        v8::Local<v8::Value>(),
        v8::PropertyHandlerFlags::kNone));"""
    install_node.append(TextNode(text))

    return callback_defs, install_node


def make_cross_origin_property_callbacks_and_install_node(
        cg_context, attribute_entries, operation_entries):
    """
    Implements non-ordinary internal methods of WindowProxy and Location
    objects.
    https://html.spec.whatwg.org/C/#the-windowproxy-exotic-object
    https://html.spec.whatwg.org/C/#the-location-interface
    """

    assert isinstance(cg_context, CodeGenContext)

    callback_defs = []
    install_node = SequenceNode()

    CROSS_ORIGIN_INTERFACES = ("Window", "Location")
    if cg_context.class_like.identifier not in CROSS_ORIGIN_INTERFACES:
        return callback_defs, install_node
    props = cg_context.interface.indexed_and_named_properties

    entry_nodes = []
    for entry in attribute_entries:
        attribute = entry.property_
        if "CrossOrigin" not in attribute.extended_attributes:
            continue
        assert entry.world == CodeGenContext.ALL_WORLDS
        values = attribute.extended_attributes.values_of("CrossOrigin")
        get_func = "nullptr"
        set_func = "nullptr"
        get_value = "nullptr"
        set_value = "nullptr"
        if not values or "Getter" in values:
            get_func = entry.attr_get_callback_name
            cgc = cg_context.make_copy(
                attribute=attribute,
                attribute_get=True,
                v8_callback_type=(
                    CodeGenContext.V8_ACCESSOR_NAME_GETTER_CALLBACK))
            get_value = callback_function_name(cgc, for_cross_origin=True)
            func_def = make_attribute_get_callback_def(cgc, get_value)
            callback_defs.extend([func_def, EmptyNode()])
        if values and "Setter" in values:
            set_func = entry.attr_set_callback_name
            cgc = cg_context.make_copy(
                attribute=attribute,
                attribute_set=True,
                v8_callback_type=(
                    CodeGenContext.V8_GENERIC_NAMED_PROPERTY_SETTER_CALLBACK))
            set_value = callback_function_name(cgc, for_cross_origin=True)
            func_def = make_attribute_set_callback_def(cgc, set_value)
            callback_defs.extend([func_def, EmptyNode()])
        pattern = ("{{\"{property_name}\", "
                   "{get_func}, {set_func}, {get_value}, {set_value}}},")
        entry_nodes.append(
            TextNode(
                _format(
                    pattern,
                    property_name=attribute.identifier,
                    get_func=get_func,
                    set_func=set_func,
                    get_value=get_value,
                    set_value=set_value)))
    callback_defs.append(
        ListNode([
            TextNode("constexpr bindings::CrossOriginAttributeTableEntry "
                     "kCrossOriginAttributeTable[] = {"),
            ListNode(entry_nodes),
            TextNode("};"),
            EmptyNode(),
        ]))

    entry_nodes = []
    for entry in operation_entries:
        operation_group = entry.property_
        if "CrossOrigin" not in operation_group.extended_attributes:
            continue
        assert entry.world == CodeGenContext.ALL_WORLDS
        entry_nodes.append(
            TextNode(
                _format(
                    "{{\"{property_name}\", {op_callback}, {op_func_length}}},",
                    property_name=operation_group.identifier,
                    op_callback=entry.op_callback_name,
                    op_func_length=entry.op_func_length)))
    callback_defs.append(
        ListNode([
            TextNode("constexpr bindings::CrossOriginOperationTableEntry "
                     "kCrossOriginOperationTable[] = {"),
            ListNode(entry_nodes),
            TextNode("};"),
            EmptyNode(),
        ]))

    cg_context = cg_context.make_copy(
        v8_callback_type=CodeGenContext.V8_OTHER_CALLBACK)

    func_defs = [
        make_cross_origin_access_check_callback(
            cg_context, "CrossOriginAccessCheckCallback"),
        make_cross_origin_named_getter_callback(
            cg_context, "CrossOriginNamedGetterCallback"),
        make_cross_origin_named_setter_callback(
            cg_context, "CrossOriginNamedSetterCallback"),
        make_cross_origin_named_deleter_callback(
            cg_context, "CrossOriginNamedDeleterCallback"),
        make_cross_origin_named_definer_callback(
            cg_context, "CrossOriginNamedDefinerCallback"),
        make_cross_origin_named_descriptor_callback(
            cg_context, "CrossOriginNamedDescriptorCallback"),
        make_cross_origin_named_query_callback(
            cg_context, "CrossOriginNamedQueryCallback"),
        make_cross_origin_named_enumerator_callback(
            cg_context, "CrossOriginNamedEnumeratorCallback"),
        make_cross_origin_indexed_getter_callback(
            cg_context.make_copy(
                indexed_property_getter=(props and props.indexed_getter)),
            "CrossOriginIndexedGetterCallback"),
        make_cross_origin_indexed_setter_callback(
            cg_context, "CrossOriginIndexedSetterCallback"),
        make_cross_origin_indexed_deleter_callback(
            cg_context, "CrossOriginIndexedDeleterCallback"),
        make_cross_origin_indexed_definer_callback(
            cg_context, "CrossOriginIndexedDefinerCallback"),
        make_cross_origin_indexed_descriptor_callback(
            cg_context, "CrossOriginIndexedDescriptorCallback"),
        make_cross_origin_indexed_enumerator_callback(
            cg_context, "CrossOriginIndexedEnumeratorCallback"),
    ]
    for func_def in func_defs:
        callback_defs.append(func_def)
        callback_defs.append(EmptyNode())

    text = """\
// Cross origin properties
${instance_object_template}->SetAccessCheckCallbackAndHandler(
    CrossOriginAccessCheckCallback,
    v8::NamedPropertyHandlerConfiguration(
        CrossOriginNamedGetterCallback,
        CrossOriginNamedSetterCallback,
        CrossOriginNamedQueryCallback,
        CrossOriginNamedDeleterCallback,
        CrossOriginNamedEnumeratorCallback,
        CrossOriginNamedDefinerCallback,
        CrossOriginNamedDescriptorCallback,
        v8::Local<v8::Value>(),
        v8::PropertyHandlerFlags::kNone),
    v8::IndexedPropertyHandlerConfiguration(
        CrossOriginIndexedGetterCallback,
        CrossOriginIndexedSetterCallback,
        nullptr,  // query
        CrossOriginIndexedDeleterCallback,
        CrossOriginIndexedEnumeratorCallback,
        CrossOriginIndexedDefinerCallback,
        CrossOriginIndexedDescriptorCallback,
        v8::Local<v8::Value>(),
        v8::PropertyHandlerFlags::kNone),
    v8::External::New(
        ${isolate},
        const_cast<WrapperTypeInfo*>(${class_name}::GetWrapperTypeInfo())));
"""
    install_node.append(TextNode(text))
    install_node.accumulate(
        CodeGenAccumulator.require_include_headers([
            "third_party/blink/renderer/bindings/core/v8/binding_security.h",
            "third_party/blink/renderer/platform/bindings/v8_cross_origin_property_support.h",
        ]))

    if cg_context.interface.identifier != "Window":
        return callback_defs, install_node

    func_defs = [
        make_same_origin_indexed_getter_callback(
            cg_context.make_copy(
                indexed_property_getter=(props and props.indexed_getter)),
            "SameOriginIndexedGetterCallback"),
        make_same_origin_indexed_setter_callback(
            cg_context, "SameOriginIndexedSetterCallback"),
        make_same_origin_indexed_deleter_callback(
            cg_context, "SameOriginIndexedDeleterCallback"),
        make_same_origin_indexed_definer_callback(
            cg_context, "SameOriginIndexedDefinerCallback"),
        make_same_origin_indexed_descriptor_callback(
            cg_context, "SameOriginIndexedDescriptorCallback"),
        make_same_origin_indexed_enumerator_callback(
            cg_context, "SameOriginIndexedEnumeratorCallback"),
    ]
    for func_def in func_defs:
        callback_defs.append(func_def)
        callback_defs.append(EmptyNode())

    text = """\
// Same origin interceptors
${instance_object_template}->SetHandler(
    v8::IndexedPropertyHandlerConfiguration(
        SameOriginIndexedGetterCallback,
        SameOriginIndexedSetterCallback,
        nullptr,  // query
        SameOriginIndexedDeleterCallback,
        SameOriginIndexedEnumeratorCallback,
        SameOriginIndexedDefinerCallback,
        SameOriginIndexedDescriptorCallback,
        v8::Local<v8::Value>(),
        v8::PropertyHandlerFlags::kNone));
"""
    install_node.append(TextNode(text))

    return callback_defs, install_node


def make_cross_component_init(
        cg_context, function_name, class_name, has_unconditional_props,
        has_context_independent_props, has_context_dependent_props):
    """
    Returns:
        A triplet of CodeNode of:
        - function declaration
        - function definition
        - trampoline member variable definitions
    """
    assert isinstance(cg_context, CodeGenContext)
    assert isinstance(function_name, str)
    assert isinstance(class_name, str)
    assert isinstance(has_unconditional_props, bool)
    assert isinstance(has_context_independent_props, bool)
    assert isinstance(has_context_dependent_props, bool)

    T = TextNode
    F = lambda *args, **kwargs: T(_format(*args, **kwargs))

    def filter_four_trampolines(nodes):
        assert len(nodes) == 4
        flags = (True, has_unconditional_props, has_context_independent_props,
                 has_context_dependent_props)
        return [node for node, flag in zip(nodes, flags) if flag]

    trampoline_var_decls = ListNode(
        filter_four_trampolines([
            F("static InstallInterfaceTemplateFuncType {};",
              TP_INSTALL_INTERFACE_TEMPLATE),
            F("static InstallUnconditionalPropertiesFuncType {};",
              TP_INSTALL_UNCONDITIONAL_PROPS),
            F("static InstallContextIndependentPropertiesFuncType {};",
              TP_INSTALL_CONTEXT_INDEPENDENT_PROPS),
            F("static InstallContextDependentPropertiesFuncType {};",
              TP_INSTALL_CONTEXT_DEPENDENT_PROPS),
        ]))

    trampoline_var_defs = ListNode(
        filter_four_trampolines([
            F(("${class_name}::InstallInterfaceTemplateFuncType "
               "${class_name}::{} = nullptr;"), TP_INSTALL_INTERFACE_TEMPLATE),
            F(("${class_name}::InstallUnconditionalPropertiesFuncType "
               "${class_name}::{} = nullptr;"),
              TP_INSTALL_UNCONDITIONAL_PROPS),
            F(("${class_name}::InstallContextIndependentPropertiesFuncType "
               "${class_name}::{} = nullptr;"),
              TP_INSTALL_CONTEXT_INDEPENDENT_PROPS),
            F(("${class_name}::InstallContextDependentPropertiesFuncType "
               "${class_name}::{} = nullptr;"),
              TP_INSTALL_CONTEXT_DEPENDENT_PROPS),
        ]))
    trampoline_var_defs.set_base_template_vars(cg_context.template_bindings())

    func_decl = CxxFuncDeclNode(
        name=function_name, arg_decls=[], return_type="void", static=True)

    func_def = CxxFuncDefNode(
        name=function_name,
        arg_decls=[],
        return_type="void",
        class_name=class_name)
    func_def.set_base_template_vars(cg_context.template_bindings())

    body = func_def.body
    body.extend(
        filter_four_trampolines([
            F("${class_name}::{} = {};", TP_INSTALL_INTERFACE_TEMPLATE,
              FN_INSTALL_INTERFACE_TEMPLATE),
            F("${class_name}::{} = {};", TP_INSTALL_UNCONDITIONAL_PROPS,
              FN_INSTALL_UNCONDITIONAL_PROPS),
            F("${class_name}::{} = {};", TP_INSTALL_CONTEXT_INDEPENDENT_PROPS,
              FN_INSTALL_CONTEXT_INDEPENDENT_PROPS),
            F("${class_name}::{} = {};", TP_INSTALL_CONTEXT_DEPENDENT_PROPS,
              FN_INSTALL_CONTEXT_DEPENDENT_PROPS),
        ]))

    return func_decl, func_def, trampoline_var_decls, trampoline_var_defs


# ----------------------------------------------------------------------------
# WrapperTypeInfo
# ----------------------------------------------------------------------------


def make_wrapper_type_info(cg_context, function_name,
                           has_context_dependent_props):
    assert isinstance(cg_context, CodeGenContext)
    assert function_name == "GetWrapperTypeInfo"
    assert isinstance(has_context_dependent_props, bool)

    F = lambda *args, **kwargs: TextNode(_format(*args, **kwargs))

    func_def = CxxFuncDefNode(
        name=function_name,
        arg_decls=[],
        return_type="constexpr const WrapperTypeInfo*",
        static=True)
    func_def.set_base_template_vars(cg_context.template_bindings())
    func_def.body.append(TextNode("return &wrapper_type_info_;"))

    member_var_def = TextNode(
        "static const WrapperTypeInfo wrapper_type_info_;")

    wrapper_type_info_def = ListNode()
    wrapper_type_info_def.set_base_template_vars(
        cg_context.template_bindings())

    pattern = """\
// Construction of WrapperTypeInfo may require non-trivial initialization due
// to cross-component address resolution in order to load the pointer to the
// parent interface's WrapperTypeInfo.  We ignore this issue because the issue
// happens only on component builds and the official release builds
// (statically-linked builds) are never affected by this issue.
#if defined(COMPONENT_BUILD) && defined(WIN32) && defined(__clang__)
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wglobal-constructors"
#endif

const WrapperTypeInfo ${class_name}::wrapper_type_info_{{
    gin::kEmbedderBlink,
    ${class_name}::{install_interface_template_func},
    {install_context_dependent_func},
    "${{class_like.identifier}}",
    {wrapper_type_info_of_inherited},
    {wrapper_type_prototype},
    {wrapper_class_id},
    {active_script_wrappable_inheritance},
    {idl_definition_kind},
}};

#if defined(COMPONENT_BUILD) && defined(WIN32) && defined(__clang__)
#pragma clang diagnostic pop
#endif
"""
    class_like = cg_context.class_like
    if has_context_dependent_props:
        install_context_dependent_func = _format(
            "${class_name}::{}", FN_INSTALL_CONTEXT_DEPENDENT_PROPS)
    else:
        install_context_dependent_func = "nullptr"
    if class_like.is_interface and class_like.inherited:
        wrapper_type_info_of_inherited = "{}::GetWrapperTypeInfo()".format(
            v8_bridge_class_name(class_like.inherited))
    else:
        wrapper_type_info_of_inherited = "nullptr"
    if class_like.is_interface:
        wrapper_type_prototype = "WrapperTypeInfo::kWrapperTypeObjectPrototype"
    else:
        wrapper_type_prototype = "WrapperTypeInfo::kWrapperTypeNoPrototype"
    if class_like.is_interface and class_like.does_implement("Node"):
        wrapper_class_id = "WrapperTypeInfo::kNodeClassId"
    else:
        wrapper_class_id = "WrapperTypeInfo::kObjectClassId"
    if class_like.code_generator_info.is_active_script_wrappable:
        active_script_wrappable_inheritance = (
            "WrapperTypeInfo::kInheritFromActiveScriptWrappable")
    else:
        active_script_wrappable_inheritance = (
            "WrapperTypeInfo::kNotInheritFromActiveScriptWrappable")
    if class_like.is_interface:
        idl_definition_kind = "WrapperTypeInfo::kIdlInterface"
    elif class_like.is_namespace:
        idl_definition_kind = "WrapperTypeInfo::kIdlNamespace"
    elif class_like.is_callback_interface:
        idl_definition_kind = "WrapperTypeInfo::kIdlCallbackInterface"
    wrapper_type_info_def.append(
        F(pattern,
          install_interface_template_func=FN_INSTALL_INTERFACE_TEMPLATE,
          install_context_dependent_func=install_context_dependent_func,
          wrapper_type_info_of_inherited=wrapper_type_info_of_inherited,
          wrapper_type_prototype=wrapper_type_prototype,
          wrapper_class_id=wrapper_class_id,
          active_script_wrappable_inheritance=(
              active_script_wrappable_inheritance),
          idl_definition_kind=idl_definition_kind))

    if class_like.is_interface:
        blink_class = blink_class_name(class_like)
        pattern = """\
const WrapperTypeInfo& {blink_class}::wrapper_type_info_ =
    ${class_name}::wrapper_type_info_;
"""
        wrapper_type_info_def.append(F(pattern, blink_class=blink_class))

    if class_like.code_generator_info.is_active_script_wrappable:
        pattern = """\
// [ActiveScriptWrappable]
static_assert(
    std::is_base_of<ActiveScriptWrappableBase, {blink_class}>::value,
    "{blink_class} does not inherit from ActiveScriptWrappable<> despite "
    "the IDL has [ActiveScriptWrappable] extended attribute.");
static_assert(
    !std::is_same<decltype(&{blink_class}::HasPendingActivity),
                  decltype(&ScriptWrappable::HasPendingActivity)>::value,
    "{blink_class} is not overriding hasPendingActivity() despite "
    "the IDL has [ActiveScriptWrappable] extended attribute.");"""
    else:
        pattern = """\
// non-[ActiveScriptWrappable]
static_assert(
    !std::is_base_of<ActiveScriptWrappableBase, {blink_class}>::value,
    "{blink_class} inherits from ActiveScriptWrappable<> without "
    "[ActiveScriptWrappable] extended attribute.");
static_assert(
    std::is_same<decltype(&{blink_class}::HasPendingActivity),
                 decltype(&ScriptWrappable::HasPendingActivity)>::value,
    "{blink_class} is overriding hasPendingActivity() without "
    "[ActiveScriptWrappable] extended attribute.");"""
    if class_like.is_interface:
        wrapper_type_info_def.append(F(pattern, blink_class=blink_class))

    return func_def, member_var_def, wrapper_type_info_def


# ----------------------------------------------------------------------------
# V8 Context Snapshot
# ----------------------------------------------------------------------------


def make_v8_context_snapshot_api(cg_context, component, attribute_entries,
                                 constant_entries, constructor_entries,
                                 exposed_construct_entries, operation_entries,
                                 named_properties_object_callback_defs,
                                 cross_origin_property_callback_defs,
                                 install_context_independent_func_name):
    assert isinstance(cg_context, CodeGenContext)
    assert isinstance(component, web_idl.Component)

    if not cg_context.interface:
        return None, None

    derived_interfaces = cg_context.interface.deriveds
    derived_names = list(
        map(lambda interface: interface.identifier, derived_interfaces))
    derived_names.append(cg_context.interface.identifier)
    if not ("Window" in derived_names or "HTMLDocument" in derived_names):
        return None, None

    header_ns = CxxNamespaceNode(name_style.namespace("v8_context_snapshot"))
    source_ns = CxxNamespaceNode(name_style.namespace("v8_context_snapshot"))

    export_text = component_export(component, False)

    def add_func(func_decl, func_def):
        header_ns.body.extend([
            TextNode(export_text),
            func_decl,
            EmptyNode(),
        ])
        source_ns.body.extend([
            func_def,
            EmptyNode(),
        ])

    add_func(*_make_v8_context_snapshot_get_reference_table_function(
        cg_context, name_style.func("GetRefTableOf",
                                    cg_context.class_name), attribute_entries,
        constant_entries, constructor_entries, exposed_construct_entries,
        operation_entries, named_properties_object_callback_defs,
        cross_origin_property_callback_defs))

    add_func(*_make_v8_context_snapshot_install_props_per_context_function(
        cg_context, name_style.func("InstallPropsOf",
                                    cg_context.class_name), attribute_entries,
        constant_entries, exposed_construct_entries, operation_entries))

    add_func(*_make_v8_context_snapshot_install_props_per_isolate_function(
        cg_context, name_style.func("InstallPropsOf", cg_context.class_name),
        install_context_independent_func_name))

    return header_ns, source_ns


def _make_v8_context_snapshot_get_reference_table_function(
        cg_context, function_name, attribute_entries, constant_entries,
        constructor_entries, exposed_construct_entries, operation_entries,
        named_properties_object_callback_defs,
        cross_origin_property_callback_defs):
    callback_names = ["${class_name}::GetWrapperTypeInfo()"]

    for entry in attribute_entries:
        if entry.exposure_conditional.is_always_true:
            callback_names.append(entry.attr_get_callback_name)
            callback_names.append(entry.attr_set_callback_name)
    for entry in constant_entries:
        if entry.exposure_conditional.is_always_true:
            callback_names.append(entry.const_callback_name)
    for entry in constructor_entries:
        if entry.exposure_conditional.is_always_true:
            callback_names.append(entry.ctor_callback_name)
    for entry in exposed_construct_entries:
        if entry.exposure_conditional.is_always_true:
            callback_names.append(entry.prop_callback_name)
    for entry in operation_entries:
        if entry.exposure_conditional.is_always_true:
            callback_names.append(entry.op_callback_name)

    def collect_callbacks(node):
        if isinstance(node, CxxFuncDefNode):
            callback_names.append(node.function_name)
        elif hasattr(node, "__iter__"):
            for child_node in node:
                collect_callbacks(child_node)

    collect_callbacks(named_properties_object_callback_defs)
    collect_callbacks(cross_origin_property_callback_defs)

    entry_nodes = list(
        map(
            lambda name: TextNode("reinterpret_cast<intptr_t>({}),".format(name
                                                                           )),
            filter(None, callback_names)))
    table_node = ListNode([
        TextNode("static const intptr_t kReferenceTable[] = {"),
        ListNode(entry_nodes),
        TextNode("};"),
    ])

    func_decl = CxxFuncDeclNode(name=function_name,
                                arg_decls=[],
                                return_type="base::span<const intptr_t>")

    func_def = CxxFuncDefNode(name=function_name,
                              arg_decls=[],
                              return_type="base::span<const intptr_t>")
    func_def.set_base_template_vars(cg_context.template_bindings())
    body = func_def.body
    body.extend([table_node, TextNode("return kReferenceTable;")])

    return func_decl, func_def


def _make_v8_context_snapshot_install_props_per_context_function(
        cg_context, function_name, attribute_entries, constant_entries,
        exposed_construct_entries, operation_entries):
    def selector(entry):
        if entry.exposure_conditional.is_always_true:
            return False
        if entry.is_context_dependent:
            return False
        return True

    func_decl, func_def, _ = make_install_properties(
        cg_context,
        function_name,
        class_name=None,
        prop_install_mode=PropInstallMode.V8_CONTEXT_SNAPSHOT,
        trampoline_var_name=None,
        attribute_entries=list(filter(selector, attribute_entries)),
        constant_entries=list(filter(selector, constant_entries)),
        exposed_construct_entries=list(
            filter(selector, exposed_construct_entries)),
        operation_entries=list(filter(selector, operation_entries)))

    return func_decl, func_def


def _make_v8_context_snapshot_install_props_per_isolate_function(
        cg_context, function_name, install_context_independent_func_name):
    arg_decls = [
        "v8::Isolate* isolate",
        "const DOMWrapperWorld& world",
        "v8::Local<v8::Template> instance_template",
        "v8::Local<v8::Template> prototype_template",
        "v8::Local<v8::Template> interface_template",
    ]
    arg_names = [
        "isolate",
        "world",
        "instance_template",
        "prototype_template",
        "interface_template",
    ]
    return_type = "void"

    func_decl = CxxFuncDeclNode(name=function_name,
                                arg_decls=arg_decls,
                                return_type=return_type)
    func_def = CxxFuncDefNode(name=function_name,
                              arg_decls=arg_decls,
                              return_type=return_type)

    if not install_context_independent_func_name:
        return func_decl, func_def

    func_def.set_base_template_vars(cg_context.template_bindings())
    body = func_def.body
    for arg_name in arg_names:
        body.add_template_var(arg_name, arg_name)
    pattern = """\
return ${class_name}::{func}(
    ${isolate}, ${world},
    ${instance_template},
    ${prototype_template},
    ${interface_template});\
"""
    body.append(
        TextNode(_format(pattern, func=install_context_independent_func_name)))
    return func_decl, func_def


# ----------------------------------------------------------------------------
# Main functions
# ----------------------------------------------------------------------------


def _collect_include_headers(class_like):
    assert isinstance(class_like, (web_idl.Interface, web_idl.Namespace))

    headers = set(class_like.code_generator_info.blink_headers)

    def collect_from_idl_type(idl_type):
        idl_type.apply_to_all_composing_elements(add_include_headers)

    def add_include_headers(idl_type):
        # ScriptPromise doesn't require any header for the result type.
        if idl_type.is_promise:
            raise StopIteration(idl_type.syntactic_form)

        type_def_obj = idl_type.type_definition_object
        if type_def_obj is not None:
            if (type_def_obj.identifier in (
                    "OnErrorEventHandlerNonNull",
                    "OnBeforeUnloadEventHandlerNonNull")):
                raise StopIteration(idl_type.syntactic_form)

            headers.add(PathManager(type_def_obj).api_path(ext="h"))
            if type_def_obj.is_interface or type_def_obj.is_namespace:
                headers.add(PathManager(type_def_obj).blink_path(ext="h"))
            raise StopIteration(idl_type.syntactic_form)

        union_def_obj = idl_type.union_definition_object
        if union_def_obj is not None:
            headers.add(PathManager(union_def_obj).api_path(ext="h"))

    for attribute in class_like.attributes:
        collect_from_idl_type(attribute.idl_type)
    for constructor in class_like.constructors:
        for argument in constructor.arguments:
            collect_from_idl_type(argument.idl_type)
    for operation in class_like.operations:
        collect_from_idl_type(operation.return_type)
        for argument in operation.arguments:
            collect_from_idl_type(argument.idl_type)

    if class_like.is_interface:
        for exposed_construct in class_like.exposed_constructs:
            headers.add(PathManager(exposed_construct).api_path(ext="h"))
        for legacy_window_alias in class_like.legacy_window_aliases:
            headers.add(
                PathManager(legacy_window_alias.original).api_path(ext="h"))

    path_manager = PathManager(class_like)
    headers.discard(path_manager.api_path(ext="h"))
    headers.discard(path_manager.impl_path(ext="h"))

    # TODO(yukishiino): Window interface should be
    # [ImplementedAs=LocalDOMWindow] instead of [ImplementedAs=DOMWindow], and
    # [CrossOrigin] properties should be implemented specifically with
    # DOMWindow class.  Then, we'll have less hacks.
    if class_like.identifier == "Window":
        headers.add("third_party/blink/renderer/core/frame/local_dom_window.h")

    return headers


def generate_class_like(class_like):
    assert isinstance(class_like, (web_idl.Interface, web_idl.Namespace))

    path_manager = PathManager(class_like)
    api_component = path_manager.api_component
    impl_component = path_manager.impl_component
    is_cross_components = path_manager.is_cross_components
    for_testing = class_like.code_generator_info.for_testing

    # Class names
    api_class_name = v8_bridge_class_name(class_like)
    if is_cross_components:
        impl_class_name = "{}::Impl".format(api_class_name)
    else:
        impl_class_name = api_class_name

    interface = None
    namespace = None
    if class_like.is_interface:
        interface = class_like
        cg_context = CodeGenContext(interface=interface,
                                    class_name=api_class_name)
    elif class_like.is_namespace:
        namespace = class_like
        cg_context = CodeGenContext(namespace=namespace,
                                    class_name=api_class_name)

    # Filepaths
    api_header_path = path_manager.api_path(ext="h")
    api_source_path = path_manager.api_path(ext="cc")
    if is_cross_components:
        impl_header_path = path_manager.impl_path(ext="h")
        impl_source_path = path_manager.impl_path(ext="cc")

    # Root nodes
    api_header_node = ListNode(tail="\n")
    api_header_node.set_accumulator(CodeGenAccumulator())
    api_header_node.set_renderer(MakoRenderer())
    api_source_node = ListNode(tail="\n")
    api_source_node.set_accumulator(CodeGenAccumulator())
    api_source_node.set_renderer(MakoRenderer())
    if is_cross_components:
        impl_header_node = ListNode(tail="\n")
        impl_header_node.set_accumulator(CodeGenAccumulator())
        impl_header_node.set_renderer(MakoRenderer())
        impl_source_node = ListNode(tail="\n")
        impl_source_node.set_accumulator(CodeGenAccumulator())
        impl_source_node.set_renderer(MakoRenderer())
    else:
        impl_header_node = api_header_node
        impl_source_node = api_source_node

    # Namespaces
    api_header_blink_ns = CxxNamespaceNode(name_style.namespace("blink"))
    api_source_blink_ns = CxxNamespaceNode(name_style.namespace("blink"))
    if is_cross_components:
        impl_header_blink_ns = CxxNamespaceNode(name_style.namespace("blink"))
        impl_source_blink_ns = CxxNamespaceNode(name_style.namespace("blink"))
    else:
        impl_header_blink_ns = api_header_blink_ns
        impl_source_blink_ns = api_source_blink_ns

    # Class definitions
    api_class_def = CxxClassDefNode(
        cg_context.class_name,
        base_class_names=[
            _format("bindings::V8InterfaceBridge<${class_name}, {}>",
                    blink_class_name(class_like)),
        ],
        final=True,
        export=component_export(api_component, for_testing))
    api_class_def.set_base_template_vars(cg_context.template_bindings())
    api_class_def.bottom_section.append(
        TextNode("friend class {};".format(blink_class_name(class_like))))
    if is_cross_components:
        impl_class_def = CxxClassDefNode(impl_class_name,
                                         final=True,
                                         export=component_export(
                                             impl_component, for_testing))
        impl_class_def.set_base_template_vars(cg_context.template_bindings())
        api_class_def.public_section.extend([
            TextNode("// Cross-component implementation class"),
            TextNode("class Impl;"),
            EmptyNode(),
        ])
    else:
        impl_class_def = api_class_def

    # Constants
    constants_def = None
    if class_like.constants:
        constants_def = CxxClassDefNode(name="Constant", final=True)
        constants_def.top_section.append(TextNode("STATIC_ONLY(Constant);"))
        for constant in class_like.constants:
            cgc = cg_context.make_copy(constant=constant)
            constants_def.public_section.append(
                make_constant_constant_def(cgc, constant_name(cgc)))

    # Custom callback implementations
    custom_callback_impl_decls = ListNode()

    def add_custom_callback_impl_decl(**params):
        arg_decls = params.pop("arg_decls")
        name = params.pop("name", None)
        if name is None:
            name = custom_function_name(cg_context.make_copy(**params))
        custom_callback_impl_decls.append(
            CxxFuncDeclNode(
                name=name,
                arg_decls=arg_decls,
                return_type="void",
                static=True))

    if class_like.identifier == "HTMLAllCollection":
        add_custom_callback_impl_decl(
            name=name_style.func("LegacyCallCustom"),
            arg_decls=["const v8::FunctionCallbackInfo<v8::Value>&"])
    for attribute in class_like.attributes:
        custom_values = attribute.extended_attributes.values_of("Custom")
        is_cross_origin = "CrossOrigin" in attribute.extended_attributes
        cross_origin_values = attribute.extended_attributes.values_of(
            "CrossOrigin")
        if "Getter" in custom_values:
            add_custom_callback_impl_decl(
                attribute=attribute,
                attribute_get=True,
                arg_decls=["const v8::FunctionCallbackInfo<v8::Value>&"])
            if is_cross_origin and (not cross_origin_values
                                    or "Getter" in cross_origin_values):
                add_custom_callback_impl_decl(
                    attribute=attribute,
                    attribute_get=True,
                    arg_decls=["const v8::PropertyCallbackInfo<v8::Value>&"])
        if "Setter" in custom_values:
            add_custom_callback_impl_decl(
                attribute=attribute,
                attribute_set=True,
                arg_decls=[
                    "v8::Local<v8::Value>",
                    "const v8::FunctionCallbackInfo<v8::Value>&",
                ])
            if is_cross_origin and (not cross_origin_values
                                    or "Setter" in cross_origin_values):
                add_custom_callback_impl_decl(
                    attribute=attribute,
                    attribute_set=True,
                    arg_decls=[
                        "v8::Local<v8::Value>",
                        "const v8::PropertyCallbackInfo<void>&",
                    ])
    for operation_group in class_like.operation_groups:
        if "Custom" in operation_group.extended_attributes:
            add_custom_callback_impl_decl(
                operation_group=operation_group,
                arg_decls=["const v8::FunctionCallbackInfo<v8::Value>&"])
    if interface and interface.indexed_and_named_properties:
        props = interface.indexed_and_named_properties
        operation = props.own_named_getter
        if operation and "Custom" in operation.extended_attributes:
            add_custom_callback_impl_decl(
                named_property_getter=operation,
                arg_decls=[
                    "const AtomicString& property_name",
                    "const v8::PropertyCallbackInfo<v8::Value>&",
                ])
        operation = props.own_named_setter
        if operation and "Custom" in operation.extended_attributes:
            add_custom_callback_impl_decl(
                named_property_setter=operation,
                arg_decls=[
                    "const AtomicString& property_name",
                    "v8::Local<v8::Value> v8_property_value",
                    "const v8::PropertyCallbackInfo<v8::Value>&",
                ])
        operation = props.own_named_deleter
        if operation and "Custom" in operation.extended_attributes:
            add_custom_callback_impl_decl(
                named_property_deleter=operation,
                arg_decls=[
                    "const AtomicString& property_name",
                    "const v8::PropertyCallbackInfo<v8::Value>&",
                ])

    # Cross-component trampolines
    if is_cross_components:
        # tp_ = trampoline name
        tp_install_interface_template = TP_INSTALL_INTERFACE_TEMPLATE
        tp_install_unconditional_props = TP_INSTALL_UNCONDITIONAL_PROPS
        tp_install_context_independent_props = (
            TP_INSTALL_CONTEXT_INDEPENDENT_PROPS)
        tp_install_context_dependent_props = TP_INSTALL_CONTEXT_DEPENDENT_PROPS
    else:
        tp_install_interface_template = None
        tp_install_unconditional_props = None
        tp_install_context_independent_props = None
        tp_install_context_dependent_props = None

    # Callback functions
    attribute_entries = []
    constant_entries = []
    constructor_entries = []
    exposed_construct_entries = []
    operation_entries = []
    callback_defs = make_property_entries_and_callback_defs(
        cg_context,
        attribute_entries=attribute_entries,
        constant_entries=constant_entries,
        constructor_entries=constructor_entries,
        exposed_construct_entries=exposed_construct_entries,
        operation_entries=operation_entries)
    supplemental_install_node = SequenceNode()

    # Indexed and named properties
    # Shorten a function name to mitigate a style check error.
    f = make_indexed_and_named_property_callbacks_and_install_node
    (indexed_and_named_property_decls, indexed_and_named_property_defs,
     indexed_and_named_property_install_node) = f(cg_context)
    supplemental_install_node.append(indexed_and_named_property_install_node)
    supplemental_install_node.append(EmptyNode())

    # Named properties object
    (named_properties_object_callback_defs,
     named_properties_object_install_node) = (
         make_named_properties_object_callbacks_and_install_node(cg_context))
    callback_defs.extend(named_properties_object_callback_defs)
    supplemental_install_node.append(named_properties_object_install_node)
    supplemental_install_node.append(EmptyNode())

    # Cross origin properties
    (cross_origin_property_callback_defs,
     cross_origin_property_install_node) = (
         make_cross_origin_property_callbacks_and_install_node(
             cg_context, attribute_entries, operation_entries))
    callback_defs.extend(cross_origin_property_callback_defs)
    supplemental_install_node.append(cross_origin_property_install_node)
    supplemental_install_node.append(EmptyNode())

    # Installer functions
    is_unconditional = lambda entry: entry.exposure_conditional.is_always_true
    is_context_dependent = lambda entry: entry.is_context_dependent
    is_context_independent = (
        lambda e: not is_context_dependent(e) and not is_unconditional(e))
    (install_unconditional_props_decl, install_unconditional_props_def,
     install_unconditional_props_trampoline) = make_install_properties(
         cg_context,
         FN_INSTALL_UNCONDITIONAL_PROPS,
         class_name=impl_class_name,
         prop_install_mode=PropInstallMode.UNCONDITIONAL,
         trampoline_var_name=tp_install_unconditional_props,
         attribute_entries=list(filter(is_unconditional, attribute_entries)),
         constant_entries=list(filter(is_unconditional, constant_entries)),
         exposed_construct_entries=list(
             filter(is_unconditional, exposed_construct_entries)),
         operation_entries=list(filter(is_unconditional, operation_entries)))
    (install_context_independent_props_decl,
     install_context_independent_props_def,
     install_context_independent_props_trampoline) = make_install_properties(
         cg_context,
         FN_INSTALL_CONTEXT_INDEPENDENT_PROPS,
         class_name=impl_class_name,
         prop_install_mode=PropInstallMode.CONTEXT_INDEPENDENT,
         trampoline_var_name=tp_install_context_independent_props,
         attribute_entries=list(
             filter(is_context_independent, attribute_entries)),
         constant_entries=list(filter(is_context_independent,
                                      constant_entries)),
         exposed_construct_entries=list(
             filter(is_context_independent, exposed_construct_entries)),
         operation_entries=list(
             filter(is_context_independent, operation_entries)))
    (install_context_dependent_props_decl, install_context_dependent_props_def,
     install_context_dependent_props_trampoline) = make_install_properties(
         cg_context,
         FN_INSTALL_CONTEXT_DEPENDENT_PROPS,
         class_name=impl_class_name,
         prop_install_mode=PropInstallMode.CONTEXT_DEPENDENT,
         trampoline_var_name=tp_install_context_dependent_props,
         attribute_entries=list(filter(is_context_dependent,
                                       attribute_entries)),
         constant_entries=list(filter(is_context_dependent, constant_entries)),
         exposed_construct_entries=list(
             filter(is_context_dependent, exposed_construct_entries)),
         operation_entries=list(filter(is_context_dependent,
                                       operation_entries)))
    (install_interface_template_decl, install_interface_template_def,
     install_interface_template_trampoline) = make_install_interface_template(
         cg_context,
         FN_INSTALL_INTERFACE_TEMPLATE,
         class_name=impl_class_name,
         trampoline_var_name=tp_install_interface_template,
         constructor_entries=constructor_entries,
         supplemental_install_node=supplemental_install_node,
         install_unconditional_func_name=(install_unconditional_props_def
                                          and FN_INSTALL_UNCONDITIONAL_PROPS),
         install_context_independent_func_name=(
             install_context_independent_props_def
             and FN_INSTALL_CONTEXT_INDEPENDENT_PROPS))
    installer_function_decls = ListNode([
        install_interface_template_decl,
        install_unconditional_props_decl,
        install_context_independent_props_decl,
        install_context_dependent_props_decl,
    ])
    installer_function_defs = ListNode([
        install_interface_template_def,
        EmptyNode(),
        install_unconditional_props_def,
        EmptyNode(),
        install_context_independent_props_def,
        EmptyNode(),
        install_context_dependent_props_def,
    ])
    installer_function_trampolines = ListNode([
        install_interface_template_trampoline,
        install_unconditional_props_trampoline,
        install_context_independent_props_trampoline,
        install_context_dependent_props_trampoline,
    ])

    # WrapperTypeInfo
    (get_wrapper_type_info_def, wrapper_type_info_var_def,
     wrapper_type_info_init) = make_wrapper_type_info(
         cg_context,
         "GetWrapperTypeInfo",
         has_context_dependent_props=bool(
             install_context_dependent_props_decl))

    # Cross-component trampolines
    if is_cross_components:
        (cross_component_init_decl, cross_component_init_def,
         trampoline_var_decls,
         trampoline_var_defs) = make_cross_component_init(
             cg_context,
             "Init",
             class_name=impl_class_name,
             has_unconditional_props=bool(install_unconditional_props_decl),
             has_context_independent_props=bool(
                 install_context_independent_props_decl),
             has_context_dependent_props=bool(
                 install_context_dependent_props_decl))

    # V8 Context Snapshot
    (header_v8_context_snapshot_ns,
     source_v8_context_snapshot_ns) = make_v8_context_snapshot_api(
         cg_context, impl_component, attribute_entries, constant_entries,
         constructor_entries, exposed_construct_entries, operation_entries,
         named_properties_object_callback_defs,
         cross_origin_property_callback_defs,
         (install_context_independent_props_def
          and FN_INSTALL_CONTEXT_INDEPENDENT_PROPS))

    # Header part (copyright, include directives, and forward declarations)
    api_header_node.extend([
        make_copyright_header(),
        EmptyNode(),
        enclose_with_header_guard(
            ListNode([
                make_header_include_directives(api_header_node.accumulator),
                EmptyNode(),
                api_header_blink_ns,
            ]), name_style.header_guard(api_header_path)),
    ])
    api_header_blink_ns.body.extend([
        make_forward_declarations(api_header_node.accumulator),
        EmptyNode(),
    ])
    api_source_node.extend([
        make_copyright_header(),
        EmptyNode(),
        TextNode("#include \"{}\"".format(api_header_path)),
        EmptyNode(),
        make_header_include_directives(api_source_node.accumulator),
        EmptyNode(),
        api_source_blink_ns,
    ])
    api_source_blink_ns.body.extend([
        make_forward_declarations(api_source_node.accumulator),
        EmptyNode(),
    ])
    if is_cross_components:
        impl_header_node.extend([
            make_copyright_header(),
            EmptyNode(),
            enclose_with_header_guard(
                ListNode([
                    make_header_include_directives(
                        impl_header_node.accumulator),
                    EmptyNode(),
                    impl_header_blink_ns,
                ]), name_style.header_guard(impl_header_path)),
        ])
        impl_header_blink_ns.body.extend([
            make_forward_declarations(impl_header_node.accumulator),
            EmptyNode(),
        ])
        impl_source_node.extend([
            make_copyright_header(),
            EmptyNode(),
            TextNode("#include \"{}\"".format(impl_header_path)),
            EmptyNode(),
            make_header_include_directives(impl_source_node.accumulator),
            EmptyNode(),
            impl_source_blink_ns,
        ])
        impl_source_blink_ns.body.extend([
            make_forward_declarations(impl_source_node.accumulator),
            EmptyNode(),
        ])
    api_header_node.accumulator.add_include_headers([
        class_like.code_generator_info.blink_headers[0],
        component_export_header(api_component, for_testing),
        "third_party/blink/renderer/platform/bindings/v8_interface_bridge.h",
    ])
    if interface and interface.inherited:
        api_source_node.accumulator.add_include_headers(
            [PathManager(interface.inherited).api_path(ext="h")])
    if is_cross_components:
        impl_header_node.accumulator.add_include_headers([
            api_header_path,
            component_export_header(impl_component, for_testing),
        ])
    impl_source_node.accumulator.add_include_headers([
        "third_party/blink/renderer/bindings/core/v8/generated_code_helper.h",
        "third_party/blink/renderer/bindings/core/v8/native_value_traits_impl.h",
        "third_party/blink/renderer/bindings/core/v8/v8_set_return_value_for_core.h",
        "third_party/blink/renderer/platform/bindings/exception_messages.h",
        "third_party/blink/renderer/platform/bindings/idl_member_installer.h",
        "third_party/blink/renderer/platform/bindings/runtime_call_stats.h",
        "third_party/blink/renderer/platform/bindings/v8_binding.h",
    ])
    impl_source_node.accumulator.add_include_headers(
        _collect_include_headers(class_like))

    # Assemble the parts.
    api_header_blink_ns.body.extend([
        api_class_def,
        EmptyNode(),
    ])
    if is_cross_components:
        impl_header_blink_ns.body.extend([
            impl_class_def,
            EmptyNode(),
        ])

    if constants_def:
        api_class_def.public_section.extend([
            TextNode("// Constants"),
            constants_def,
            EmptyNode(),
        ])

    api_class_def.public_section.append(get_wrapper_type_info_def)
    api_class_def.public_section.append(EmptyNode())
    api_class_def.private_section.append(wrapper_type_info_var_def)
    api_class_def.private_section.append(EmptyNode())
    api_source_blink_ns.body.extend([
        wrapper_type_info_init,
        EmptyNode(),
    ])

    if is_cross_components:
        api_class_def.public_section.append(installer_function_trampolines)
        api_class_def.public_section.append(EmptyNode())
        api_class_def.private_section.extend([
            TextNode("// Cross-component trampolines"),
            trampoline_var_decls,
            EmptyNode(),
        ])
        api_source_blink_ns.body.extend([
            TextNode("// Cross-component trampolines"),
            trampoline_var_defs,
            EmptyNode(),
        ])
        impl_class_def.public_section.append(cross_component_init_decl)
        impl_class_def.private_section.append(installer_function_decls)
        impl_source_blink_ns.body.extend([
            cross_component_init_def,
            EmptyNode(),
        ])
    else:
        api_class_def.public_section.append(installer_function_decls)
        api_class_def.public_section.append(EmptyNode())

    if custom_callback_impl_decls:
        api_class_def.public_section.extend([
            TextNode("// Custom callback implementations"),
            custom_callback_impl_decls,
            EmptyNode(),
        ])

    if indexed_and_named_property_decls:
        api_class_def.public_section.extend([
            TextNode("// Indexed properties and named properties"),
            indexed_and_named_property_decls,
            EmptyNode(),
        ])
        api_source_blink_ns.body.extend([
            indexed_and_named_property_defs,
            EmptyNode(),
        ])

    impl_source_blink_ns.body.extend([
        CxxNamespaceNode(name="", body=callback_defs),
        EmptyNode(),
        installer_function_defs,
        EmptyNode(),
    ])

    if header_v8_context_snapshot_ns:
        impl_header_blink_ns.body.extend([
            CxxNamespaceNode(name=name_style.namespace("bindings"),
                             body=header_v8_context_snapshot_ns),
            EmptyNode(),
        ])
        impl_source_blink_ns.body.extend([
            CxxNamespaceNode(name=name_style.namespace("bindings"),
                             body=source_v8_context_snapshot_ns),
            EmptyNode(),
        ])

    # Write down to the files.
    write_code_node_to_file(api_header_node,
                            path_manager.gen_path_to(api_header_path))
    write_code_node_to_file(api_source_node,
                            path_manager.gen_path_to(api_source_path))
    if path_manager.is_cross_components:
        write_code_node_to_file(impl_header_node,
                                path_manager.gen_path_to(impl_header_path))
        write_code_node_to_file(impl_source_node,
                                path_manager.gen_path_to(impl_source_path))


def generate_interface(interface_identifier):
    assert isinstance(interface_identifier, web_idl.Identifier)

    web_idl_database = package_initializer().web_idl_database()
    interface = web_idl_database.find(interface_identifier)

    generate_class_like(interface)


def generate_install_properties_per_feature(function_name,
                                            filepath_basename,
                                            for_testing=False):
    assert isinstance(function_name, str)
    assert isinstance(filepath_basename, str)
    assert isinstance(for_testing, bool)

    web_idl_database = package_initializer().web_idl_database()

    # Filepaths
    header_path = PathManager.component_path("modules",
                                             "{}.h".format(filepath_basename))
    source_path = PathManager.component_path("modules",
                                             "{}.cc".format(filepath_basename))

    # Root nodes
    header_node = ListNode(tail="\n")
    header_node.set_accumulator(CodeGenAccumulator())
    header_node.set_renderer(MakoRenderer())
    source_node = ListNode(tail="\n")
    source_node.set_accumulator(CodeGenAccumulator())
    source_node.set_renderer(MakoRenderer())

    # Namespaces
    header_blink_ns = CxxNamespaceNode(name_style.namespace("blink"))
    source_blink_ns = CxxNamespaceNode(name_style.namespace("blink"))
    header_bindings_ns = CxxNamespaceNode(name_style.namespace("bindings"))
    source_bindings_ns = CxxNamespaceNode(name_style.namespace("bindings"))
    header_blink_ns.body.extend([
        make_forward_declarations(header_node.accumulator),
        EmptyNode(),
        header_bindings_ns,
    ])
    source_blink_ns.body.append(source_bindings_ns)

    # Function nodes
    arg_decls = [
        "ScriptState* script_state",
        "OriginTrialFeature feature",
    ]
    func_decl = CxxFuncDeclNode(
        name=function_name, arg_decls=arg_decls, return_type="void")
    func_def = CxxFuncDefNode(
        name=function_name, arg_decls=arg_decls, return_type="void")
    func_def.body.add_template_vars({
        "script_state": "script_state",
        "feature": "feature",
    })
    helper_func_def = CxxFuncDefNode(
        name="InstallPropertiesPerFeatureInternal",
        arg_decls=[
            "ScriptState* script_state",
            "OriginTrialFeature feature",
            "base::span<const WrapperTypeInfo* const> wrapper_type_info_list",
        ],
        return_type="void")

    # Assemble the parts.
    header_node.accumulator.add_class_decls(["ScriptState"])
    header_node.accumulator.add_include_headers([
        "third_party/blink/renderer/platform/runtime_enabled_features.h",
    ])
    header_node.extend([
        make_copyright_header(),
        EmptyNode(),
        enclose_with_header_guard(
            ListNode([
                make_header_include_directives(header_node.accumulator),
                EmptyNode(),
                header_blink_ns,
            ]), name_style.header_guard(header_path)),
    ])
    source_node.accumulator.add_include_headers([
        "base/containers/span.h",
        "third_party/blink/renderer/platform/bindings/script_state.h",
        "third_party/blink/renderer/platform/bindings/v8_per_context_data.h",
    ])
    source_node.extend([
        make_copyright_header(),
        EmptyNode(),
        TextNode("#include \"{}\"".format(header_path)),
        EmptyNode(),
        make_header_include_directives(source_node.accumulator),
        EmptyNode(),
        source_blink_ns,
    ])
    header_bindings_ns.body.extend([
        TextNode("""\
// Install ES properties associated with the given origin trial feature.\
"""),
        func_decl,
    ])
    source_bindings_ns.body.extend([
        CxxNamespaceNode(name="", body=helper_func_def),
        EmptyNode(),
        func_def,
    ])

    # The public function
    feature_to_class_likes = {}
    set_of_class_likes = set()
    for class_like in itertools.chain(web_idl_database.interfaces,
                                      web_idl_database.namespaces):
        if class_like.code_generator_info.for_testing != for_testing:
            continue

        for member in itertools.chain(class_like.attributes,
                                      class_like.constants,
                                      class_like.operation_groups,
                                      class_like.exposed_constructs):
            features = list(
                member.exposure.context_dependent_runtime_enabled_features)
            for entry in member.exposure.global_names_and_features:
                if entry.feature and entry.feature.is_context_dependent:
                    features.append(entry.feature)
            for feature in features:
                feature_to_class_likes.setdefault(feature,
                                                  set()).add(class_like)
            if features:
                set_of_class_likes.add(class_like)

    switch_node = CxxSwitchNode(cond="${feature}")
    switch_node.append(
        case=None,
        body=[
            TextNode("// Ignore unknown, deprecated, and unused features."),
            TextNode("return;"),
        ],
        should_add_break=False)
    for feature, class_likes in sorted(feature_to_class_likes.items()):
        entries = [
            TextNode("{}::GetWrapperTypeInfo(), ".format(
                v8_bridge_class_name(class_like)))
            for class_like in sorted(class_likes, key=lambda x: x.identifier)
        ]
        table_def = ListNode([
            TextNode("static const WrapperTypeInfo* const wti_list[] = {"),
            ListNode(entries),
            TextNode("};"),
        ])
        switch_node.append(
            case="OriginTrialFeature::k{}".format(feature),
            body=[
                table_def,
                TextNode("selected_wti_list = wti_list;"),
            ])

    func_def.body.extend([
        TextNode(
            "base::span<const WrapperTypeInfo* const> selected_wti_list;"),
        EmptyNode(),
        switch_node,
        EmptyNode(),
        TextNode("InstallPropertiesPerFeatureInternal"
                 "(${script_state}, ${feature}, selected_wti_list);"),
    ])

    for class_like in set_of_class_likes:
        path_manager = PathManager(class_like)
        source_node.accumulator.add_include_headers(
            [path_manager.api_path(ext="h")])

    # The helper function
    helper_func_def.body.append(
        TextNode("""\
V8PerContextData* per_context_data = script_state->PerContextData();
v8::Isolate* isolate = script_state->GetIsolate();
v8::Local<v8::Context> context = script_state->GetContext();
const DOMWrapperWorld& world = script_state->World();
V8InterfaceBridgeBase::FeatureSelector feature_selector(feature);

for (const auto* wrapper_type_info : wrapper_type_info_list) {
  v8::Local<v8::Object> instance_object;
  v8::Local<v8::Object> prototype_object;
  v8::Local<v8::Function> interface_object;
  v8::Local<v8::Template> interface_template =
      wrapper_type_info->GetV8ClassTemplate(isolate, world);

  switch (wrapper_type_info->idl_definition_kind) {
    case WrapperTypeInfo::kIdlInterface:
      if (!per_context_data->GetExistingConstructorAndPrototypeForType(
              wrapper_type_info, &prototype_object, &interface_object)) {
        continue;
      }
      break;
    case WrapperTypeInfo::kIdlNamespace:
      NOTIMPLEMENTED();
      break;
    default:
      NOTREACHED();
  }

  wrapper_type_info->install_context_dependent_props_func(
      context, world, instance_object, prototype_object,  interface_object,
      interface_template, feature_selector);
}\
"""))

    # Write down to the files.
    write_code_node_to_file(header_node, path_manager.gen_path_to(header_path))
    write_code_node_to_file(source_node, path_manager.gen_path_to(source_path))


def generate_init_idl_interfaces(function_name,
                                 filepath_basename,
                                 for_testing=False):
    assert isinstance(function_name, str)
    assert isinstance(filepath_basename, str)
    assert isinstance(for_testing, bool)

    web_idl_database = package_initializer().web_idl_database()

    # Filepaths
    header_path = PathManager.component_path("modules",
                                             "{}.h".format(filepath_basename))
    source_path = PathManager.component_path("modules",
                                             "{}.cc".format(filepath_basename))

    # Root nodes
    header_node = ListNode(tail="\n")
    header_node.set_accumulator(CodeGenAccumulator())
    header_node.set_renderer(MakoRenderer())
    source_node = ListNode(tail="\n")
    source_node.set_accumulator(CodeGenAccumulator())
    source_node.set_renderer(MakoRenderer())

    # Namespaces
    header_blink_ns = CxxNamespaceNode(name_style.namespace("blink"))
    source_blink_ns = CxxNamespaceNode(name_style.namespace("blink"))
    header_bindings_ns = CxxNamespaceNode(name_style.namespace("bindings"))
    source_bindings_ns = CxxNamespaceNode(name_style.namespace("bindings"))
    header_blink_ns.body.append(header_bindings_ns)
    source_blink_ns.body.append(source_bindings_ns)

    # Function nodes
    func_decl = CxxFuncDeclNode(
        name=function_name, arg_decls=[], return_type="void")
    func_def = CxxFuncDefNode(
        name=function_name, arg_decls=[], return_type="void")
    header_bindings_ns.body.extend([
        TextNode("""\
// Initializes cross-component trampolines of IDL interface / namespace.\
"""),
        func_decl,
    ])
    source_bindings_ns.body.append(func_def)

    # Assemble the parts.
    header_node.extend([
        make_copyright_header(),
        EmptyNode(),
        enclose_with_header_guard(
            ListNode([
                make_header_include_directives(header_node.accumulator),
                EmptyNode(),
                header_blink_ns,
            ]), name_style.header_guard(header_path)),
    ])
    source_node.extend([
        make_copyright_header(),
        EmptyNode(),
        TextNode("#include \"{}\"".format(header_path)),
        EmptyNode(),
        make_header_include_directives(source_node.accumulator),
        EmptyNode(),
        source_blink_ns,
    ])

    init_calls = []
    for class_like in itertools.chain(web_idl_database.interfaces,
                                      web_idl_database.namespaces):
        if class_like.code_generator_info.for_testing != for_testing:
            continue

        path_manager = PathManager(class_like)
        if path_manager.is_cross_components:
            source_node.accumulator.add_include_headers(
                [path_manager.impl_path(ext="h")])

            class_name = v8_bridge_class_name(class_like)
            init_calls.append(_format("{}::Impl::Init();", class_name))
    for init_call in sorted(init_calls):
        func_def.body.append(TextNode(init_call))

    # Write down to the files.
    write_code_node_to_file(header_node, path_manager.gen_path_to(header_path))
    write_code_node_to_file(source_node, path_manager.gen_path_to(source_path))


def generate_interfaces(task_queue):
    assert isinstance(task_queue, TaskQueue)

    web_idl_database = package_initializer().web_idl_database()

    for interface in web_idl_database.interfaces:
        task_queue.post_task(generate_interface, interface.identifier)

    task_queue.post_task(generate_install_properties_per_feature,
                         "InstallPropertiesPerFeature",
                         "properties_per_feature_installer")
    task_queue.post_task(generate_install_properties_per_feature,
                         "InstallPropertiesPerFeatureForTesting",
                         "properties_per_feature_installer_for_testing",
                         for_testing=True)
    task_queue.post_task(generate_init_idl_interfaces, "InitIDLInterfaces",
                         "init_idl_interfaces")
    task_queue.post_task(generate_init_idl_interfaces,
                         "InitIDLInterfacesForTesting",
                         "init_idl_interfaces_for_testing",
                         for_testing=True)
