{% filter format_blink_cpp_source_code %}

{% include 'copyright_block.txt' %}
#include "{{this_include_header_path}}"

#include <algorithm>

{% for filename in cpp_includes if filename != '%s.h' % cpp_class_or_partial %}
#include "{{filename}}"
{% endfor %}

namespace blink {
{% set dom_template = '%s::DomTemplate' % v8_class if not is_array_buffer_or_view else 'nullptr' %}
{% set parent_wrapper_type_info = 'V8%s::GetWrapperTypeInfo()' % parent_interface
                                  if parent_interface else 'nullptr' %}
{% set active_scriptwrappable_inheritance =
    'kInheritFromActiveScriptWrappable'
    if active_scriptwrappable else
    'kNotInheritFromActiveScriptWrappable' %}

{% set wrapper_type_info_const = '' if has_partial_interface else 'const ' %}
{% if not is_partial %}
// Suppress warning: global constructors, because struct WrapperTypeInfo is trivial
// and does not depend on another global objects.
#if defined(COMPONENT_BUILD) && defined(WIN32) && defined(__clang__)
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wglobal-constructors"
#endif
{{wrapper_type_info_const}}WrapperTypeInfo {{snake_case_v8_class}}_wrapper_type_info = {
    gin::kEmbedderBlink,
    {{dom_template}},
    {{install_conditional_features_func or 'nullptr'}},
    "{{interface_name}}",
    {{parent_wrapper_type_info}},
    WrapperTypeInfo::kWrapperTypeObjectPrototype,
    WrapperTypeInfo::{{wrapper_class_id}},
    WrapperTypeInfo::{{active_scriptwrappable_inheritance}},
};
#if defined(COMPONENT_BUILD) && defined(WIN32) && defined(__clang__)
#pragma clang diagnostic pop
#endif

{% if not is_typed_array_type %}
// This static member must be declared by DEFINE_WRAPPERTYPEINFO in {{cpp_class}}.h.
// For details, see the comment of DEFINE_WRAPPERTYPEINFO in
// platform/bindings/ScriptWrappable.h.
const WrapperTypeInfo& {{cpp_class}}::wrapper_type_info_ = {{snake_case_v8_class}}_wrapper_type_info;
{% endif %}

{% if active_scriptwrappable %}
// [ActiveScriptWrappable]
static_assert(
    std::is_base_of<ActiveScriptWrappableBase, {{cpp_class}}>::value,
    "{{cpp_class}} does not inherit from ActiveScriptWrappable<>, but specifying "
    "[ActiveScriptWrappable] extended attribute in the IDL file.  "
    "Be consistent.");
static_assert(
    !std::is_same<decltype(&{{cpp_class}}::HasPendingActivity),
                  decltype(&ScriptWrappable::HasPendingActivity)>::value,
    "{{cpp_class}} is not overriding hasPendingActivity(), but is specifying "
    "[ActiveScriptWrappable] extended attribute in the IDL file.  "
    "Be consistent.");
{% else %}
// not [ActiveScriptWrappable]
static_assert(
    !std::is_base_of<ActiveScriptWrappableBase, {{cpp_class}}>::value,
    "{{cpp_class}} inherits from ActiveScriptWrappable<>, but is not specifying "
    "[ActiveScriptWrappable] extended attribute in the IDL file.  "
    "Be consistent.");
static_assert(
    std::is_same<decltype(&{{cpp_class}}::HasPendingActivity),
                 decltype(&ScriptWrappable::HasPendingActivity)>::value,
    "{{cpp_class}} is overriding hasPendingActivity(), but is not specifying "
    "[ActiveScriptWrappable] extended attribute in the IDL file.  "
    "Be consistent.");
{% endif %}

{% endif %}{# not is_partial #}
{% if not is_array_buffer_or_view %}
namespace {{internal_namespace}} {
{% if has_partial_interface %}
{% for method in methods if method.overloads and method.overloads.has_partial_overloads %}
static void (*{{method.name}}MethodForPartialInterface)(const v8::FunctionCallbackInfo<v8::Value>&) = 0;
{% endfor %}
{% endif %}

{##############################################################################}
{# Attributes #}
{% from 'attributes.cc.tmpl' import attribute_getter, attribute_setter,
       with context %}
{% for attribute in attributes %}
{% for world_suffix in attribute.world_suffixes %}
{% if attribute.private_property_is_shared_between_getter_and_setter %}
// Define a private property key shared between getter and setter.
static const V8PrivateProperty::SymbolKey kPrivateProperty{{attribute.camel_case_name}};
{% endif %}

{% if attribute.does_generate_getter %}
{{attribute_getter(attribute, world_suffix)}}
{% endif %}
{% if attribute.does_generate_setter %}
{{attribute_setter(attribute, world_suffix)}}
{% endif %}
{% endfor %}
{% endfor %}
{##############################################################################}
{# Methods #}
{% from 'methods.cc.tmpl' import generate_method, overload_resolution_method,
      origin_safe_method_getter, generate_constructor,
      runtime_determined_length_method, runtime_determined_maxarg_method
      with context %}
{% for method in methods %}
{% for world_suffix in method.world_suffixes %}
{% if not method.is_custom and method.visible %}
{{generate_method(method, world_suffix)}}
{% endif %}
{% if method.overloads and method.overloads.visible %}
{% if method.overloads.runtime_determined_lengths %}
{{runtime_determined_length_method(method.overloads)}}
{% endif %}
{% if method.overloads.runtime_determined_maxargs %}
{{runtime_determined_maxarg_method(method.overloads)}}
{% endif %}
{{overload_resolution_method(method.overloads, world_suffix)}}
{% endif %}
{% if method.is_cross_origin and method.visible and
      (not method.overload_index or method.overloads) %}
{{origin_safe_method_getter(method, world_suffix)}}
{% endif %}
{% endfor %}
{% endfor %}
{% if iterator_method %}
{{generate_method(iterator_method)}}
{% endif %}
{# Constructors #}
{% for constructor in constructors %}
{{generate_constructor(constructor)}}
{% endfor %}
{% block overloaded_constructor %}{% endblock %}
{% block constructor_callback %}{% endblock %}
{# Special operations (methods) #}
{% block named_property_getter %}{% endblock %}
{% block named_property_setter %}{% endblock %}
{% block named_property_deleter %}{% endblock %}
{% block named_property_query %}{% endblock %}
{% block named_property_descriptor %}{% endblock %}
{% block named_property_enumerator %}{% endblock %}
{% block indexed_property_getter %}{% endblock %}
{% block indexed_property_descriptor %}{% endblock %}
{% block indexed_property_setter %}{% endblock %}
{% block indexed_property_deleter %}{% endblock %}
{##############################################################################}
{% if has_access_check_callbacks and not is_partial and has_cross_origin_named_enumerator %}
static const struct {
  using GetterCallback = void(*)(const v8::PropertyCallbackInfo<v8::Value>&);
  using SetterCallback = void(*)(v8::Local<v8::Value>, const V8CrossOriginCallbackInfo&);

  const char* const name;
  const GetterCallback getter;
  const SetterCallback setter;
} kCrossOriginAttributeTable[] = {
  {% for attribute in attributes if attribute.has_cross_origin_getter or attribute.has_cross_origin_setter %}
  {
    "{{attribute.name}}",
    {% if attribute.has_cross_origin_getter %}
    {% if attribute.has_custom_getter %}
    {{v8_class}}::{{attribute.camel_case_name}}AttributeGetterCustom,
    {% else %}
    {{internal_namespace}}::{{attribute.camel_case_name}}AttributeGetter,
    {% endif %}
    {% else %}
    nullptr,
    {% endif %}
    {%+ if attribute.has_cross_origin_setter %}&{{internal_namespace}}::{{attribute.camel_case_name}}AttributeSetter{% else %}nullptr{% endif %},
  },
  {% endfor %}
};

static const struct {
  using ValueCallback = void(*)(const v8::PropertyCallbackInfo<v8::Value>&);

  const char* const name;
  const ValueCallback value;
} kCrossOriginOperationTable[] = {
  {% for method in methods if method.is_cross_origin and
        (not method.overload_index or method.overloads) %}
  {"{{method.name}}", &{{internal_namespace}}::{{method.camel_case_name}}OriginSafeMethodGetter},
  {% endfor %}
};
{% endif %}
{##############################################################################}
}  // namespace {{internal_namespace}}

{# Constants #}
{% from 'constants.cc.tmpl' import constant_getter_callback with context %}
{% for constant in constants | has_special_getter %}
{{constant_getter_callback(constant)}}
{% endfor %}

{# Attributes #}
{% from 'attributes.cc.tmpl' import constructor_getter_callback,
       attribute_getter_callback, attribute_setter_callback with context %}
{% for attribute in attributes %}
{% for world_suffix in attribute.world_suffixes %}
{% if not attribute.constructor_type %}
{{attribute_getter_callback(attribute, world_suffix)}}
{% else %}
{{constructor_getter_callback(attribute, world_suffix)}}
{% endif %}
{% if attribute.has_setter %}
{{attribute_setter_callback(attribute, world_suffix)}}
{% endif %}
{% endfor %}
{% endfor %}

{# Methods #}
{% from 'methods.cc.tmpl' import origin_safe_method_getter_callback,
      method_callback with context %}
{% for method in methods %}
{% for world_suffix in method.world_suffixes %}
{% if not method.overload_index or method.overloads %}
{# Document about the following condition: #}
{# https://docs.google.com/document/d/1qBC7Therp437Jbt_QYAtNYMZs6zQ_7_tnMkNUG_ACqs/edit?usp=sharing #}
{% if (method.overloads and method.overloads.visible and
       (not method.overloads.has_partial_overloads or not is_partial)) or
      (not method.overloads and method.visible) %}
{# A single callback is generated for overloaded methods #}
{# with considering partial overloads #}
{{method_callback(method, world_suffix)}}
{% endif %}
{% endif %}
{% if method.is_cross_origin and method.visible and
     (not method.overload_index or method.overloads) %}
{{origin_safe_method_getter_callback(method, world_suffix)}}
{% endif %}
{% endfor %}
{% endfor %}
{% if iterator_method %}
{{method_callback(iterator_method)}}
{% endif %}
{# Special operations (methods) #}
{% block named_property_getter_callback %}{% endblock %}
{% block named_property_setter_callback %}{% endblock %}
{% block named_property_deleter_callback %}{% endblock %}
{% block named_property_query_callback %}{% endblock %}
{% block named_property_enumerator_callback %}{% endblock %}
{% block indexed_property_getter_callback %}{% endblock %}
{% block indexed_property_descriptor_callback %}{% endblock %}
{% block indexed_property_setter_callback %}{% endblock %}
{% block indexed_property_deleter_callback %}{% endblock %}
{% block indexed_property_definer_callback %}{% endblock %}

{% if has_access_check_callbacks and not is_partial %}
bool {{v8_class_or_partial}}::SecurityCheck(v8::Local<v8::Context> accessing_context, v8::Local<v8::Object> accessed_object, v8::Local<v8::Value> data) {
  {% if interface_name == 'Window' %}
  v8::Isolate* isolate = v8::Isolate::GetCurrent();
  v8::Local<v8::Object> window = V8Window::FindInstanceInPrototypeChain(accessed_object, isolate);
  if (window.IsEmpty())
    return false;  // the frame is gone.

  const DOMWindow* target_window = V8Window::ToImpl(window);
  return BindingSecurity::ShouldAllowAccessTo(ToLocalDOMWindow(accessing_context), target_window, BindingSecurity::ErrorReportOption::kDoNotReport);
  {% elif interface_name == 'Location' %}
  {{cpp_class}}* impl = {{v8_class}}::ToImpl(accessed_object);
  return BindingSecurity::ShouldAllowAccessTo(ToLocalDOMWindow(accessing_context), impl, BindingSecurity::ErrorReportOption::kDoNotReport);
  {% else %}
  #error "Unexpected security check for interface {{interface_name}}"
  {% endif %}
}

{% if has_cross_origin_named_getter %}
void {{v8_class_or_partial}}::CrossOriginNamedGetter(v8::Local<v8::Name> name, const v8::PropertyCallbackInfo<v8::Value>& info) {
  {{ runtime_timer_scope_disabled_by_default(runtime_call_stats.cross_origin_named_getter_counter) }}
  if (!name->IsString())
    return;
  const AtomicString& property_name = ToCoreAtomicString(name.As<v8::String>());

  for (const auto& attribute : {{internal_namespace}}::kCrossOriginAttributeTable) {
    if (property_name == attribute.name && attribute.getter) {
      attribute.getter(info);
      return;
    }
  }
  for (const auto& operation : {{internal_namespace}}::kCrossOriginOperationTable) {
    if (property_name == operation.name) {
      operation.value(info);
      return;
    }
  }

  {% if named_property_getter and named_property_getter.is_cross_origin %}
  {% if named_property_getter.is_custom %}
  {{v8_class}}::NamedPropertyGetterCustom(property_name, info);
  {% else %}
  {{internal_namespace}}::NamedPropertyGetter(property_name, info);
  {% endif %}
  {% else %}
  // HTML 7.2.3.3 CrossOriginGetOwnPropertyHelper ( O, P )
  // https://html.spec.whatwg.org/C/#crossorigingetownpropertyhelper-(-o,-p-)
  // step 3. If P is "then", @@toStringTag, @@hasInstance, or
  //   @@isConcatSpreadable, then return PropertyDescriptor{ [[Value]]:
  //   undefined, [[Writable]]: false, [[Enumerable]]: false,
  //   [[Configurable]]: true }.
  if (property_name == "then") {
    V8SetReturnValue(info, v8::Undefined(info.GetIsolate()));
    return;
  }

  BindingSecurity::FailedAccessCheckFor(
      info.GetIsolate(),
      {{v8_class}}::GetWrapperTypeInfo(),
      info.Holder());
  {% endif %}
}
{% endif %}

{% if has_cross_origin_named_setter %}
void {{v8_class_or_partial}}::CrossOriginNamedSetter(v8::Local<v8::Name> name, v8::Local<v8::Value> value, const v8::PropertyCallbackInfo<v8::Value>& info) {
  {{ runtime_timer_scope_disabled_by_default(runtime_call_stats.cross_origin_named_setter_counter) }}
  if (!name->IsString())
    return;
  const AtomicString& property_name = ToCoreAtomicString(name.As<v8::String>());

  for (const auto& attribute : {{internal_namespace}}::kCrossOriginAttributeTable) {
    if (property_name == attribute.name && attribute.setter) {
      attribute.setter(value, V8CrossOriginCallbackInfo(info));
      return;
    }
  }

  {# If there were no matches in the cross-origin attribute table, consider it
     an access check failure: there are no custom named setters that are
     accessible from a cross-origin context. #}

  BindingSecurity::FailedAccessCheckFor(
      info.GetIsolate(),
      {{v8_class}}::GetWrapperTypeInfo(),
      info.Holder());
}
{% endif %}

{% if has_cross_origin_named_enumerator %}
void {{v8_class_or_partial}}::CrossOriginNamedEnumerator(const v8::PropertyCallbackInfo<v8::Array>& info) {
  Vector<String> names;
  for (const auto& attribute : {{internal_namespace}}::kCrossOriginAttributeTable)
    names.push_back(attribute.name);
  for (const auto& operation : {{internal_namespace}}::kCrossOriginOperationTable)
    names.push_back(operation.name);

  // Use the current context as the creation context, as a cross-origin access
  // may involve an object that does not have a creation context.
  V8SetReturnValue(info,
                   ToV8(names, info.GetIsolate()->GetCurrentContext()->Global(),
                        info.GetIsolate()).As<v8::Array>());
}
{% endif %}

{% if has_cross_origin_indexed_getter %}
void {{v8_class_or_partial}}::CrossOriginIndexedGetter(uint32_t index, const v8::PropertyCallbackInfo<v8::Value>& info) {
  {% if indexed_property_getter.is_custom %}
  {{v8_class}}::IndexedPropertyGetterCustom(index, info);
  {% else %}
  {{internal_namespace}}::IndexedPropertyGetter(index, info);
  {% endif %}
}
{% endif %}
{% endif %}{# has_access_check_callbacks #}

{% block visit_dom_wrapper %}{% endblock %}
{##############################################################################}
{% block install_methods %}
{% from 'methods.cc.tmpl' import method_configuration with context %}
{% if methods | has_method_configuration(is_partial) %}
static constexpr V8DOMConfiguration::MethodConfiguration k{{v8_class}}Methods[] = {
    {% for method in methods | has_method_configuration(is_partial) %}
    {{method_configuration(method) | trim | indent(4)}},
    {% endfor %}
};

{% endif %}
{% endblock %}
{% endif %}{# not is_array_buffer_or_view #}
{##############################################################################}
{% block named_constructor %}{% endblock %}
{##############################################################################}
{% block install_dom_template %}
{% if not is_array_buffer_or_view %}
{% from 'methods.cc.tmpl' import install_custom_signature,
        method_configuration with context %}
{% from 'attributes.cc.tmpl' import accessor_configuration,
        attribute_configuration, install_attributes, install_interface_objects,
        with context %}
{% from 'constants.cc.tmpl' import install_constants,
        constant_configuration with context %}
{% if has_partial_interface or is_partial %}
void {{v8_class_or_partial}}::Install{{v8_class}}Template(
    v8::Isolate* isolate,
    const DOMWrapperWorld& world,
    v8::Local<v8::FunctionTemplate> interface_template) {
{% else %}
static void Install{{v8_class}}Template(
    v8::Isolate* isolate,
    const DOMWrapperWorld& world,
    v8::Local<v8::FunctionTemplate> interface_template) {
{% endif %}
  // Initialize the interface object's template.
  {% if is_partial %}
  {{v8_class}}::Install{{v8_class}}Template(isolate, world, interface_template);
  {% else %}
  {% set parent_interface_template =
         '%s::DomTemplateForNamedPropertiesObject(isolate, world)' % v8_class
         if has_named_properties_object else
         'V8%s::DomTemplate(isolate, world)' % parent_interface
         if parent_interface else
         'v8::Local<v8::FunctionTemplate>()' %}
  V8DOMConfiguration::InitializeDOMInterfaceTemplate(isolate, interface_template, {{v8_class}}::GetWrapperTypeInfo()->interface_name, {{parent_interface_template}}, {{v8_class}}::kInternalFieldCount);
  {% if constructors or has_custom_constructor or has_html_constructor %}
  interface_template->SetCallHandler({{internal_namespace}}::ConstructorCallback);
  interface_template->SetLength({{interface_length}});
  {% endif %}
  {% endif %}{# is_partial #}

  {% if runtime_enabled_feature_name and not context_enabled_feature_name %}
  if (!{{runtime_enabled_feature_name | runtime_enabled_function}}) {
    return;
  }
  {% endif %}

  v8::Local<v8::Signature> signature = v8::Signature::New(isolate, interface_template);
  ALLOW_UNUSED_LOCAL(signature);
  v8::Local<v8::ObjectTemplate> instance_template = interface_template->InstanceTemplate();
  ALLOW_UNUSED_LOCAL(instance_template);
  v8::Local<v8::ObjectTemplate> prototype_template = interface_template->PrototypeTemplate();
  ALLOW_UNUSED_LOCAL(prototype_template);

  {% if interface_name == 'Window' and not is_partial %}
  prototype_template->SetInternalFieldCount(V8Window::kInternalFieldCount);
  {% endif %}

  {% if is_immutable_prototype %}
  // Global object prototype chain consists of Immutable Prototype Exotic Objects
  prototype_template->SetImmutableProto();
  {% endif %}

  {% if is_global %}
  // Global objects are Immutable Prototype Exotic Objects
  instance_template->SetImmutableProto();
  {% endif %}

  // Register IDL constants, attributes and operations.
  {% if constants %}
  {{install_constants() | trim | indent(2)}}
  {% endif %}
  {% if data_attributes %}
  {{install_interface_objects(data_attributes, 'instance_template', 'prototype_template') | trim | indent(2)}}
  {% endif %}
  {% if accessors %}
  {{install_attributes(accessors, 'instance_template', 'prototype_template', 'interface_template') | trim | indent(2)}}
  {% endif %}
  {% if methods | has_method_configuration(is_partial) %}
  V8DOMConfiguration::InstallMethods(
      isolate, world, instance_template, prototype_template, interface_template,
      signature, k{{v8_class}}Methods, base::size(k{{v8_class}}Methods));
  {% endif %}

  {% if has_access_check_callbacks and not is_partial %}
  // Cross-origin access check
  {% set cross_origin_named_getter = '%s::CrossOriginNamedGetter' % v8_class_or_partial if has_cross_origin_named_getter else 'nullptr' %}
  {% set cross_origin_named_setter = '%s::CrossOriginNamedSetter' % v8_class_or_partial if has_cross_origin_named_setter else 'nullptr' %}
  {% set cross_origin_named_enumerator = '%s::CrossOriginNamedEnumerator' % v8_class_or_partial if has_cross_origin_named_enumerator else 'nullptr' %}
  {% set cross_origin_indexed_getter = '%s::CrossOriginIndexedGetter' % v8_class_or_partial if has_cross_origin_indexed_getter else 'nullptr' %}
  instance_template->SetAccessCheckCallbackAndHandler(
      {{v8_class_or_partial}}::SecurityCheck,
      v8::NamedPropertyHandlerConfiguration(
          {{cross_origin_named_getter}},
          {{cross_origin_named_setter}},
          nullptr,
          nullptr,
          {{cross_origin_named_enumerator}}),
      v8::IndexedPropertyHandlerConfiguration({{cross_origin_indexed_getter}}),
      v8::External::New(isolate, const_cast<WrapperTypeInfo*>({{v8_class}}::GetWrapperTypeInfo())));
  {% endif %}

  {% if (indexed_property_getter or named_property_getter) and not is_partial %}
  // Indexed properties
  {{install_indexed_property_handler('instance_template') | trim | indent(2)}}
  {% endif %}
  {% if named_property_getter and not is_partial and not has_named_properties_object %}
  // Named properties
  {{install_named_property_handler('instance_template') | trim | indent(2)}}
  {% endif %}

  {% if has_array_iterator and not is_partial %}
  // Array iterator (@@iterator)
  {%+ if is_global %}instance_template{% else %}prototype_template{% endif %}->SetIntrinsicDataProperty(v8::Symbol::GetIterator(isolate), v8::kArrayProto_values, v8::DontEnum);
  {% if iterable %}
  {% if is_global %}
#error "iterable<V> on [Global] is currently unsupported."
  {% endif %}
  // For value iterators, the properties below must originally be set to the corresponding ones in %ArrayPrototype%.
  // See https://heycam.github.io/webidl/#es-iterators.
  prototype_template->SetIntrinsicDataProperty(V8AtomicString(isolate, "entries"), v8::kArrayProto_entries);
  prototype_template->SetIntrinsicDataProperty(V8AtomicString(isolate, "forEach"), v8::kArrayProto_forEach);
  prototype_template->SetIntrinsicDataProperty(V8AtomicString(isolate, "keys"), v8::kArrayProto_keys);
  prototype_template->SetIntrinsicDataProperty(V8AtomicString(isolate, "values"), v8::kArrayProto_values);
  {% endif %}
  {% endif %}

  {% if iterator_method and not iterator_method.runtime_enabled_feature_name %}
  {% filter exposed(iterator_method.exposed_test) %}
  {% set symbol_alias = '"%s"' % iterator_method_alias
                        if iterator_method_alias else 'nullptr' %}
  // Iterator (@@iterator)
  static const V8DOMConfiguration::SymbolKeyedMethodConfiguration
  kSymbolKeyedIteratorConfiguration = {
      v8::Symbol::GetIterator,
      {{symbol_alias}},
      {{v8_class_or_partial}}::IteratorMethodCallback,
      0,
      v8::DontEnum,
      V8DOMConfiguration::kOnPrototype,
      V8DOMConfiguration::kCheckHolder,
      V8DOMConfiguration::kDoNotCheckAccess,
      V8DOMConfiguration::kHasSideEffect
  };
  V8DOMConfiguration::InstallMethod(
      isolate, world, prototype_template, signature,
      kSymbolKeyedIteratorConfiguration);
  {% endfilter %}
  {% endif %}

  {% if interface_name == 'FileSystemDirectoryHandle' %}
  // Temporary @@asyncIterator support for FileSystemDirectoryHandle
  // TODO(https://crbug.com/1087157): Replace with proper bindings support.
  static const V8DOMConfiguration::SymbolKeyedMethodConfiguration
  kSymbolKeyedIteratorConfiguration = {
      v8::Symbol::GetAsyncIterator,
      "entries",
      V8FileSystemDirectoryHandle::EntriesMethodCallback,
      0,
      v8::DontEnum,
      V8DOMConfiguration::kOnPrototype,
      V8DOMConfiguration::kCheckHolder,
      V8DOMConfiguration::kDoNotCheckAccess,
      V8DOMConfiguration::kHasSideEffect
  };
  V8DOMConfiguration::InstallMethod(
      isolate, world, prototype_template, signature,
      kSymbolKeyedIteratorConfiguration);
  {% endif %}

  {% if interface_name == 'Iterator' %}
  // The WebIDL spec says when an interface has pair iterators the iterators it
  // returns must be instances of the "default iterator object" whose
  // [[Prototype]] points to an "iterator prototype object" whose
  // [[Prototype]], on its turn, points to %IteratorPrototype%. next() must be
  // implemented in the "iterator prototype object", while %IteratorPrototype%
  // provides @@iterator.
  // References:
  // https://heycam.github.io/webidl/#es-default-iterator-object
  // https://heycam.github.io/webidl/#es-iterator-prototype-object
  //
  // The iterators we return from interfaces that have pair interators adhere
  // to the above by:
  // - Adding the "next()" property to its prototype object.
  // - Making the prototype object inherit from %IteratorPrototype% with the
  //   hack below, which creates another function template with no prototype
  //   and sets the "prototype" property of its function object.
  //   When |interface_template|'s function object is created, its
  //   prototype.__proto__ will point to the value of the "prototype" property
  //   of |intrinsic_iterator_prototype_interface_template|, which is exactly
  //   what we want.
  //
  // Finally, creating a FunctionTemplate here might look expensive since they
  // have the same lifetime as their context, but:
  // - |interface_template| is cached in V8PerIsolateData, so we create only one
  //   FunctionTemplate per interface.
  // - There is only one Iterator interface that creates this FunctionTemplate,
  //   so there is no need to reuse this FunctionTemplate and register it in
  //   V8PerIsolateData.
  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_template->Inherit(intrinsic_iterator_prototype_interface_template);
  {% endif %}

  {% if interface_name == 'FileSystemDirectoryIterator' %}
  // 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_template->Inherit(intrinsic_iterator_prototype_interface_template);
  {% endif %}

  {% if interface_name == 'DOMException' %}
  // The WebIDL spec states that DOMException objects have a few peculiarities.
  // One of them is similar to what it mandates for Iterator objects when it
  // comes to the inheritance chain. Instead of
  //     DOMException -> prototype -> %ObjectPrototype%
  // we have
  //     DOMException -> prototype -> %ErrorPrototype% -> %ObjectPrototype%
  // so that DOMException objects "inherit" toString() and a few properties
  // from %ErrorPrototype%.
  // See https://heycam.github.io/webidl/#es-DOMException-specialness.
  //
  // We achieve this with the same hack we use for Iterators: create a new
  // function template with no prototype, set its "prototype" property to
  // %ErrorPrototype% and make |interface_template| inherit from it. When
  // |interface_template| is instantiated, its prototype.__proto__ will point to
  // |intrinsic_error_prototype_interface_template|'s "prototype" property.
  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_template->Inherit(intrinsic_error_prototype_interface_template);
  {% endif %}

  {% if interface_name == 'Location' %}
  // Symbol.toPrimitive
  // Prevent author scripts to inject Symbol.toPrimitive property into location
  // objects, also prevent the look-up of Symbol.toPrimitive through the
  // prototype chain.
  instance_template->Set(v8::Symbol::GetToPrimitive(isolate),
                        v8::Undefined(isolate),
                        static_cast<v8::PropertyAttribute>(
                            v8::ReadOnly | v8::DontEnum | v8::DontDelete));
  {% endif %}

  {% if has_custom_legacy_call_as_function and not is_partial %}
  instance_template->SetCallAsFunctionHandler({{v8_class}}::LegacyCallCustom);
  {% endif %}

  {% if interface_name == 'HTMLAllCollection' and not is_partial %}
  // Needed for legacy support of document.all
  instance_template->MarkAsUndetectable();
  {% endif %}

  // Custom signature
  {% for method in methods | custom_registration(is_partial) %}
  {% filter exposed(method.overloads.exposed_test_all
                    if method.overloads else method.exposed_test) %}
  {% set feature_name = method.overloads.runtime_enabled_all
                        if method.overloads else method.runtime_enabled_feature_name %}
  {% if not feature_name %}
  {% if method.is_cross_origin %}
  {{install_origin_safe_method(method, 'instance_template', 'prototype_template', 'interface_template', 'signature') | trim | indent(2)}}
  {% else %}
  {{install_custom_signature(method, 'instance_template', 'prototype_template', 'interface_template', 'signature') | trim | indent(2)}}
  {% endif %}
  {% endif %}
  {% endfilter %}
  {% endfor %}
  {% if not has_partial_interface %}

  {{v8_class_or_partial}}::InstallRuntimeEnabledFeaturesOnTemplate(
      isolate, world, interface_template);
  {% endif %}
}

void {{v8_class_or_partial}}::InstallRuntimeEnabledFeaturesOnTemplate(
    v8::Isolate* isolate,
    const DOMWrapperWorld& world,
    v8::Local<v8::FunctionTemplate> interface_template) {
  {% if runtime_enabled_feature_name and not context_enabled_feature_name %}
  if (!{{runtime_enabled_feature_name | runtime_enabled_function}}) {
    return;
  }
  {% endif %}

  {% if is_partial %}
  {{v8_class}}::InstallRuntimeEnabledFeaturesOnTemplate(isolate, world, interface_template);
  {% endif %}

  v8::Local<v8::Signature> signature = v8::Signature::New(isolate, interface_template);
  ALLOW_UNUSED_LOCAL(signature);
  v8::Local<v8::ObjectTemplate> instance_template = interface_template->InstanceTemplate();
  ALLOW_UNUSED_LOCAL(instance_template);
  v8::Local<v8::ObjectTemplate> prototype_template = interface_template->PrototypeTemplate();
  ALLOW_UNUSED_LOCAL(prototype_template);

  // Register IDL constants, attributes and operations.
  {% for feature_name, constants_list in constants | selectattr('runtime_enabled_feature_name') | groupby('runtime_enabled_feature_name') %}
  {% filter runtime_enabled(feature_name) %}
  static constexpr V8DOMConfiguration::ConstantConfiguration kConfigurations[] = {
      {% for constant in constants_list %}
      {{constant_configuration(constant) | trim | indent(6)}},
      {% endfor %}
  };
  V8DOMConfiguration::InstallConstants(
      isolate, interface_template, prototype_template,
      kConfigurations, base::size(kConfigurations));
  {% endfilter %}
  {% endfor %}

  {% for feature_name, attribute_list in runtime_enabled_attributes | selectattr('is_data_type_property') | groupby('runtime_enabled_feature_name') %}
  {% filter runtime_enabled(feature_name) %}
  {{install_interface_objects(attribute_list | sort, 'instance_template', 'prototype_template') | trim | indent(2)}}
  {% endfilter %}
  {% endfor %}

  {% for feature_name, attribute_list in runtime_enabled_attributes | selectattr('is_data_type_property', 'equalto', False) | groupby('runtime_enabled_feature_name') %}
  {% filter runtime_enabled(feature_name) %}
  {{install_attributes(attribute_list | sort, 'instance_template', 'prototype_template', 'interface_template') | trim | indent(2)}}
  {% endfilter %}
  {% endfor %}

  {% if iterator_method and iterator_method.runtime_enabled_feature_name %}
  {% filter exposed(iterator_method.exposed_test) %}
  {% filter runtime_enabled(iterator_method.runtime_enabled_feature_name) %}
  {% set symbol_alias = '"%s"' % iterator_method_alias
                        if iterator_method_alias else 'nullptr' %}
  // Iterator (@@iterator)
  static constexpr V8DOMConfiguration::SymbolKeyedMethodConfiguration
  kSymbolKeyedIteratorConfiguration = {
      v8::Symbol::GetIterator,
      {{symbol_alias}},
      {{v8_class_or_partial}}::IteratorMethodCallback,
      0,
      v8::DontEnum,
      V8DOMConfiguration::kOnPrototype,
      V8DOMConfiguration::kCheckHolder,
      V8DOMConfiguration::kDoNotCheckAccess,
      V8DOMConfiguration::kHasSideEffect
  };
  V8DOMConfiguration::InstallMethod(
      isolate, world, prototype_template, signature,
      kSymbolKeyedIteratorConfiguration);
  {% endfilter %}
  {% endfilter %}
  {% endif %}

  // Custom signature
  {% for method in methods | custom_registration(is_partial) %}
  {% filter exposed(method.overloads.exposed_test_all
                    if method.overloads else method.exposed_test) %}
  {% set feature_name = method.overloads.runtime_enabled_all
        if method.overloads else method.runtime_enabled_feature_name %}
  {% if feature_name %}
  {% filter runtime_enabled(feature_name) %}
  {% if method.is_cross_origin %}
  {{install_origin_safe_method(method, 'instance_template', 'prototype_template') | trim | indent(2)}}
  {% else %}
  {{install_custom_signature(method, 'instance_template', 'prototype_template', 'interface_template', 'signature') | trim | indent(2)}}
  {% endif %}
  {% endfilter %}
  {% endif %}
  {% endfilter %}
  {% endfor %}
}

{% endif %}{# not is_array_buffer_or_view #}
{% endblock %}
{##############################################################################}
{% block install_runtime_enabled %}
{% if needs_runtime_enabled_installer %}
{% from 'attributes.cc.tmpl' import accessor_configuration,
        attribute_configuration, install_attributes, install_interface_objects,
        with context %}
{% from 'methods.cc.tmpl' import install_custom_signature with context %}
{% if not is_partial %}
void {{v8_class}}::InstallRuntimeEnabledFeatures(
    v8::Isolate* isolate,
    const DOMWrapperWorld& world,
    v8::Local<v8::Object> instance,
    v8::Local<v8::Object> prototype,
    v8::Local<v8::Function> interface) {
  {% if runtime_enabled_feature_name %}
#error "We don't expect a runtime enabled interface {{v8_class_or_partial}} to have InstallRuntimeEnabledFeatures()."
  {% endif %}

  InstallRuntimeEnabledFeaturesImpl(isolate, world, instance, prototype, interface);
  {% if has_partial_interface %}

  // Call partial interface's installer.
  install_runtime_enabled_features_function_(isolate, world, instance, prototype, interface);
  {% endif %}
}
{% endif %}{# not is_partial #}

void {{v8_class_or_partial}}::InstallRuntimeEnabledFeaturesImpl(
    v8::Isolate* isolate,
    const DOMWrapperWorld& world,
    v8::Local<v8::Object> instance,
    v8::Local<v8::Object> prototype,
    v8::Local<v8::Function> interface) {
  {% if runtime_enabled_feature_name %}
#error "We don't expect a runtime enabled interface {{v8_class_or_partial}} to have InstallRuntimeEnabledFeatures()."
  {% endif %}

  v8::Local<v8::FunctionTemplate> interface_template = {{v8_class}}::GetWrapperTypeInfo()->DomTemplate(isolate, world);
  v8::Local<v8::Signature> signature = v8::Signature::New(isolate, interface_template);
  ALLOW_UNUSED_LOCAL(signature);

  {# TODO(peria): Generate code to install constants. It depends on runtime_enabled_feaure of this interface. #}

  {% for feature_name, attrs in runtime_enabled_attributes | selectattr('is_data_type_property') | groupby('runtime_enabled_feature_name') %}
  {% filter runtime_enabled(feature_name) %}
  {{install_interface_objects(attrs | sort, 'instance', 'prototype')}}
  {% endfilter %}
  {% endfor %}

  {% for feature_name, attrs in runtime_enabled_attributes | selectattr('is_data_type_property', 'equalto', False) | groupby('runtime_enabled_feature_name') %}
  {% filter runtime_enabled(feature_name) %}
  {{install_attributes(attrs | sort, 'instance', 'prototype', 'interface') | trim | indent(2)}}
  {% endfilter %}
  {% endfor %}

  {% if iterator_method and iterator_method.runtime_enabled_feature_name %}
#error "{{v8_class_or_partial}} should not have runtime enabled iterator (@@iterator)."
  {% endif %}

  {% if methods | custom_registration(is_partial) %}
  {% for method in methods | custom_registration(is_partial) %}
  {% filter exposed(method.overloads.exposed_test_all
                    if method.overloads else method.exposed_test) %}
  {% set feature_name = (method.overloads.runtime_enabled_all
                         if method.overloads else method.runtime_enabled_feature_name) %}
  {% if feature_name %}
  {% filter runtime_enabled(feature_name) %}
  {% if method.is_cross_origin %}
#error "{{v8_class_or_partial}} should not have runtime enabled and cross origin methods."
  {% else %}
  {{install_custom_signature(method, 'instance', 'prototype', 'interface', 'signature') | trim | indent(2)}}
  {% endif %}
  {% endfilter %}
  {% endif %}
  {% endfilter %}
  {% endfor %}
  {% endif %}
}

{% endif %}{# needs_runtime_enabled_installer #}
{% endblock %}
{##############################################################################}
{% block origin_trials %}
{% from 'attributes.cc.tmpl' import accessor_configuration,
        attribute_configuration, install_attributes, install_interface_objects,
        with context %}
{% from 'constants.cc.tmpl' import constant_configuration with context %}
{% from 'methods.cc.tmpl' import method_configuration with context %}
{% for feature in optional_features %}
void {{v8_class_or_partial}}::Install{{feature.name}}(
    v8::Isolate* isolate,
    const DOMWrapperWorld& world,
    v8::Local<v8::Object> instance,
    v8::Local<v8::Object> prototype,
    v8::Local<v8::Function> interface) {
  {% if feature.attributes or feature.methods %}
  v8::Local<v8::FunctionTemplate> interface_template =
      {{v8_class}}::GetWrapperTypeInfo()->DomTemplate(isolate, world);
  v8::Local<v8::Signature> signature = v8::Signature::New(isolate, interface_template);
  ALLOW_UNUSED_LOCAL(signature);
  {% endif %}
  {% if feature.needs_context %}
  ExecutionContext* execution_context = ToExecutionContext(isolate->GetCurrentContext());
  {% endif %}{# needs context #}
  {% if feature.needs_secure_context %}
  bool is_secure_context = (execution_context && execution_context->IsSecureContext());
  {% endif %}{# needs secure context #}
  {# Origin-Trial-enabled attributes #}
  {% for secure_context_test, attribute_list in feature.attributes | selectattr('is_data_type_property') | groupby('secure_context_test') %}
  {% filter secure_context(secure_context_test) %}
  {{install_interface_objects(attribute_list, 'instance', 'prototype') | trim | indent(2)}}
  {% endfilter %}
  {% endfor %}
  {% for secure_context_test, attribute_list in feature.attributes | rejectattr('is_data_type_property') | groupby('secure_context_test') %}
  {% filter secure_context(secure_context_test) %}
  {{install_attributes(attribute_list, 'instance', 'prototype', 'interface') | trim | indent(2)}}
  {% endfilter %}{# secure_context #}
  {% endfor %}
  {# Origin-Trial-enabled constants #}
  {% for constant in feature.constants %}
  {% set constant_name = constant.camel_case_name %}
  static constexpr V8DOMConfiguration::ConstantConfiguration
  k{{constant_name}}Configuration = {{constant_configuration(constant)}};
  V8DOMConfiguration::InstallConstant(
      isolate, interface, prototype, k{{constant_name}}Configuration);
  {% endfor %}
  {# Origin-Trial-enabled methods (no overloads) #}
  {% for method in feature.methods %}
  {% filter exposed(method.exposed_test) %}
  {% filter secure_context(method.secure_context_test) %}
  static constexpr V8DOMConfiguration::MethodConfiguration
  k{{method.camel_case_name}}Configurations[] = {
      {{method_configuration(method) | trim | indent(6)}}
  };
  for (const auto& config : k{{method.camel_case_name}}Configurations) {
    V8DOMConfiguration::InstallMethod(
        isolate, world, instance, prototype,
        interface, signature, config);
  }
  {% endfilter %}{# secure_context #}
  {% endfilter %}{# exposed_test #}
  {% endfor %}
}

void {{v8_class_or_partial}}::Install{{feature.name}}(
    ScriptState* script_state, v8::Local<v8::Object> instance) {
  V8PerContextData* per_context_data = script_state->PerContextData();
  v8::Local<v8::Object> prototype = per_context_data->PrototypeForType(
      {{v8_class}}::GetWrapperTypeInfo());
  v8::Local<v8::Function> interface = per_context_data->ConstructorForType(
      {{v8_class}}::GetWrapperTypeInfo());
  ALLOW_UNUSED_LOCAL(interface);
  Install{{feature.name}}(script_state->GetIsolate(), script_state->World(), instance, prototype, interface);
}
{% if not feature.needs_instance %}

void {{v8_class_or_partial}}::Install{{feature.name}}(ScriptState* script_state) {
  Install{{feature.name}}(script_state, v8::Local<v8::Object>());
}
{% endif %}

{% endfor %}{# feature #}
{% endblock %}
{##############################################################################}
{% block get_dom_template %}{% endblock %}
{% block get_dom_template_for_named_properties_object %}{% endblock %}
{% block has_instance %}{% endblock %}
{% block to_impl %}{% endblock %}
{% block to_impl_with_type_check %}{% endblock %}
{##############################################################################}
{% block install_conditional_features %}
{% from 'attributes.cc.tmpl' import install_conditional_attributes,
      install_conditional_interface_objects with context %}
{% from 'methods.cc.tmpl' import install_conditional_methods with context %}
{% if install_conditional_features_func %}
void {{v8_class_or_partial}}::InstallConditionalFeatures(
    v8::Local<v8::Context> context,
    const DOMWrapperWorld& world,
    v8::Local<v8::Object> instance_object,
    v8::Local<v8::Object> prototype_object,
    v8::Local<v8::Function> interface_object,
    v8::Local<v8::FunctionTemplate> interface_template) {
  CHECK(!interface_template.IsEmpty());
  DCHECK((!prototype_object.IsEmpty() && !interface_object.IsEmpty()) ||
         !instance_object.IsEmpty());
  {% if is_partial %}
  {{v8_class}}::InstallConditionalFeatures(
      context, world, instance_object, prototype_object, interface_object, interface_template);
  {% endif %}

  v8::Isolate* isolate = context->GetIsolate();

  {% if unscopables %}
  if (!prototype_object.IsEmpty()) {
    v8::Local<v8::Name> unscopables_symbol(v8::Symbol::GetUnscopables(isolate));
    v8::Local<v8::Object> unscopables;
    bool has_unscopables;
    if (prototype_object->HasOwnProperty(context, unscopables_symbol)
        .To(&has_unscopables) && has_unscopables) {
      unscopables = prototype_object->Get(context, unscopables_symbol)
                    .ToLocalChecked().As<v8::Object>();
    } else {
      // Web IDL 3.6.3. Interface prototype object
      // https://heycam.github.io/webidl/#create-an-interface-prototype-object
      // step 8.1. Let unscopableObject be the result of performing
      //   ! ObjectCreate(null).
      unscopables = v8::Object::New(isolate);
      unscopables->SetPrototype(context, v8::Null(isolate)).ToChecked();
    }
    {% for name, runtime_enabled_feature_name in unscopables %}
    {% filter runtime_enabled(runtime_enabled_feature_name) %}
    unscopables->CreateDataProperty(
        context, V8AtomicString(isolate, "{{name}}"), v8::True(isolate))
        .FromJust();
    {% endfilter %}
    {% endfor %}
    prototype_object->CreateDataProperty(
        context, unscopables_symbol, unscopables).FromJust();
  }
  {% endif %}{# unscopables #}

  {% if conditional_attributes or conditional_methods %}
  v8::Local<v8::Signature> signature = v8::Signature::New(isolate, interface_template);
  {% endif %}
  {% if conditional_attributes or conditional_methods or conditional_interface_objects %}
  ExecutionContext* execution_context = ToExecutionContext(context);
  DCHECK(execution_context);
  {% if has_conditional_secure_attributes or has_conditional_secure_methods %}
  bool is_secure_context = (execution_context && execution_context->IsSecureContext());
  {% endif %}

  {% set attributes_on_instance = conditional_attributes | selectattr('on_instance') | list %}
  {% set methods_on_instance = conditional_methods | selectattr('on_instance') | list %}
  {% if attributes_on_instance or conditional_interface_objects or methods_on_instance %}
  if (!instance_object.IsEmpty()) {
    {{install_conditional_attributes(attributes_on_instance) | trim | indent(4)}}
    {{install_conditional_interface_objects(conditional_interface_objects) | trim | indent(4)}}
    {{install_conditional_methods(methods_on_instance) | trim | indent(4)}}
  }
  {% endif %}

  {% set attributes_on_prototype = conditional_attributes | selectattr('on_prototype') | list %}
  {% set attributes_on_interface = conditional_attributes | selectattr('on_interface') | list %}
  {% set methods_on_prototype = conditional_methods | selectattr('on_prototype') | list %}
  {% set methods_on_interface = conditional_methods | selectattr('on_interface') | list %}
  {% if attributes_on_prototype or attributes_on_interface or methods_on_prototype or methods_on_interface %}
  if (!prototype_object.IsEmpty() || !interface_object.IsEmpty()) {
    {{install_conditional_attributes(attributes_on_prototype + attributes_on_interface) | trim | indent(4)}}
    {{install_conditional_methods(methods_on_prototype + methods_on_interface) | trim | indent(4)}}
  }
  {% endif %}
  {% endif %}{# conditional_attributes or conditional_methods #}
}
{% endif %}

{% endblock %}{# install_conditional_features #}
{##############################################################################}
{% block partial_interface %}{% endblock %}
}  // namespace blink

{% endfilter %}{# format_blink_cpp_source_code #}
