{#
 # Copyright 2017 The Cobalt Authors. All Rights Reserved.
 #
 # Licensed under the Apache License, Version 2.0 (the "License");
 # you may not use this file except in compliance with the License.
 # You may obtain a copy of the License at
 #
 #     http://www.apache.org/licenses/LICENSE-2.0
 #
 # Unless required by applicable law or agreed to in writing, software
 # distributed under the License is distributed on an "AS IS" BASIS,
 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 # See the License for the specific language governing permissions and
 # limitations under the License.
 #}

{% from 'macros.cc.template' import add_extra_arguments %}
{% from 'macros.cc.template' import call_cobalt_function %}
{% from 'macros.cc.template' import get_cobalt_value %}
{% from 'macros.cc.template' import check_if_object_implements_interface with context %}
{% from 'macros.cc.template' import constructor_implementation with context %}
{% from 'macros.cc.template' import function_implementation with context %}
{% from 'macros.cc.template' import get_impl_class_instance %}
{% from 'macros.cc.template' import nonstatic_function_prologue %}
{% from 'macros.cc.template' import overload_resolution_implementation with context %}
{% from 'macros.cc.template' import set_attribute_implementation with context %}
{% from 'macros.cc.template' import static_function_prologue %}

{% extends "interface-base.cc.template" %}

{% block includes %}
{{ super() }}
#include "{{generated_conversion_include}}"

#include "cobalt/script/callback_interface_traits.h"
#include "cobalt/script/v8c/v8c_array_buffer.h"
#include "cobalt/script/v8c/v8c_array_buffer_view.h"
#include "cobalt/script/v8c/callback_function_conversion.h"
#include "cobalt/script/v8c/conversion_helpers.h"
#include "cobalt/script/v8c/entry_scope.h"
#include "cobalt/script/v8c/helpers.h"
#include "cobalt/script/v8c/native_promise.h"
#include "cobalt/script/v8c/type_traits.h"
#include "cobalt/script/v8c/v8c_typed_arrays.h"
#include "cobalt/script/v8c/v8c_data_view.h"
#include "cobalt/script/v8c/v8c_callback_function.h"
#include "cobalt/script/v8c/v8c_callback_interface_holder.h"
#include "cobalt/script/v8c/v8c_engine.h"
#include "cobalt/script/v8c/v8c_exception_state.h"
#include "cobalt/script/v8c/v8c_global_environment.h"
#include "cobalt/script/v8c/v8c_property_enumerator.h"
#include "cobalt/script/v8c/v8c_value_handle.h"
#include "cobalt/script/v8c/wrapper_private.h"
#include "cobalt/script/v8c/common_v8c_bindings_code.h"
#include "v8/include/v8.h"

{% endblock includes %}

{% block using_directives %}
{{ super() }}
using cobalt::script::v8c::EntryScope;
using cobalt::script::v8c::EscapableEntryScope;
using cobalt::script::v8c::FromJSValue;
using cobalt::script::v8c::kConversionFlagClamped;
using cobalt::script::v8c::kConversionFlagNullable;
using cobalt::script::v8c::kConversionFlagObjectOnly;
using cobalt::script::v8c::kConversionFlagRestricted;
using cobalt::script::v8c::kConversionFlagTreatNullAsEmptyString;
using cobalt::script::v8c::kConversionFlagTreatUndefinedAsEmptyString;
using cobalt::script::v8c::kNoConversionFlags;
using cobalt::script::v8c::NewInternalString;
using cobalt::script::v8c::ToJSValue;
using cobalt::script::v8c::TypeTraits;
using cobalt::script::v8c::V8cExceptionState;
using cobalt::script::v8c::V8cGlobalEnvironment;
using cobalt::script::v8c::V8cPropertyEnumerator;
using cobalt::script::v8c::WrapperFactory;
using cobalt::script::v8c::WrapperPrivate;
{% endblock using_directives %}

{% block enumeration_declarations %}
{% if enumerations|length %}
// Declare and define these in the same namespace that the other overloads
// were brought into with the using declaration.
{% for enumeration in enumerations %}
void ToJSValue(
    v8::Isolate* isolate,
    {{impl_class}}::{{enumeration.name}} in_enum,
    v8::Local<v8::Value>* out_value);
void FromJSValue(v8::Isolate* context, v8::Local<v8::Value> value,
                 int conversion_flags, ExceptionState* exception_state,
                 {{impl_class}}::{{enumeration.name}}* out_enum);
{% endfor %}
{% endif %}
{% endblock enumeration_declarations %}

{% block top_level_unnamed_namespace %}
{% endblock top_level_unnamed_namespace %}

{% block implementation %}

namespace {

const int kInterfaceUniqueId = {{unique_id}};

{% if named_property_getter %}

void NamedPropertyGetterCallback(
    v8::Local<v8::Name> property,
    const v8::PropertyCallbackInfo<v8::Value>& info) {
  v8::Isolate* isolate = info.GetIsolate();
  v8::Local<v8::Object> object = info.Holder();
{{ nonstatic_function_prologue(impl_class) }}
  std::string property_name = *v8::String::Utf8Value(isolate, property);
  if (!impl->CanQueryNamedProperty(property_name)) {
    return;
  }
{{ call_cobalt_function(impl_class, named_property_getter.type,
                        named_property_getter.name, ["property_name"],
                        named_property_getter.raises_exception,
                        named_property_getter.call_with) }}
  if (exception_state.is_exception_set()) {
    return;
  }
  info.GetReturnValue().Set(result_value);
}

{% if not indexed_property_getter %}
void IndexedPropertyGetterCallback(
    uint32_t index,
    const v8::PropertyCallbackInfo<v8::Value>& info) {
  v8::Local<v8::String> as_string = (v8::Integer::New(info.GetIsolate(), index)->ToString(
                                     info.GetIsolate()->GetCurrentContext())).ToLocalChecked();
  NamedPropertyGetterCallback(as_string, info);
}
{% endif %}

void NamedPropertyQueryCallback(
    v8::Local<v8::Name> property,
    const v8::PropertyCallbackInfo<v8::Integer>& info) {
  v8::Isolate* isolate = info.GetIsolate();
  v8::Local<v8::Object> object = info.Holder();
{{ get_impl_class_instance(impl_class) }}
  std::string property_name = *v8::String::Utf8Value(isolate, property);
  bool result = impl->CanQueryNamedProperty(property_name);
  if (!result) {
    return;
  }

  // https://heycam.github.io/webidl/#LegacyPlatformObjectGetOwnProperty
  int properties = v8::None;
  // 2.7. If |O| implements an interface with a named property setter, then set
  //      desc.[[Writable]] to true, otherwise set it to false.
{% if named_property_setter %}
{% else %}
  properties |= v8::ReadOnly;
{% endif %}
  // 2.8. If |O| implements an interface with the
  //      [LegacyUnenumerableNamedProperties] extended attribute, then set
  //      desc.[[Enumerable]] to false, otherwise set it to true.
{% if has_legacy_unenumerable_named_properties %}
  // TODO: Note that this is never true at the moment, as Cobalt's IDLs and
  // IDL compiler do not support this.
  properties |= v8::DontEnum;
{% endif %}

  info.GetReturnValue().Set(properties);
}

{% if not indexed_property_getter %}
void IndexedPropertyDescriptorCallback(
    uint32_t index, const v8::PropertyCallbackInfo<v8::Value>& info) {
  // TODO: Figure out under what conditions this gets called.  It's not
  // getting called in our tests.
  NOTIMPLEMENTED();
}
{% endif %}

void NamedPropertyEnumeratorCallback(
    const v8::PropertyCallbackInfo<v8::Array>& info) {
  v8::Isolate* isolate = info.GetIsolate();
  v8::Local<v8::Object> object = info.Holder();
{{ get_impl_class_instance(impl_class) }}
  v8::Local<v8::Array> array = v8::Array::New(isolate);
  V8cPropertyEnumerator property_enumerator(isolate, &array);
  impl->EnumerateNamedProperties(&property_enumerator);
  info.GetReturnValue().Set(array);
}

{% endif %}

{% if named_property_setter %}
void NamedPropertySetterCallback(
    v8::Local<v8::Name> property,
    v8::Local<v8::Value> value,
    const v8::PropertyCallbackInfo<v8::Value>& info) {
  v8::Isolate* isolate = info.GetIsolate();
  v8::Local<v8::Object> object = info.Holder();
{{ nonstatic_function_prologue(impl_class) }}
  std::string property_name = *v8::String::Utf8Value(isolate, property);
  TypeTraits<{{named_property_setter.type}}>::ConversionType native_value;
  FromJSValue(isolate, value, {{named_property_setter.conversion_flags}},
              &exception_state, &native_value);
  if (exception_state.is_exception_set()) {
    return;
  }
{{ call_cobalt_function(impl_class, "void",
                        named_property_setter.name, ["property_name", "native_value"],
                        named_property_setter.raises_exception,
                        named_property_setter.call_with) }}
  if (exception_state.is_exception_set()) {
    return;
  }
  info.GetReturnValue().Set(value);
}

{% if not indexed_property_setter %}
void IndexedPropertySetterCallback(
    uint32_t index,
    v8::Local<v8::Value> value,
    const v8::PropertyCallbackInfo<v8::Value>& info) {
  v8::Local<v8::String> as_string = (v8::Integer::New(info.GetIsolate(), index)->ToString(
                                     info.GetIsolate()->GetCurrentContext())).ToLocalChecked();
  NamedPropertySetterCallback(as_string, value, info);
}
{% endif %}

{% endif %}

{% if named_property_deleter %}
void NamedPropertyDeleterCallback(
    v8::Local<v8::Name> property,
    const v8::PropertyCallbackInfo<v8::Boolean>& info) {
  v8::Isolate* isolate = info.GetIsolate();
  v8::Local<v8::Object> object = info.Holder();
{{ nonstatic_function_prologue(impl_class) }}
  std::string property_name = *v8::String::Utf8Value(isolate, property);
  if (!impl->CanQueryNamedProperty(property_name)) {
    return;
  }
{{ call_cobalt_function(impl_class, "void",
                        named_property_deleter.name, ["property_name"],
                        named_property_deleter.raises_exception,
                        named_property_deleter.call_with) }}
  if (exception_state.is_exception_set()) {
    return;
  }
  info.GetReturnValue().Set(true);
}

{% if not indexed_property_deleter %}
void IndexedPropertyDeleterCallback(
    uint32_t index,
    const v8::PropertyCallbackInfo<v8::Boolean>& info) {
  v8::Isolate* isolate = info.GetIsolate();
  v8::Local<v8::String> as_string = (v8::Integer::New(info.GetIsolate(), index)->ToString(
                                     info.GetIsolate()->GetCurrentContext())).ToLocalChecked();
  NamedPropertyDeleterCallback(as_string, info);
}
{% endif %}

{% endif %}

{% if indexed_property_getter %}

void IndexedPropertyGetterCallback(
    uint32_t index,
    const v8::PropertyCallbackInfo<v8::Value>& info) {
  v8::Isolate* isolate = info.GetIsolate();
  v8::Local<v8::Object> object = info.Holder();
{{ nonstatic_function_prologue(impl_class) }}
  if (index >= impl->length()) {
    // |index| is out of bounds, so return undefined.
    return;
  }
{{ call_cobalt_function(impl_class, indexed_property_getter.type,
                        indexed_property_getter.name, ["index"],
                        indexed_property_getter.raises_exception,
                        indexed_property_getter.call_with) }}
  info.GetReturnValue().Set(result_value);
}

void IndexedPropertyDescriptorCallback(
    uint32_t index, const v8::PropertyCallbackInfo<v8::Value>& info) {
  // TODO: Figure out under what conditions this gets called.  It's not
  // getting called in our tests.
  NOTIMPLEMENTED();
}

void IndexedPropertyEnumeratorCallback(
    const v8::PropertyCallbackInfo<v8::Array>& info) {
  v8::Isolate* isolate = info.GetIsolate();
  v8::Local<v8::Context> context = isolate->GetCurrentContext();
  v8::Local<v8::Object> object = info.Holder();
{{ get_impl_class_instance(impl_class) }}
  const uint32_t length = impl->length();
  v8::Local<v8::Array> array = v8::Array::New(isolate, length);
  for (uint32_t i = 0; i < length; ++i) {
    array->Set(context, i, v8::Integer::New(isolate, i)).Check();
  }
  info.GetReturnValue().Set(array);
}

void IndexedPropertyDefinerCallback(
    uint32_t index, const v8::PropertyDescriptor& desc,
    const v8::PropertyCallbackInfo<v8::Value>& info) {
  // TODO: Figure out under what conditions this gets called.  It's not
  // getting called in our tests.
  NOTIMPLEMENTED();
}

{% endif %}

{% if indexed_property_setter %}
void IndexedPropertySetterCallback(
    uint32_t index,
    v8::Local<v8::Value> value,
    const v8::PropertyCallbackInfo<v8::Value>& info) {
  v8::Isolate* isolate = info.GetIsolate();
  v8::Local<v8::Object> object = info.Holder();
{{ nonstatic_function_prologue(impl_class) }}
  if (index >= impl->length()) {
    return;
  }
  TypeTraits<{{indexed_property_setter.type}}>::ConversionType native_value;
  FromJSValue(isolate, value, {{indexed_property_setter.conversion_flags}},
              &exception_state, &native_value);
  if (exception_state.is_exception_set()) {
    return;
  }
{{ call_cobalt_function(impl_class, "void",
                        indexed_property_setter.name, ["index", "native_value"],
                        indexed_property_setter.raises_exception,
                        indexed_property_setter.call_with) }}
  if (exception_state.is_exception_set()) {
    return;
  }
  info.GetReturnValue().Set(value);
}
{% endif %}

{% if indexed_property_deleter %}
void IndexedPropertyDeleterCallback(
    uint32_t index,
    const v8::PropertyCallbackInfo<v8::Boolean>& info) {
  v8::Isolate* isolate = info.GetIsolate();
  v8::Local<v8::Object> object = info.Holder();
{{ nonstatic_function_prologue(impl_class) }}
  if (index >= impl->length()) {
    return;
  }
{{ call_cobalt_function(impl_class, "void",
                        indexed_property_deleter.name, ["index"],
                        indexed_property_deleter.raises_exception,
                        indexed_property_deleter.call_with) }}
  if (exception_state.is_exception_set()) {
    return;
  }
  info.GetReturnValue().Set(v8::Boolean::New(isolate, true));
}
{% endif %}

{% if constructor %}

{% for overload in constructor.overloads if constructor.overloads|length > 1 %}
void Constructor{{overload.overload_index}}(
    const v8::FunctionCallbackInfo<v8::Value>& info) {
  v8::Isolate* isolate = info.GetIsolate();
{{ constructor_implementation(overload) -}}
}
{% endfor %}

void Constructor(const v8::FunctionCallbackInfo<v8::Value>& info) {
{% if constructor.overloads|length == 1 %}
  v8::Isolate* isolate = info.GetIsolate();
{{ constructor_implementation(constructor.overloads[0]) -}}
{% else %}
{{ overload_resolution_implementation(constructor, "Constructor")}}
{% endif %}
}

{% else %}

void DummyConstructor(const v8::FunctionCallbackInfo<v8::Value>& info) {
  V8cExceptionState exception(info.GetIsolate());
  exception.SetSimpleException(
      script::kTypeError, "{{interface_name}} is not constructible.");
}

{% endif %}

{% for attribute in attributes + static_attributes %}
{% if attribute.conditional %}
#if defined({{attribute.conditional}})
{% endif %}

{% if attribute.is_constructor_attribute %}
// Nothing for {{attribute}}.  We will just give them the v8::FunctionTemplate.
{% else %}
void {{attribute.idl_name}}AttributeGetter(
    const v8::FunctionCallbackInfo<v8::Value>& info) {
  script::v8c::shared_bindings::AttributeGetterImpl<{{impl_class}},
                                                    {{binding_class}}>(
                    info,
                    {{ "true" if attribute.is_static else "false"}},
                    {{ "true" if attribute.type == "void" else "false"}},
                    [](v8::Isolate* isolate, {{impl_class}}* impl,
                       cobalt::script::ExceptionState& exception_state,
                       v8::Local<v8::Value>& result_value) {
{{ get_cobalt_value(impl_class, attribute.type,
                    attribute.getter_function_name, [],
                    attribute.raises_exception, attribute.call_with,
                    attribute.is_static) }}
  });
}

{% if attribute.has_setter %}
void {{attribute.idl_name}}AttributeSetter(
    const v8::FunctionCallbackInfo<v8::Value>& info) {
  script::v8c::shared_bindings::AttributeSetterImpl<{{impl_class}}, {{binding_class}}>(info,
                    {{ "true" if attribute.is_static else "false"}},
                    {{ "true" if attribute.type == "void" else "false"}},
                    [](v8::Isolate* isolate, {{impl_class}}* impl,
                       V8cExceptionState& exception_state,
                       v8::Local<v8::Value>& result_value,
                       v8::Local<v8::Value> v8_value) {
{{ set_attribute_implementation(attribute, impl_class) -}}
  });
}
{% endif %} {#- attribute.has_setter #}

{% endif %}
{% if attribute.conditional %}
#endif  // {{attribute.conditional}}
{% endif %} {#- attribute.is_constructor_attribute #}
{% endfor %} {#- for attribute in attributes + static_attributes #}

{%- for operation in operations + static_operations %}
{% if operation.conditional %}
#if defined({{operation.conditional}})
{% endif %}
{% set boundFunctionSuffix = "StaticMethod" if operation.is_static else "Method" %}

{% for overload in operation.overloads if operation.overloads|length > 1 %}
void {{operation.idl_name}}{{boundFunctionSuffix}}{{overload.overload_index}}(
    const v8::FunctionCallbackInfo<v8::Value>& info) {
{{ function_implementation(overload) -}}
}
{% endfor %}

void {{operation.idl_name}}{{boundFunctionSuffix}}(const v8::FunctionCallbackInfo<v8::Value>& info) {
{% if operation.overloads|length == 1 %}
{{ function_implementation(operation.overloads[0]) -}}
{% else %}
{{ overload_resolution_implementation(operation, operation.idl_name + boundFunctionSuffix) }}
{% endif %}
}

{% if operation.conditional %}
#endif  // {{operation.conditional}}
{% endif %}
{% endfor %}

{% if stringifier %}
void Stringifier(const v8::FunctionCallbackInfo<v8::Value>& info) {
  auto* impl = script::v8c::shared_bindings::get_impl_class_from_info<{{impl_class}}, {{binding_class}}>(info);

  if (!impl) {
    return;
  }
  std::string stringified = impl->{{stringifier.name}}();

  v8::Local<v8::Value> v8_stringified;
  ToJSValue(info.GetIsolate(), stringified, &v8_stringified);

  info.GetReturnValue().Set(v8_stringified);
}
{% endif %}

void InitializeTemplate(v8::Isolate* isolate) {
  // https://heycam.github.io/webidl/#interface-object
  // 3.6.1. Interface object
  //
  // The interface object for a given interface is a built-in function object.
  // It has properties that correspond to the constants and static operations
  // defined on that interface, as described in sections 3.6.6 Constants and
  // 3.6.8 Operations.
  //
  // If the interface is declared with a [Constructor] extended attribute,
  // then the interface object can be called as a constructor to create an
  // object that implements that interface. Calling that interface as a
  // function will throw an exception.
  //
  // Interface objects whose interfaces are not declared with a [Constructor]
  // extended attribute will throw when called, both as a function and as a
  // constructor.
  //
  // An interface object for a non-callback interface has an associated object
  // called the interface prototype object. This object has properties that
  // correspond to the regular attributes and regular operations defined on
  // the interface, and is described in more detail in 3.6.3 Interface
  // prototype object.
{% if constructor %}
  v8::Local<v8::FunctionTemplate> function_template =
      v8::FunctionTemplate::New(
          isolate,
          Constructor,
          v8::Local<v8::Value>(),
          v8::Local<v8::Signature>(),
          {{constructor.length}});
  function_template->SetLength({{constructor.length}});
{% else %}
  v8::Local<v8::FunctionTemplate> function_template =
      v8::FunctionTemplate::New(
          isolate,
          DummyConstructor,
          v8::Local<v8::Value>(),
          v8::Local<v8::Signature>(),
          0);
{% endif %}
  function_template->SetClassName(NewInternalString(isolate, "{{interface_name}}"));
  function_template->ReadOnlyPrototype();

  v8::Local<v8::ObjectTemplate> prototype_template = function_template->PrototypeTemplate();
  v8::Local<v8::ObjectTemplate> instance_template = function_template->InstanceTemplate();
  instance_template->SetInternalFieldCount(WrapperPrivate::kInternalFieldCount);

  V8cGlobalEnvironment* global_environment = V8cGlobalEnvironment::GetFromIsolate(isolate);
  global_environment->AddInterfaceData(kInterfaceUniqueId, function_template);

{% if parent_interface %}
  {
    // An interface can be defined to inherit from another interface. If the
    // identifier of the interface is followed by a U+003A COLON (":") character
    // and an identifier, then that identifier identifies the inherited
    // interface. An object that implements an interface that inherits from
    // another also implements that inherited interface. The object therefore
    // will also have members that correspond to the interface members from the
    // inherited interface.
    v8::Local<v8::FunctionTemplate> parent_template = {{parent_interface}}::GetTemplate(isolate);
    function_template->Inherit(parent_template);
    static_assert(
        std::is_base_of<{{parent_interface_name}}, {{impl_class}}>::value,
        "Expected {{impl_class}} to have C++ parent class "
        "{{parent_interface_name}}, because that is its WebIDL parent.");
  }
{% elif is_exception_interface %}
  {
    // A spicy hack from Chromium in order to achieve
    // https://heycam.github.io/webidl/#es-DOMException-specialness
    // See https://cs.chromium.org/chromium/src/third_party/WebKit/Source/bindings/templates/interface_base.cpp.tmpl?l=630&rcl=0f7c2c752bb24ad08c17017e4e68401093fe76a0
    script::v8c::shared_bindings::set_intrinsic_error_prototype_interface_template(isolate, function_template);
  }
{% endif %}

  // https://heycam.github.io/webidl/#es-constants
  // 3.6.6. Constants
  //
  // For each exposed constant defined on an interface A, there must be a
  // corresponding property. The property has the following characteristics:
{% for constant in constants %}
  {
    // The name of the property is the identifier of the constant.
    v8::Local<v8::String> name = NewInternalString(
        isolate,
        "{{constant.idl_name}}");

    // The value of the property is that which is obtained by converting the
    // constant's IDL value to an ECMAScript value.
    v8::Local<v8::Value> constant_value;
    ToJSValue(isolate, {{constant.value}}, &constant_value);

    // The property has attributes { [[Writable]]: false, [[Enumerable]]: true,
    // [[Configurable]]: false }.
    v8::PropertyAttribute attributes = static_cast<v8::PropertyAttribute>(
        v8::ReadOnly | v8::DontDelete);

    // The location of the property is determined as follows:
{% if is_global_interface %}
    // If the interface was declared with the [Global] extended attribute, then
    // the property exists on the single object that implements the interface.
    instance_template->Set(name, constant_value, attributes);

{% else %}
    // Otherwise, if the interface has an interface prototype object, then the
    // property exists on it.
    prototype_template->Set(name, constant_value, attributes);
{% endif %}

    // In addition, a property with the same characteristics must exist on the
    // interface object or the legacy callback interface object, if either of
    // those objects exists.
    function_template->Set(name, constant_value, attributes);
  }
{% endfor %}

  // https://heycam.github.io/webidl/#es-attributes
  // 3.6.7. Attributes
  //
  // For each exposed attribute of the interface there must exist a
  // corresponding property. The characteristics of this property are as
  // follows:
{% for attribute in all_attributes_v8_order_quirk %}
{% if attribute.conditional %}
#if defined({{attribute.conditional}})
{% endif %}
  {
{% if not attribute.is_constructor_attribute %}

    script::v8c::shared_bindings::set_property_for_nonconstructor_attribute(
                  isolate,
    // The property has attributes { [[Get]]: G, [[Set]]: S, [[Enumerable]]:
    // true, [[Configurable]]: configurable }, where: configurable is false if
    // the attribute was declared with the [Unforgeable] extended attribute and
    // true otherwise;
                  {{ "false" if attribute.is_unforgeable else "true"}},
                  {{ "true" if attribute.has_setter else "false"}},
                  {{ "true" if attribute.on_interface else "false"}},
                  {{ "true" if attribute.on_instance else "false"}},
                  function_template,
                  instance_template,
                  prototype_template,
                  "{{attribute.idl_name}}"
                  ,{{attribute.idl_name}}AttributeGetter
{% if attribute.has_setter %}
                  ,{{attribute.idl_name}}AttributeSetter
{% endif %}
                  );

{% else %} {#- not attribute.is_constructor_attribute #}
    {
      v8::Local<v8::String> name = NewInternalString(
          isolate,
          "{{attribute.idl_name}}");
      instance_template->Set(
          name,
{% if attribute.interface_name == interface_name %}
          function_template
{% else %}
          V8c{{attribute.impl_class}}::GetTemplate(isolate)
{% endif %}
      );
    }
{% endif %} {#- not attribute.is_constructor_attribute #}
  }
{% if attribute.conditional %}
#endif  // {{attribute.conditional}}
{% endif %}
{% endfor %}

  // https://heycam.github.io/webidl/#es-operations
  // 3.6.8. Operations
  //
  // For each unique identifier of an exposed operation defined on the
  // interface, there must exist a corresponding property, unless the effective
  // overload set for that identifier and operation and with an argument count
  // of 0 has no entries.
  //
  // The characteristics of this property are as follows:
{% for operation in operations + static_operations %}
{% if operation.conditional %}
#if defined({{operation.conditional}})
{% endif %}
  {
    // The name of the property is the identifier.
    v8::Local<v8::String> name = NewInternalString(
        isolate,
        "{{operation.idl_name}}");

    // The property has attributes { [[Writable]]: B, [[Enumerable]]: true,
    // [[Configurable]]: B }, where B is false if the operation is unforgeable
    // on the interface, and true otherwise.
    bool B = {{ "false" if operation.is_unforgeable else "true"}};
    v8::PropertyAttribute attributes = static_cast<v8::PropertyAttribute>(
        B ? v8::None : (v8::ReadOnly | v8::DontDelete));

    v8::Local<v8::FunctionTemplate> method_template =
        v8::FunctionTemplate::New(isolate, {{operation.idl_name}}{{"Static" if operation.is_static else ""}}Method);
    method_template->RemovePrototype();
    method_template->SetLength({{operation.length}});

    // The location of the property is determined as follows:
{% if operation.on_interface %}
    // If the operation is static, then the property exists on the interface
    // object.
    function_template->
{% elif operation.on_instance %}
    // Otherwise, if the operation is unforgeable on the interface or if the
    // interface was declared with the [Global] extended attribute, then the
    // property exists on every object that implements the interface.
    instance_template->
{% else %}
    // Otherwise, the property exists solely on the interface's interface
    // prototype object.
    prototype_template->
{% endif %}
        Set(name, method_template);

    // The value of the property is the result of creating an operation function
    // given the operation, the interface, and the relevant Realm of the object
    // that is the location of the property.

    // Note: that is, even if an includes statement was used to make an
    // operation available on the interface, we pass in the interface which
    // includes the interface mixin, and not the interface mixin on which the
    // operation was originally declared.
  }
{% if operation.conditional %}
#endif  // {{operation.conditional}}
{% endif %}
{% endfor %}

  // https://heycam.github.io/webidl/#es-stringifier
  // 3.6.8.2. Stringifiers
  prototype_template->Set(
      v8::Symbol::GetToStringTag(isolate),
      NewInternalString(isolate, "{{interface_name}}"),
      static_cast<v8::PropertyAttribute>(v8::ReadOnly | v8::DontEnum));

{% if stringifier %}
  {
    v8::Local<v8::String> name = NewInternalString(isolate, "toString");
    v8::Local<v8::FunctionTemplate> method_template = v8::FunctionTemplate::New(isolate, Stringifier);
    prototype_template->Set(
      NewInternalString(isolate, "toString"),
      method_template);
  }
{% endif %}

{% if named_property_getter %}
  {
    v8::NamedPropertyHandlerConfiguration named_property_handler_configuration = {
      NamedPropertyGetterCallback,
      {{ "NamedPropertySetterCallback" if named_property_setter else "nullptr" }},
      NamedPropertyQueryCallback,
      {{ "NamedPropertyDeleterCallback" if named_property_deleter else "nullptr" }},
      NamedPropertyEnumeratorCallback,
      v8::Local<v8::Value>(),
      static_cast<v8::PropertyHandlerFlags>(int(v8::PropertyHandlerFlags::kNonMasking) | int(v8::PropertyHandlerFlags::kOnlyInterceptStrings))
    };
    instance_template->SetHandler(named_property_handler_configuration);
  }
{% endif %}

{% if named_property_getter and not indexed_property_getter %}
  {
    v8::IndexedPropertyHandlerConfiguration indexed_property_handler_configuration = {
      IndexedPropertyGetterCallback,
      {{ "IndexedPropertySetterCallback" if named_property_setter else "nullptr" }},
      IndexedPropertyDescriptorCallback,
      {{ "IndexedPropertyDeleterCallback" if named_property_deleter else "nullptr" }},
      nullptr,
      nullptr
    };
    instance_template->SetHandler(indexed_property_handler_configuration);
  }
{% endif %}

{% if indexed_property_getter %}
  {
    v8::IndexedPropertyHandlerConfiguration indexed_property_handler_configuration = {
      IndexedPropertyGetterCallback,
      {{ "IndexedPropertySetterCallback" if indexed_property_setter else "nullptr" }},
      IndexedPropertyDescriptorCallback,
      {{ "IndexedPropertyDeleterCallback" if indexed_property_deleter else "nullptr" }},
      IndexedPropertyEnumeratorCallback,
      IndexedPropertyDefinerCallback
    };
    instance_template->SetHandler(indexed_property_handler_configuration);
  }
{% endif %}

}

}  // namespace

{% if is_global_interface %}

// The global interface is special.  Just give them the global object proxy.
v8::Local<v8::Object> {{binding_class}}::CreateWrapper(
    v8::Isolate* isolate, const scoped_refptr<Wrappable>&) {
  return isolate->GetCurrentContext()->Global();
}

{% else %}

v8::Local<v8::Object> {{binding_class}}::CreateWrapper(
    v8::Isolate* isolate, const scoped_refptr<Wrappable>& wrappable) {
  EscapableEntryScope entry_scope(isolate);
  v8::Local<v8::Context> context = isolate->GetCurrentContext();

  V8cGlobalEnvironment* global_environment = V8cGlobalEnvironment::GetFromIsolate(isolate);
  if (!global_environment->HasInterfaceData(kInterfaceUniqueId)) {
    InitializeTemplate(isolate);
  }
  v8::Local<v8::FunctionTemplate> function_template = global_environment->GetInterfaceData(kInterfaceUniqueId);

  DCHECK(function_template->InstanceTemplate()->InternalFieldCount() == WrapperPrivate::kInternalFieldCount);
  v8::Local<v8::Object> object = function_template->InstanceTemplate()->NewInstance(context).ToLocalChecked();
  DCHECK(object->InternalFieldCount() == WrapperPrivate::kInternalFieldCount);

  // This |WrapperPrivate|'s lifetime will be managed by V8.
  new WrapperPrivate(isolate, wrappable, object);
  return entry_scope.Escape(object);
}

{% endif %}

v8::Local<v8::FunctionTemplate> {{binding_class}}::GetTemplate(v8::Isolate* isolate) {
  V8cGlobalEnvironment* global_environment = V8cGlobalEnvironment::GetFromIsolate(isolate);
  if (!global_environment->HasInterfaceData(kInterfaceUniqueId)) {
    InitializeTemplate(isolate);
  }
  return global_environment->GetInterfaceData(kInterfaceUniqueId);
}

{% endblock implementation %}

{% block create_global_object_impl %}

namespace cobalt {
namespace script {
namespace v8c {

template <typename GlobalInterface>
void V8cGlobalEnvironment::CreateGlobalObject(
    const scoped_refptr<GlobalInterface>& global_interface,
    EnvironmentSettings* environment_settings) {
  TRACE_EVENT0("cobalt::script", "V8cGlobalEnvironment::CreateGlobalObject()");
  // Intentionally not an |EntryScope|, since the context doesn't exist yet.
  v8::Isolate::Scope isolate_scope(isolate_);
  v8::HandleScope handle_scope(isolate_);
  v8::Local<v8::ObjectTemplate> global_object_template =
                {{binding_class}}::GetTemplate(isolate_)->InstanceTemplate();

  v8::Local<v8::Context> context =
      v8::Context::New(isolate_, nullptr, global_object_template);
  context_.Reset(isolate_, context);
  v8::Context::Scope context_scope(context);

  global_wrappable_ = global_interface;

  DCHECK(!environment_settings_);
  DCHECK(environment_settings);
  environment_settings_ = environment_settings;
  EvaluateAutomatics();

  v8::Local<v8::Object> global_object = context->Global();
  new WrapperPrivate(isolate_, global_interface, global_object);

  auto actual_global_object = global_object->GetPrototype()->
                                          ToObject(context).ToLocalChecked();
  new WrapperPrivate(isolate_, global_interface, actual_global_object);

{% for interface in all_interfaces %}
{% if interface.conditional %}
#if defined({{interface.conditional}})
{% endif %}
  wrapper_factory_->RegisterWrappableType(
      {{interface.impl_name}}::{{interface.impl_name}}WrappableType(),
      base::Bind(V8c{{interface.impl_name}}::CreateWrapper),
      base::Bind(V8c{{interface.impl_name}}::GetTemplate));
{% if interface.conditional %}
#endif  // defined({{interface.conditional}})
{% endif %}
{% endfor %}

}

}  // namespace v8c

template<>
void GlobalEnvironment::CreateGlobalObject<{{impl_class}}>(
    const scoped_refptr<{{impl_class}}>& global_interface,
    EnvironmentSettings* environment_settings) {
  base::polymorphic_downcast<v8c::V8cGlobalEnvironment*>(this)->
                  CreateGlobalObject(global_interface, environment_settings);
}

}  // namespace script
}  // namespace cobalt

{% endblock create_global_object_impl %}

{%  block enumeration_definitions %}
// enum block
{% for enumeration in enumerations %}

inline void ToJSValue(
    v8::Isolate* isolate,
    {{impl_class}}::{{enumeration.name}} in_enum,
    v8::Local<v8::Value>* out_value) {
  switch (in_enum) {
{% for value, idl_value in enumeration.value_pairs %}
    case {{impl_class}}::{{value}}:
      ToJSValue(isolate, std::string("{{idl_value}}"), out_value);
      return;
{% endfor %}
    default:
      NOTREACHED();
      *out_value = v8::Undefined(isolate);
  }
}

inline void FromJSValue(
    v8::Isolate* isolate, v8::Local<v8::Value> value,
    int conversion_flags, ExceptionState* exception_state,
    {{impl_class}}::{{enumeration.name}}* out_enum) {
  DCHECK_EQ(0, conversion_flags) << "Unexpected conversion flags.";
  // Value -> IDL enum algorithm described here:
  // http://heycam.github.io/webidl/#es-enumeration
  // 1. Let S be the result of calling ToString(V).
  v8::Local<v8::Context> context = isolate->GetCurrentContext();
  v8::MaybeLocal<v8::String> maybe_string = value->ToString(context);
  v8::Local<v8::String> string;
  if (!maybe_string.ToLocal(&string)) {
    exception_state->SetSimpleException(cobalt::script::kConvertToEnumFailed);
    return;
  }

  bool match = false;
// 3. Return the enumeration value of type E that is equal to S.
{% for value, idl_value in enumeration.value_pairs %}
{{-" else " if not loop.first}}
  if (string == NewInternalString(isolate, "{{id_value}}")) {
    *out_enum = {{impl_class}}::{{value}};
  }
{% endfor %}
  else {
    // 2. If S is not one of E's enumeration values, then throw a TypeError.
    exception_state->SetSimpleException(cobalt::script::kConvertToEnumFailed);
    return;
  }
}

{% endfor %}

{% endblock enumeration_definitions %}
