{% extends 'interface_base.cc.tmpl' %}

{% from 'methods.cc.tmpl' import runtime_timer_scope, runtime_timer_scope_disabled_by_default %}

{##############################################################################}
{% block indexed_property_getter %}
{% if indexed_property_getter and not indexed_property_getter.is_custom %}
{% set getter = indexed_property_getter %}
static void IndexedPropertyGetter(
    uint32_t index,
    const v8::PropertyCallbackInfo<v8::Value>& info) {
  {% if getter.is_raises_exception %}
  ExceptionState exception_state(info.GetIsolate(), ExceptionState::kIndexedGetterContext, "{{interface_name}}");
  {% endif %}

  {{cpp_class}}* impl = {{v8_class}}::ToImpl(info.Holder());

  // We assume that all the implementations support length() method, although
  // the spec doesn't require that length() must exist.  It's okay that
  // the interface does not have length attribute as long as the
  // implementation supports length() member function.
  if (index >= impl->length())
    return;  // Returns undefined due to out-of-range.

  {% set getter_name = getter.name or 'AnonymousIndexedGetter' %}
  {% set getter_arguments = ['index'] %}
  {% if getter.is_call_with_script_state %}
  ScriptState* script_state = ScriptState::ForRelevantRealm(info);
  {% set getter_arguments = ['script_state'] + getter_arguments %}
  {% endif %}
  {% if getter.is_raises_exception %}
  {% set getter_arguments = getter_arguments + ['exception_state'] %}
  {% endif %}
  {{getter.cpp_type}} result = impl->{{getter_name}}({{getter_arguments | join(', ')}});
  {{getter.v8_set_return_value}};
}

{% endif %}
{% endblock %}


{##############################################################################}
{% block indexed_property_getter_callback %}
{% if indexed_property_getter or named_property_getter %}
{% set getter = indexed_property_getter or named_property_getter %}
void {{v8_class_or_partial}}::IndexedPropertyGetterCallback(
    uint32_t index, const v8::PropertyCallbackInfo<v8::Value>& info) {
  {{ runtime_timer_scope_disabled_by_default(runtime_call_stats.indexed_property_getter_counter) }}
  {% if indexed_property_getter %}

  {% if getter.is_custom %}
  {{v8_class}}::IndexedPropertyGetterCustom(index, info);
  {% else %}
  {{internal_namespace}}::IndexedPropertyGetter(index, info);
  {% endif %}

  {% else %}{# otherwise, named property #}

  const AtomicString& property_name = AtomicString::Number(index);

  {% if getter.is_custom %}
  {{v8_class}}::NamedPropertyGetterCustom(property_name, info);
  {% else %}
  {{internal_namespace}}::NamedPropertyGetter(property_name, info);
  {% endif %}

  {% endif %}{# indexed_property_getter #}
}

{% endif %}
{% endblock %}


{##############################################################################}
{% block indexed_property_setter %}
{% from 'utilities.cc.tmpl' import v8_value_to_local_cpp_value %}
{% if indexed_property_setter and not indexed_property_setter.is_custom %}
{% set setter = indexed_property_setter %}
static void IndexedPropertySetter(
    uint32_t index,
    v8::Local<v8::Value> v8_value,
    const v8::PropertyCallbackInfo<v8::Value>& info) {
  {% if setter.has_exception_state %}
  ExceptionState exception_state(
      info.GetIsolate(),
      ExceptionState::kIndexedSetterContext,
      "{{interface_name}}");
  {% endif %}
  {% if setter.is_ce_reactions %}
  CEReactionsScope ce_reactions_scope;
  {% endif %}

  {{cpp_class}}* impl = {{v8_class}}::ToImpl(info.Holder());
  {{v8_value_to_local_cpp_value(setter) | trim | indent(2)}}
  {% if setter.has_type_checking_interface %}
  {# Type checking for interface types (if interface not implemented, throw
     TypeError), per http://www.w3.org/TR/WebIDL/#es-interface #}
  if (!property_value{% if setter.is_nullable %} && !IsUndefinedOrNull(v8_value){% endif %}) {
    exception_state.ThrowTypeError("The provided value is not of type '{{setter.idl_type}}'.");
    return;
  }
  {% endif %}

  {% set setter_name = setter.name or 'AnonymousIndexedSetter' %}
  {% set setter_arguments = ['index', 'property_value'] %}
  {% if setter.is_call_with_script_state %}
  ScriptState* script_state = ScriptState::ForRelevantRealm(info);
  {% set setter_arguments = ['script_state'] + setter_arguments %}
  {% endif %}
  {% if setter.is_raises_exception %}
  {% set setter_arguments = setter_arguments + ['exception_state'] %}
  {% endif %}
  IndexedPropertySetterResult result = impl->{{setter_name}}({{setter_arguments | join(', ')}});
  {% if setter.is_raises_exception %}
  if (exception_state.HadException())
    return;
  {% endif %}
  if (result == IndexedPropertySetterResult::kDidNotIntercept)
    return;
  V8SetReturnValue(info, v8_value);
}

{% endif %}
{% endblock %}


{##############################################################################}
{% block indexed_property_setter_callback %}
{% if indexed_property_getter or named_property_setter %}
{% set setter = indexed_property_setter or named_property_setter %}
void {{v8_class_or_partial}}::IndexedPropertySetterCallback(
    uint32_t index,
    v8::Local<v8::Value> v8_value,
    const v8::PropertyCallbackInfo<v8::Value>& info) {
  {% if indexed_property_setter %}

  {% if setter.is_custom %}
  {{v8_class}}::IndexedPropertySetterCustom(index, v8_value, info);
  {% else %}
  {{internal_namespace}}::IndexedPropertySetter(index, v8_value, info);
  {% endif %}

  {% elif not indexed_property_getter and named_property_setter %}

  const AtomicString& property_name = AtomicString::Number(index);

  {% if setter.is_custom %}
  {{v8_class}}::NamedPropertySetterCustom(property_name, v8_value, info);
  {% else %}
  {{internal_namespace}}::NamedPropertySetter(property_name, v8_value, info);
  {% endif %}

  {% else %}{# neither of indexed_property_setter nor named_property_setter #}

  // No indexed property setter defined.  Do not fall back to the default
  // setter.
  V8SetReturnValue(info, v8::Null(info.GetIsolate()));
  if (info.ShouldThrowOnError()) {
    ExceptionState exception_state(info.GetIsolate(),
                                   ExceptionState::kIndexedSetterContext,
                                   "{{interface_name}}");
    {% if setter.is_ce_reactions %}
    CEReactionsScope ce_reactions_scope;
    {% endif %}
    exception_state.ThrowTypeError("Index property setter is not supported.");
  }

  {% endif %}{# indexed/named_property_setter #}
}

{% endif %}
{% endblock %}


{##############################################################################}
{% block indexed_property_descriptor %}
{% if indexed_property_getter %}
static void IndexedPropertyDescriptor(
    uint32_t index, const v8::PropertyCallbackInfo<v8::Value>& info) {
  // https://heycam.github.io/webidl/#LegacyPlatformObjectGetOwnProperty
  // Steps 1.1 to 1.2.4 are covered here: we rely on indexedPropertyGetter() to
  // call the getter function and check that |index| is a valid property index,
  // in which case it will have set info.GetReturnValue() to something other
  // than undefined.
  {{v8_class_or_partial}}::IndexedPropertyGetterCallback(index, info);
  v8::Local<v8::Value> getter_value = info.GetReturnValue().Get();
  if (!getter_value->IsUndefined()) {
    // 1.2.5. Let |desc| be a newly created Property Descriptor with no fields.
    // 1.2.6. Set desc.[[Value]] to the result of converting value to an
    //        ECMAScript value.
    // 1.2.7. If O implements an interface with an indexed property setter,
    //        then set desc.[[Writable]] to true, otherwise set it to false.
    v8::PropertyDescriptor desc(getter_value, {% if indexed_property_setter %}true{% else %}false{% endif %});
    // 1.2.8. Set desc.[[Enumerable]] and desc.[[Configurable]] to true.
    desc.set_enumerable(true);
    desc.set_configurable(true);
    // 1.2.9. Return |desc|.
    V8SetReturnValue(info, desc);
  }
}

{% endif %}
{% endblock %}


{##############################################################################}
{% block named_property_descriptor %}
{% if not indexed_property_getter and named_property_getter %}
static void NamedPropertyDescriptor(
    uint32_t index, const v8::PropertyCallbackInfo<v8::Value>& info) {
  // This function is called when an IDL interface supports named properties
  // but not indexed properties. When a numeric property is queried, V8 calls
  // indexedPropertyDescriptorCallback(), which calls this function.

  {% if named_property_getter.is_enumerable %}
  // Since we initialize our indexed and named property handlers differently
  // (the former use descriptors and definers, the latter uses a query
  // callback), we need to inefficiently call the query callback and convert
  // the v8::PropertyAttribute integer it returns into a v8::PropertyDescriptor
  // expected by a descriptor callback.
  // TODO(rakuco): remove this hack once we switch named property handlers to
  // using descriptor and definer callbacks (bug 764633).
  const AtomicString& index_as_name = AtomicString::Number(index);
  {% if named_property_getter.is_custom_property_query %}
  {{v8_class}}::NamedPropertyQueryCustom(index_as_name, info);
  {% else %}
  {{internal_namespace}}::NamedPropertyQuery(index_as_name, info);
  {% endif %}
  v8::Local<v8::Value> getter_value = info.GetReturnValue().Get();
  if (!getter_value->IsUndefined()) {
    DCHECK(getter_value->IsInt32());
    const int32_t props =
        getter_value->ToInt32(info.GetIsolate()->GetCurrentContext())
            .ToLocalChecked()
            ->Value();
    v8::PropertyDescriptor desc(V8String(info.GetIsolate(), index_as_name),
                                !(props & v8::ReadOnly));
    desc.set_enumerable(!(props & v8::DontEnum));
    desc.set_configurable(!(props & v8::DontDelete));
    V8SetReturnValue(info, desc);
  }
  {% else %}{# TODO(rakuco): drop this once we remove [NotEnumerable] getters #}
  // This IDL interface defines a [NotEnumerable] getter. We need to do
  // something similar to indexedPropertyDescriptor(): call
  // indexedPropertyGetterCallback, let it end up calling the named property
  // getter and, if all goes well, we create a v8::PropertyDescriptor with the
  // right values.
  {{v8_class_or_partial}}::IndexedPropertyGetterCallback(index, info);
  v8::Local<v8::Value> getter_value = info.GetReturnValue().Get();
  if (!getter_value->IsUndefined()) {
    v8::PropertyDescriptor desc(getter_value, {% if named_property_setter %}true{% else %}false{% endif %});
    desc.set_enumerable(false);
    desc.set_configurable(true);
    V8SetReturnValue(info, desc);
  }
  {% endif %}
}

{% endif %}
{% endblock %}


{##############################################################################}
{% block indexed_property_descriptor_callback %}
{% if indexed_property_getter or named_property_getter %}
void {{v8_class_or_partial}}::IndexedPropertyDescriptorCallback(
    uint32_t index, const v8::PropertyCallbackInfo<v8::Value>& info) {
  {% if indexed_property_getter %}
  {{internal_namespace}}::IndexedPropertyDescriptor(index, info);
  {% else %}{# The interface only supports named properties. #}
  {{internal_namespace}}::NamedPropertyDescriptor(index, info);
  {% endif %}{# indexed_property_getter #}
}

{% endif %}
{% endblock %}


{##############################################################################}
{% block indexed_property_deleter %}
{% if indexed_property_deleter and not indexed_property_deleter.is_custom %}
{% set deleter = indexed_property_deleter %}
static void IndexedPropertyDeleter(
    uint32_t index, const v8::PropertyCallbackInfo<v8::Boolean>& info) {
  {% if deleter.is_raises_exception %}
  ExceptionState exception_state(
      info.GetIsolate(),
      ExceptionState::kIndexedDeletionContext,
      "{{interface_name}}");
  {% endif %}
  {% if deleter.is_ce_reactions %}
  CEReactionsScope ce_reactions_scope;
  {% endif %}

  {{cpp_class}}* impl = {{v8_class}}::ToImpl(info.Holder());

  {% set deleter_name = deleter.name or 'AnonymousIndexedDeleter' %}
  {% set deleter_arguments = ['index'] %}
  {% if deleter.is_call_with_script_state %}
  ScriptState* script_state = ScriptState::ForRelevantRealm(info);
  {% set deleter_arguments = ['script_state'] + deleter_arguments %}
  {% endif %}
  {% if deleter.is_raises_exception %}
  {% set deleter_arguments = deleter_arguments + ['exception_state'] %}
  {% endif %}
  NamedPropertyDeleterResult result = impl->{{deleter_name}}({{deleter_arguments | join(', ')}});
  {% if deleter.is_raises_exception %}
  if (exception_state.HadException())
    return;
  {% endif %}
  if (result == NamedPropertyDeleterResult::kDidNotIntercept)
    return;
  V8SetReturnValue(info, result == NamedPropertyDeleterResult::kDeleted);
}

{% endif %}
{% endblock %}


{##############################################################################}
{% block indexed_property_deleter_callback %}
{% if indexed_property_deleter or named_property_deleter %}
{% set deleter = indexed_property_deleter or named_property_deleter %}
void {{v8_class_or_partial}}::IndexedPropertyDeleterCallback(
    uint32_t index, const v8::PropertyCallbackInfo<v8::Boolean>& info) {
  {% if indexed_property_deleter %}

  {% if deleter.is_custom %}
  {{v8_class}}::IndexedPropertyDeleterCustom(index, info);
  {% else %}
  {{internal_namespace}}::IndexedPropertyDeleter(index, info);
  {% endif %}

  {% else %}{# otherwise, named property #}

  const AtomicString& property_name = AtomicString::Number(index);

  {% if deleter.is_custom %}
  {{v8_class}}::NamedPropertyDeleterCustom(property_name, info);
  {% else %}
  {{internal_namespace}}::NamedPropertyDeleter(property_name, info);
  {% endif %}

  {% endif %}{# indexed_property_deleter #}
}

{% endif %}
{% endblock %}


{##############################################################################}
{% block indexed_property_definer_callback %}
{% if indexed_property_getter %}
void {{v8_class_or_partial}}::IndexedPropertyDefinerCallback(
    uint32_t index,
    const v8::PropertyDescriptor& desc,
    const v8::PropertyCallbackInfo<v8::Value>& info) {
{% if indexed_property_setter %}
  // https://heycam.github.io/webidl/#legacy-platform-object-defineownproperty
  // 3.9.3. [[DefineOwnProperty]]
  // step 1.1. If the result of calling IsDataDescriptor(Desc) is false, then
  //   return false.
  if (desc.has_get() || desc.has_set()) {
    V8SetReturnValue(info, v8::Null(info.GetIsolate()));
    if (info.ShouldThrowOnError()) {
      ExceptionState exception_state(info.GetIsolate(),
                                     ExceptionState::kIndexedSetterContext,
                                     "{{interface_name}}");
      exception_state.ThrowTypeError("Accessor properties are not allowed.");
    }
    return;
  }

  // Return nothing and fall back to indexedPropertySetterCallback.
{% else %}{# indexed_property_setter #}
  // https://heycam.github.io/webidl/#legacy-platform-object-defineownproperty
  // 3.9.3. [[DefineOwnProperty]]
  // step 1.2. If O does not implement an interface with an indexed property
  //   setter, then return false.
  //
  // https://html.spec.whatwg.org/C/window-object.html#windowproxy-defineownproperty
  // 7.4.6 [[DefineOwnProperty]] (P, Desc)
  // step 2.1. If P is an array index property name, return false.
  V8SetReturnValue(info, v8::Null(info.GetIsolate()));
  if (info.ShouldThrowOnError()) {
    ExceptionState exception_state(info.GetIsolate(),
                                   ExceptionState::kIndexedSetterContext,
                                   "{{interface_name}}");
    exception_state.ThrowTypeError("Index property setter is not supported.");
  }
{% endif %}{# indexed_property_setter #}
}

{% endif %}{# indexed_property_getter #}
{% endblock %}


{##############################################################################}
{% block named_property_getter %}
{% if named_property_getter and not named_property_getter.is_custom %}
{% set getter = named_property_getter %}
static void NamedPropertyGetter(const AtomicString& name,
                                const v8::PropertyCallbackInfo<v8::Value>& info) {
  {% if getter.is_raises_exception %}
  const std::string& name_in_utf8 = name.Utf8();
  ExceptionState exception_state(
      info.GetIsolate(),
      ExceptionState::kGetterContext,
      "{{interface_name}}",
      name_in_utf8.c_str());
  {% endif %}
  {% if getter.is_call_with_script_state %}
  ScriptState* script_state = ScriptState::ForRelevantRealm(info);
  {% endif %}

  {{cpp_class}}* impl = {{v8_class}}::ToImpl(info.Holder());
  {% if getter.use_output_parameter_for_result %}
  {{getter.cpp_type}} result;
  {{getter.cpp_value}};
  {% else %}
  {{getter.cpp_type}} result = {{getter.cpp_value}};
  {% endif %}
  if ({{getter.is_null_expression}})
    return;
  {{getter.v8_set_return_value}};
}

{% endif %}
{% endblock %}


{##############################################################################}
{% block named_property_getter_callback %}
{% if named_property_getter %}
{% set getter = named_property_getter %}
void {{v8_class_or_partial}}::NamedPropertyGetterCallback(
    v8::Local<v8::Name> name, const v8::PropertyCallbackInfo<v8::Value>& info) {
  {{ runtime_timer_scope_disabled_by_default(runtime_call_stats.named_property_getter_counter) }}
  if (!name->IsString())
    return;
  const AtomicString& property_name = ToCoreAtomicString(name.As<v8::String>());

  {% if getter.is_custom %}
  {{v8_class}}::NamedPropertyGetterCustom(property_name, info);
  {% else %}
  {{internal_namespace}}::NamedPropertyGetter(property_name, info);
  {% endif %}
}

{% endif %}
{% endblock %}


{##############################################################################}
{% block named_property_setter %}
{% from 'utilities.cc.tmpl' import v8_value_to_local_cpp_value %}
{% if named_property_setter and not named_property_setter.is_custom %}
{% set setter = named_property_setter %}
static void NamedPropertySetter(
    const AtomicString& name,
    v8::Local<v8::Value> v8_value,
    const v8::PropertyCallbackInfo<v8::Value>& info) {
  {% if setter.has_exception_state %}
  const std::string& name_in_utf8 = name.Utf8();
  ExceptionState exception_state(
      info.GetIsolate(),
      ExceptionState::kSetterContext,
      "{{interface_name}}",
      name_in_utf8.c_str());
  {% endif %}
  {% if setter.is_ce_reactions %}
  CEReactionsScope ce_reactions_scope;
  {% endif %}
  {% if setter.is_call_with_script_state %}
  ScriptState* script_state = ScriptState::ForRelevantRealm(info);
  {% endif %}

  {{cpp_class}}* impl = {{v8_class}}::ToImpl(info.Holder());
  {{v8_value_to_local_cpp_value(setter) | trim | indent(2)}}
  {% if setter.has_type_checking_interface %}
  {# Type checking for interface types (if interface not implemented, throw
     TypeError), per http://www.w3.org/TR/WebIDL/#es-interface #}
  if (!property_value{% if setter.is_nullable %} && !IsUndefinedOrNull(v8_value){% endif %}) {
    exception_state.ThrowTypeError("The provided value is not of type '{{setter.idl_type}}'.");
    return;
  }
  {% endif %}

  {% set setter_name = setter.name or 'AnonymousNamedSetter' %}
  {% set setter_arguments = ['name', 'property_value'] %}
  {% if setter.is_call_with_script_state %}
  {% set setter_arguments = ['script_state'] + setter_arguments %}
  {% endif %}
  {% if setter.is_raises_exception %}
  {% set setter_arguments =  setter_arguments + ['exception_state'] %}
  {% endif %}
  NamedPropertySetterResult result = impl->{{setter_name}}({{setter_arguments | join(', ')}});
  {% if setter.is_raises_exception %}
  if (exception_state.HadException())
    return;
  {% endif %}
  if (result == NamedPropertySetterResult::kDidNotIntercept)
    return;
  V8SetReturnValue(info, v8_value);
}

{% endif %}
{% endblock %}


{##############################################################################}
{% block named_property_setter_callback %}
{% if named_property_setter %}
{% set setter = named_property_setter %}
void {{v8_class_or_partial}}::NamedPropertySetterCallback(
    v8::Local<v8::Name> name,
    v8::Local<v8::Value> v8_value,
    const v8::PropertyCallbackInfo<v8::Value>& info) {
  {{ runtime_timer_scope_disabled_by_default(runtime_call_stats.named_property_setter_counter) }}
  if (!name->IsString())
    return;
  const AtomicString& property_name = ToCoreAtomicString(name.As<v8::String>());

  {% if setter.is_custom %}
  {{v8_class}}::NamedPropertySetterCustom(property_name, v8_value, info);
  {% else %}
  {{internal_namespace}}::NamedPropertySetter(property_name, v8_value, info);
  {% endif %}
}

{% endif %}
{% endblock %}


{##############################################################################}
{% block named_property_deleter %}
{% if named_property_deleter and not named_property_deleter.is_custom %}
{% set deleter = named_property_deleter %}
static void NamedPropertyDeleter(
    const AtomicString& name, const v8::PropertyCallbackInfo<v8::Boolean>& info) {
  {% if deleter.is_raises_exception %}
  const std::string& name_in_utf8 = name.Utf8();
  ExceptionState exception_state(
      info.GetIsolate(),
      ExceptionState::kDeletionContext,
      "{{interface_name}}",
      name_in_utf8.c_str());
  {% endif %}
  {% if deleter.is_ce_reactions %}
  CEReactionsScope ce_reactions_scope;
  {% endif %}
  {% if deleter.is_call_with_script_state %}
  ScriptState* script_state = ScriptState::ForRelevantRealm(info);
  {% endif %}

  {{cpp_class}}* impl = {{v8_class}}::ToImpl(info.Holder());

  {% set deleter_name = deleter.name or 'AnonymousNamedDeleter' %}
  {% set deleter_arguments = ['name'] %}
  {% if deleter.is_call_with_script_state %}
  {% set deleter_arguments = ['script_state'] + deleter_arguments %}
  {% endif %}
  {% if deleter.is_raises_exception %}
  {% set deleter_arguments = deleter_arguments + ['exception_state'] %}
  {% endif %}
  NamedPropertyDeleterResult result = impl->{{deleter_name}}({{deleter_arguments | join(', ')}});
  {% if deleter.is_raises_exception %}
  if (exception_state.HadException())
    return;
  {% endif %}
  if (result == NamedPropertyDeleterResult::kDidNotIntercept)
    return;
  V8SetReturnValue(info, result == NamedPropertyDeleterResult::kDeleted);
}

{% endif %}
{% endblock %}


{##############################################################################}
{% block named_property_deleter_callback %}
{% if named_property_deleter %}
{% set deleter = named_property_deleter %}
void {{v8_class_or_partial}}::NamedPropertyDeleterCallback(
    v8::Local<v8::Name> name, const v8::PropertyCallbackInfo<v8::Boolean>& info) {
  if (!name->IsString())
    return;
  const AtomicString& property_name = ToCoreAtomicString(name.As<v8::String>());

  {% if deleter.is_custom %}
  {{v8_class}}::NamedPropertyDeleterCustom(property_name, info);
  {% else %}
  {{internal_namespace}}::NamedPropertyDeleter(property_name, info);
  {% endif %}
}

{% endif %}
{% endblock %}


{##############################################################################}
{% block named_property_query %}
{% if named_property_getter and named_property_getter.is_enumerable and
      not named_property_getter.is_custom_property_query %}
{% set getter = named_property_getter %}
{# If there is an enumerator, there MUST be a query method to properly
   communicate property attributes. #}
{% if indexed_property_getter %}
static void NamedPropertyQuery(
    const AtomicString& name, const v8::PropertyCallbackInfo<v8::Integer>& info) {
{% else %}
{# If we do not have an indexed property getter, this function is called #}
{# from namedPropertyDescriptor(), whose v8::PropertyCallbackInfo has a #}
{# v8::Value instead of a v8::Integer. We use this template trick to make #}
{# the compiler accept the call. #}
{# TODO(rakuco): remove this hack once we switch named property handlers to #}
{# using descriptor and definer callbacks (bug 764633). #}
template <typename T>
static void NamedPropertyQuery(
    const AtomicString& name, const v8::PropertyCallbackInfo<T>& info) {
{% endif %}
  const std::string& name_in_utf8 = name.Utf8();
  ExceptionState exception_state(
      info.GetIsolate(),
      ExceptionState::kGetterContext,
      "{{interface_name}}",
      name_in_utf8.c_str());
  {% if getter.is_call_with_script_state %}
  ScriptState* script_state = ScriptState::ForRelevantRealm(info);
  {% endif %}

  {{cpp_class}}* impl = {{v8_class}}::ToImpl(info.Holder());

  {% set getter_arguments = ['name', 'exception_state'] %}
  {% if getter.is_call_with_script_state %}
  {% set getter_arguments = ['script_state'] + getter_arguments %}
  {% endif %}
  bool result = impl->NamedPropertyQuery({{getter_arguments | join(', ')}});
  if (!result)
    return;
  // https://heycam.github.io/webidl/#LegacyPlatformObjectGetOwnProperty
  // 2.7. If |O| implements an interface with a named property setter, then set
  //      desc.[[Writable]] to true, otherwise set it to false.
  // 2.8. If |O| implements an interface with the
  //      [LegacyUnenumerableNamedProperties] extended attribute, then set
  //      desc.[[Enumerable]] to false, otherwise set it to true.
  {% if named_property_setter %}
  {% set desc_properties = ['v8::None'] %}
  {% else %}
  {% set desc_properties = ['v8::ReadOnly'] %}
  {% endif %}
  {% if has_legacy_unenumerable_named_properties %}
  {% set desc_properties = ['v8::DontEnum'] + desc_properties %}
  {% endif %}
  V8SetReturnValueInt(info, {{desc_properties | join(' | ')}});
}

{% endif %}
{% endblock %}


{##############################################################################}
{% block named_property_query_callback %}
{% if named_property_getter and named_property_getter.is_enumerable %}
{% set getter = named_property_getter %}
void {{v8_class_or_partial}}::NamedPropertyQueryCallback(
    v8::Local<v8::Name> name, const v8::PropertyCallbackInfo<v8::Integer>& info) {
  {{ runtime_timer_scope_disabled_by_default(runtime_call_stats.named_property_query_counter) }}
  if (!name->IsString())
    return;
  const AtomicString& property_name = ToCoreAtomicString(name.As<v8::String>());

  {% if getter.is_custom_property_query %}
  {{v8_class}}::NamedPropertyQueryCustom(property_name, info);
  {% else %}
  {{internal_namespace}}::NamedPropertyQuery(property_name, info);
  {% endif %}
}

{% endif %}
{% endblock %}


{##############################################################################}
{% block named_property_enumerator %}
{% if named_property_getter and named_property_getter.is_enumerable and
      not named_property_getter.is_custom_property_enumerator %}
static void NamedPropertyEnumerator(const v8::PropertyCallbackInfo<v8::Array>& info) {
  ExceptionState exception_state(
      info.GetIsolate(),
      ExceptionState::kEnumerationContext,
      "{{interface_name}}");

  {{cpp_class}}* impl = {{v8_class}}::ToImpl(info.Holder());

  Vector<String> names;
  impl->NamedPropertyEnumerator(names, exception_state);
  if (exception_state.HadException())
    return;
  V8SetReturnValue(info, ToV8(names, info.Holder(), info.GetIsolate()).As<v8::Array>());
}

{% endif %}
{% endblock %}


{##############################################################################}
{% block named_property_enumerator_callback %}
{% if named_property_getter and named_property_getter.is_enumerable %}
{% set getter = named_property_getter %}
void {{v8_class_or_partial}}::NamedPropertyEnumeratorCallback(
    const v8::PropertyCallbackInfo<v8::Array>& info) {
  {% if getter.is_custom_property_enumerator %}
  {{v8_class}}::NamedPropertyEnumeratorCustom(info);
  {% else %}
  {{internal_namespace}}::NamedPropertyEnumerator(info);
  {% endif %}
}

{% endif %}
{% endblock %}


{##############################################################################}
{% block named_constructor %}
{% from 'methods.cc.tmpl' import generate_constructor with context %}
{% if named_constructor %}
{% set active_scriptwrappable_inheritance =
    'kInheritFromActiveScriptWrappable'
    if active_scriptwrappable else
    'kNotInheritFromActiveScriptWrappable' %}
// 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
const WrapperTypeInfo {{snake_case_v8_class}}_constructor_wrapper_type_info = {
    gin::kEmbedderBlink,
    {{v8_class}}Constructor::DomTemplate,
    {{install_conditional_features_func or 'nullptr'}},
    "{{interface_name}}",
    nullptr,
    WrapperTypeInfo::kWrapperTypeObjectPrototype,
    WrapperTypeInfo::{{wrapper_class_id}},
    WrapperTypeInfo::{{active_scriptwrappable_inheritance}},
};
#if defined(COMPONENT_BUILD) && defined(WIN32) && defined(__clang__)
#pragma clang diagnostic pop
#endif

{{generate_constructor(named_constructor)}}
v8::Local<v8::FunctionTemplate> {{v8_class}}Constructor::DomTemplate(
    v8::Isolate* isolate, const DOMWrapperWorld& world) {
  static int dom_template_key; // This address is used for a key to look up the dom template.
  V8PerIsolateData* data = V8PerIsolateData::From(isolate);
  v8::Local<v8::FunctionTemplate> result =
      data->FindInterfaceTemplate(world, &dom_template_key);
  if (!result.IsEmpty())
    return result;

  result = v8::FunctionTemplate::New(isolate, {{v8_class}}ConstructorCallback);
  v8::Local<v8::ObjectTemplate> instance_template = result->InstanceTemplate();
  instance_template->SetInternalFieldCount({{v8_class}}::kInternalFieldCount);
  result->SetClassName(V8AtomicString(isolate, "{{named_constructor.name}}"));
  result->Inherit({{v8_class}}::DomTemplate(isolate, world));
  data->SetInterfaceTemplate(world, &dom_template_key, result);
  return result;
}

void {{v8_class}}Constructor::NamedConstructorAttributeGetter(
    v8::Local<v8::Name> property_name,
    const v8::PropertyCallbackInfo<v8::Value>& info) {
  v8::Local<v8::Context> creationContext = info.Holder()->CreationContext();
  V8PerContextData* per_context_data = V8PerContextData::From(creationContext);
  if (!per_context_data) {
    // TODO(yukishiino): Return a valid named constructor even after the context is detached
    return;
  }

  v8::Local<v8::Function> named_constructor =
      per_context_data->ConstructorForType({{v8_class}}Constructor::GetWrapperTypeInfo());

  // Set the prototype of named constructors to the regular constructor.
  static const V8PrivateProperty::SymbolKey kPrivatePropertyInitialized;
  auto private_property =
      V8PrivateProperty::GetSymbol(
          info.GetIsolate(), kPrivatePropertyInitialized);
  v8::Local<v8::Context> current_context = info.GetIsolate()->GetCurrentContext();
  v8::Local<v8::Value> private_value;

  if (!private_property.GetOrUndefined(named_constructor).ToLocal(&private_value) ||
      private_value->IsUndefined()) {
    v8::Local<v8::Function> interface =
        per_context_data->ConstructorForType({{v8_class}}::GetWrapperTypeInfo());
    v8::Local<v8::Value> interface_prototype =
        interface->Get(current_context, V8AtomicString(info.GetIsolate(), "prototype"))
        .ToLocalChecked();
    // https://heycam.github.io/webidl/#named-constructors
    // 8. Perform ! DefinePropertyOrThrow(F, "prototype",
    //        PropertyDescriptor{[[Value]]: proto, [[Writable]]: false,
    //                           [[Enumerable]]: false,
    //                           [Configurable]]: false}).
    const v8::PropertyAttribute prototype_attributes =
        static_cast<v8::PropertyAttribute>(v8::ReadOnly | v8::DontEnum | v8::DontDelete);
    bool result = named_constructor->DefineOwnProperty(
        current_context, V8AtomicString(info.GetIsolate(), "prototype"),
        interface_prototype, prototype_attributes).ToChecked();
    CHECK(result);
    private_property.Set(named_constructor, v8::True(info.GetIsolate()));
  }

  V8SetReturnValue(info, named_constructor);
}

{% endif %}
{% endblock %}

{##############################################################################}
{% block overloaded_constructor %}
{% if constructor_overloads %}
static void Constructor(const v8::FunctionCallbackInfo<v8::Value>& info) {
  ExceptionState exception_state(info.GetIsolate(), ExceptionState::kConstructionContext, "{{interface_name}}");
  {# This follows the overload resolution algorithm. #}
  {# https://heycam.github.io/webidl/#dfn-overload-resolution-algorithm #}
  {# 3. Initialize argcount to be min(maxarg, n). #}
  switch (std::min({{constructor_overloads.maxarg}}, info.Length())) {
    {# 4. Remove from S all entries whose type list is not of length argcount. #}
    {% for length, tests_constructors in constructor_overloads.length_tests_methods %}
    {# 12. If i = d, then: #}
    case {{length}}:
      {# Then resolve by testing argument #}
      {% for test, constructor in tests_constructors %}
      if ({{test}}) {
        {{internal_namespace}}::Constructor{{constructor.overload_index}}(info);
        return;
      }
      {% if "exception_state" in test %}
      if (exception_state.HadException()) {
        exception_state.RethrowV8Exception(exception_state.GetException());
        return;
      }
      {% endif %}
      {% endfor %}
      break;
    {% endfor %}
    default:
      {# Invalid arity, throw error #}
      {# Report full list of valid arities if gaps and above minimum #}
      {% if constructor_overloads.valid_arities %}
      if (info.Length() >= {{constructor_overloads.length}}) {
        exception_state.ThrowTypeError(ExceptionMessages::InvalidArity("{{constructor_overloads.valid_arities}}", info.Length()));
        return;
      }
      {% endif %}
      {# Otherwise just report "not enough arguments" #}
      exception_state.ThrowTypeError(ExceptionMessages::NotEnoughArguments({{constructor_overloads.length}}, info.Length()));
      return;
  }
  {# No match, throw error #}
  exception_state.ThrowTypeError("No matching constructor signature.");
}

{% endif %}
{% endblock %}


{##############################################################################}
{% block constructor_callback %}
{% if constructors or has_custom_constructor or has_html_constructor %}
{{exported}}void ConstructorCallback(const v8::FunctionCallbackInfo<v8::Value>& info) {
  {{ runtime_timer_scope_disabled_by_default(runtime_call_stats.constructor_counter) }}
  {% if measure_as %}
  ExecutionContext* execution_context_for_measurement = CurrentExecutionContext(info.GetIsolate());
  UseCounter::Count(execution_context_for_measurement, WebFeature::k{{measure_as('Constructor')}});
  {% if high_entropy %}
  Dactyloscoper::Record(execution_context_for_measurement, WebFeature::k{{measure_as('Constructor')}});
  {% endif %}
  {% endif %}
  if (!info.IsConstructCall()) {
    V8ThrowException::ThrowTypeError(
        info.GetIsolate(),
        ExceptionMessages::ConstructorNotCallableAsFunction("{{interface_name}}"));
    return;
  }

  if (ConstructorMode::Current(info.GetIsolate()) == ConstructorMode::kWrapExistingObject) {
    V8SetReturnValue(info, info.Holder());
    return;
  }

  {% if has_custom_constructor %}
  {{v8_class}}::ConstructorCustom(info);
  {% elif has_html_constructor %}
  V8HTMLConstructor::HtmlConstructor(
      info, *{{v8_class}}::GetWrapperTypeInfo(), HTMLElementType::k{{interface_name}});
  {% else %}
  {{internal_namespace}}::Constructor(info);
  {% endif %}
}

{% endif %}
{% endblock %}


{##############################################################################}
{% macro install_origin_safe_method(method, instance_template, prototype_template, interface_template, signature) %}
{% from 'utilities.cc.tmpl' import property_location %}
{# TODO(dcheng): Currently, bindings must create a function object for each
   realm as a hack to support the incumbent realm. Clean this up when Blink
   properly supports the incumbent realm. #}
{% set function_callback =
       '%s::%sMethodCallback' % (v8_class_or_partial, method.camel_case_name) %}
{% set property_attribute =
       'static_cast<v8::PropertyAttribute>(%s)' %
       ' | '.join(method.property_attributes or ['v8::None']) %}
{% set holder_check = 'V8DOMConfiguration::kCheckHolder' %}
static const V8DOMConfiguration::MethodConfiguration k{{method.camel_case_name}}OriginSafeMethodConfiguration[] = {
{% if method.is_per_world_bindings %}
{% set function_callback_for_main_world = '%sForMainWorld' % function_callback %}
    {
        "{{method.name}}",
        {{function_callback_for_main_world}},
        {{method.length}},
        {{property_attribute}},
        {{property_location(method)}},
        {{holder_check}},
        V8DOMConfiguration::kCheckAccess,
        V8DOMConfiguration::kHasSideEffect,
        V8DOMConfiguration::MainWorld,
    },
    {
        "{{method.name}}",
        {{function_callback}},
        {{method.length}},
        {{property_attribute}},
        {{property_location(method)}},
        {{holder_check}},
        V8DOMConfiguration::kCheckAccess,
        V8DOMConfiguration::kHasSideEffect,
        V8DOMConfiguration::NonMainWorlds,
    }
{% else %}
    {
        "{{method.name}}",
        {{function_callback}},
        {{method.length}},
        {{property_attribute}},
        {{property_location(method)}},
        {{holder_check}},
        V8DOMConfiguration::kCheckAccess,
        V8DOMConfiguration::kHasSideEffect,
        V8DOMConfiguration::kAllWorlds,
    }
{% endif %}
};
for (const auto& method_config : k{{method.camel_case_name}}OriginSafeMethodConfiguration)
  V8DOMConfiguration::InstallMethod(isolate, world, {{instance_template}}, {{prototype_template}}, {{interface_template}}, {{signature}}, method_config);
{%- endmacro %}


{##############################################################################}
{% macro install_indexed_property_handler(target) %}
{% set indexed_property_getter_callback =
       '%s::IndexedPropertyGetterCallback' % v8_class_or_partial %}
{% set indexed_property_setter_callback =
       '%s::IndexedPropertySetterCallback' % v8_class_or_partial
       if indexed_property_getter or named_property_setter else 'nullptr' %}
{% set indexed_property_descriptor_callback =
       '%s::IndexedPropertyDescriptorCallback' % v8_class_or_partial
       if indexed_property_getter or named_property_getter else 'nullptr' %}
{% set indexed_property_deleter_callback =
       '%s::IndexedPropertyDeleterCallback' % v8_class_or_partial
       if indexed_property_deleter or named_property_deleter else 'nullptr' %}
{% set indexed_property_enumerator_callback =
       'IndexedPropertyEnumerator<%s>' % cpp_class
       if indexed_property_getter.is_enumerable else 'nullptr' %}
{% set indexed_property_definer_callback =
       '%s::IndexedPropertyDefinerCallback' % v8_class_or_partial
       if indexed_property_getter else 'nullptr' %}
{% set property_handler_flags =
       'v8::PropertyHandlerFlags::kHasNoSideEffect'
       if indexed_property_getter.has_no_side_effect else 'v8::PropertyHandlerFlags::kNone' %}
v8::IndexedPropertyHandlerConfiguration indexedPropertyHandlerConfig(
    {{indexed_property_getter_callback}},
    {{indexed_property_setter_callback}},
    {{indexed_property_descriptor_callback}},
    {{indexed_property_deleter_callback}},
    {{indexed_property_enumerator_callback}},
    {{indexed_property_definer_callback}},
    v8::Local<v8::Value>(),
    {{property_handler_flags}});
{{target}}->SetHandler(indexedPropertyHandlerConfig);
{%- endmacro %}


{##############################################################################}
{% macro install_named_property_handler(target) %}
{% set named_property_getter_callback =
       '%s::NamedPropertyGetterCallback' % v8_class_or_partial %}
{% set named_property_setter_callback =
       '%s::NamedPropertySetterCallback' % v8_class_or_partial
       if named_property_setter else 'nullptr' %}
{% set named_property_query_callback =
       '%s::NamedPropertyQueryCallback' % v8_class_or_partial
       if named_property_getter.is_enumerable else 'nullptr' %}
{% set named_property_deleter_callback =
       '%s::NamedPropertyDeleterCallback' % v8_class_or_partial
       if named_property_deleter else 'nullptr' %}
{% set named_property_enumerator_callback =
       '%s::NamedPropertyEnumeratorCallback' % v8_class_or_partial
       if named_property_getter.is_enumerable else 'nullptr' %}
{% set property_handler_flags_list =
       ['int(v8::PropertyHandlerFlags::kOnlyInterceptStrings)'] %}
{% if not is_override_builtins %}
{% set property_handler_flags_list =
       property_handler_flags_list + ['int(v8::PropertyHandlerFlags::kNonMasking)'] %}
{% endif %}
{% if named_property_getter.has_no_side_effect %}
{% set property_handler_flags_list =
       property_handler_flags_list + ['int(v8::PropertyHandlerFlags::kHasNoSideEffect)'] %}
{% endif %}
{% set property_handler_flags =
       'static_cast<v8::PropertyHandlerFlags>(%s)' %
           ' | '.join(property_handler_flags_list) %}
v8::NamedPropertyHandlerConfiguration namedPropertyHandlerConfig({{named_property_getter_callback}}, {{named_property_setter_callback}}, {{named_property_query_callback}}, {{named_property_deleter_callback}}, {{named_property_enumerator_callback}}, v8::Local<v8::Value>(), {{property_handler_flags}});
{{target}}->SetHandler(namedPropertyHandlerConfig);
{%- endmacro %}


{##############################################################################}
{% block get_dom_template %}
{% if not is_array_buffer_or_view %}
v8::Local<v8::FunctionTemplate> {{v8_class}}::DomTemplate(
    v8::Isolate* isolate, const DOMWrapperWorld& world) {
  {% set install_template_function = '%s::install_%s_template_function_' % (v8_class, snake_case_v8_class) if has_partial_interface else 'Install%sTemplate' % v8_class %}
  return V8DOMConfiguration::DomClassTemplate(
      isolate, world, const_cast<WrapperTypeInfo*>({{v8_class}}::GetWrapperTypeInfo()),
      {{install_template_function}});
}

{% endif %}
{% endblock %}


{##############################################################################}
{% block get_dom_template_for_named_properties_object %}
{% if has_named_properties_object %}
v8::Local<v8::FunctionTemplate>
{{v8_class}}::DomTemplateForNamedPropertiesObject(
    v8::Isolate* isolate, const DOMWrapperWorld& world) {
  v8::Local<v8::FunctionTemplate> parentTemplate =
      V8{{parent_interface}}::DomTemplate(isolate, world);

  v8::Local<v8::FunctionTemplate> named_properties_function_template =
      v8::FunctionTemplate::New(isolate,
                                V8ObjectConstructor::IsValidConstructorMode);
  named_properties_function_template->SetClassName(
      V8AtomicString(isolate, "{{interface_name}}Properties"));
  named_properties_function_template->Inherit(parentTemplate);

  v8::Local<v8::ObjectTemplate> named_properties_object_template =
      named_properties_function_template->PrototypeTemplate();
  named_properties_object_template->SetInternalFieldCount(
      {{v8_class}}::kInternalFieldCount);
  // Named Properties object has SetPrototype method of Immutable Prototype Exotic Objects
  named_properties_object_template->SetImmutableProto();
  V8DOMConfiguration::SetClassString(
      isolate, named_properties_object_template, "{{interface_name}}Properties");
  {{install_named_property_handler('named_properties_object_template') | trim | indent(2)}}

  return named_properties_function_template;
}

{% endif %}
{% endblock %}


{##############################################################################}
{% block has_instance %}
{% if not is_array_buffer_or_view %}

bool {{v8_class}}::HasInstance(v8::Local<v8::Value> v8_value, v8::Isolate* isolate) {
  return V8PerIsolateData::From(isolate)->HasInstance({{v8_class}}::GetWrapperTypeInfo(), v8_value);
}

v8::Local<v8::Object> {{v8_class}}::FindInstanceInPrototypeChain(
    v8::Local<v8::Value> v8_value, v8::Isolate* isolate) {
  return V8PerIsolateData::From(isolate)->FindInstanceInPrototypeChain(
      {{v8_class}}::GetWrapperTypeInfo(), v8_value);
}

{% endif %}
{% endblock %}


{##############################################################################}
{% block to_impl %}
{% if interface_name == 'ArrayBuffer' or interface_name == 'SharedArrayBuffer' %}
{{cpp_class}}* V8{{interface_name}}::ToImpl(v8::Local<v8::Object> object) {
  DCHECK(object->Is{{interface_name}}());
  v8::Local<v8::{{interface_name}}> v8buffer = object.As<v8::{{interface_name}}>();
  // TODO(ahaas): The use of IsExternal is wrong here. Instead we should call
  // ToScriptWrappable(object)->ToImpl<ArrayBuffer>() and check for nullptr.
  // We can then also avoid the call to Externalize below.
  if (v8buffer->IsExternal()) {
    const WrapperTypeInfo* wrapper_type = ToWrapperTypeInfo(object);
    CHECK(wrapper_type);
    CHECK_EQ(wrapper_type->gin_embedder, gin::kEmbedderBlink);
    return ToScriptWrappable(object)->ToImpl<{{cpp_class}}>();
  }

  // Transfer the ownership of the allocated memory to an {{interface_name}} without
  // copying.
  auto backing_store = v8buffer->GetBackingStore();
  v8buffer->Externalize(backing_store);
  ArrayBufferContents contents(std::move(backing_store));
  {{cpp_class}}* buffer = {{cpp_class}}::Create(contents);
  v8::Local<v8::Object> associatedWrapper = buffer->AssociateWithWrapper(v8::Isolate::GetCurrent(), buffer->GetWrapperTypeInfo(), object);
  DCHECK(associatedWrapper == object);

  return buffer;
}

{% elif interface_name == 'ArrayBufferView' %}
{{cpp_class}}* V8ArrayBufferView::ToImpl(v8::Local<v8::Object> object) {
  DCHECK(object->IsArrayBufferView());
  ScriptWrappable* script_wrappable = ToScriptWrappable(object);
  if (script_wrappable)
    return script_wrappable->ToImpl<{{cpp_class}}>();

  if (object->IsInt8Array())
    return V8Int8Array::ToImpl(object);
  if (object->IsInt16Array())
    return V8Int16Array::ToImpl(object);
  if (object->IsInt32Array())
    return V8Int32Array::ToImpl(object);
  if (object->IsUint8Array())
    return V8Uint8Array::ToImpl(object);
  if (object->IsUint8ClampedArray())
    return V8Uint8ClampedArray::ToImpl(object);
  if (object->IsUint16Array())
    return V8Uint16Array::ToImpl(object);
  if (object->IsUint32Array())
    return V8Uint32Array::ToImpl(object);
  if (object->IsBigInt64Array())
    return V8BigInt64Array::ToImpl(object);
  if (object->IsBigUint64Array())
    return V8BigUint64Array::ToImpl(object);
  if (object->IsFloat32Array())
    return V8Float32Array::ToImpl(object);
  if (object->IsFloat64Array())
    return V8Float64Array::ToImpl(object);
  if (object->IsDataView())
    return V8DataView::ToImpl(object);

  NOTREACHED();
  return nullptr;
}

{% elif is_array_buffer_or_view %}
{{cpp_class}}* {{v8_class}}::ToImpl(v8::Local<v8::Object> object) {
  DCHECK(object->Is{{interface_name}}());
  ScriptWrappable* script_wrappable = ToScriptWrappable(object);
  if (script_wrappable)
    return script_wrappable->ToImpl<{{cpp_class}}>();

  v8::Local<v8::{{interface_name}}> v8_view = object.As<v8::{{interface_name}}>();
  v8::Local<v8::Object> array_buffer = v8_view->Buffer();
  {{cpp_class}}* typed_array = nullptr;
  if (array_buffer->IsArrayBuffer()) {
    typed_array = {{cpp_class}}::Create(
        V8ArrayBuffer::ToImpl(array_buffer),
        v8_view->ByteOffset(),
        v8_view->{% if interface_name == 'DataView' %}Byte{% endif %}Length());
  } else if (array_buffer->IsSharedArrayBuffer()) {
    typed_array = {{cpp_class}}::Create(
        V8SharedArrayBuffer::ToImpl(array_buffer),
        v8_view->ByteOffset(),
        v8_view->{% if interface_name == 'DataView' %}Byte{% endif %}Length());
  } else {
    NOTREACHED();
  }
  v8::Local<v8::Object> associated_wrapper =
        typed_array->AssociateWithWrapper(
            v8::Isolate::GetCurrent(), typed_array->GetWrapperTypeInfo(), object);
  DCHECK(associated_wrapper == object);

  return typed_array->ToImpl<{{cpp_class}}>();
}

{% endif %}
{% endblock %}


{##############################################################################}
{% block to_impl_with_type_check %}
{{cpp_class}}* {{v8_class}}::ToImplWithTypeCheck(
    v8::Isolate* isolate, v8::Local<v8::Value> value) {
{% if is_array_buffer_or_view %}
  return value->Is{{interface_name}}() ? ToImpl(v8::Local<v8::Object>::Cast(value)) : nullptr;
{% else %}
  return HasInstance(value, isolate) ? ToImpl(v8::Local<v8::Object>::Cast(value)) : nullptr;
{% endif %}
}

{% endblock %}


{##############################################################################}
{% block partial_interface %}
{% if has_partial_interface %}
{% if needs_runtime_enabled_installer %}
InstallRuntimeEnabledFeaturesFunction
{{v8_class}}::install_runtime_enabled_features_function_ =
    &{{v8_class}}::InstallRuntimeEnabledFeaturesImpl;
{% endif %}
{% if not is_array_buffer_or_view %}
InstallRuntimeEnabledFeaturesOnTemplateFunction
{{v8_class}}::install_runtime_enabled_features_on_template_function_ =
    &{{v8_class}}::InstallRuntimeEnabledFeaturesOnTemplate;
{% endif %}

InstallTemplateFunction
{{v8_class}}::install_{{snake_case_v8_class}}_template_function_ =
    &{{v8_class}}::Install{{v8_class}}Template;

void {{v8_class}}::UpdateWrapperTypeInfo(
    InstallTemplateFunction install_template_function,
    InstallRuntimeEnabledFeaturesFunction install_runtime_enabled_features_function,
    InstallRuntimeEnabledFeaturesOnTemplateFunction install_runtime_enabled_features_on_template_function,
    InstallConditionalFeaturesFunction install_conditional_features_function) {
  {{v8_class}}::install_{{snake_case_v8_class}}_template_function_ =
      install_template_function;

  {% if needs_runtime_enabled_installer %}
  CHECK(install_runtime_enabled_features_function);
  {{v8_class}}::install_runtime_enabled_features_function_ =
      install_runtime_enabled_features_function;

  {% endif %}
  {% if not is_array_buffer_or_view  %}
  CHECK(install_runtime_enabled_features_on_template_function);
  {{v8_class}}::install_runtime_enabled_features_on_template_function_ =
      install_runtime_enabled_features_on_template_function;
  {% endif %}

  if (install_conditional_features_function) {
    {{v8_class}}::GetWrapperTypeInfo()->install_conditional_features_function =
        install_conditional_features_function;
  }
}

{% for method in methods if method.overloads and method.overloads.has_partial_overloads %}
void {{v8_class}}::Register{{method.camel_case_name}}MethodForPartialInterface(void (*method)(const v8::FunctionCallbackInfo<v8::Value>&)) {
  {{internal_namespace}}::{{method.name}}MethodForPartialInterface = method;
}

{% endfor %}
{% endif %}{# has_partial_interface #}
{% endblock %}
