{#
 # 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();
  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();
  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();
  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::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(i, v8::Integer::New(isolate, i));
  }
  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}}, {{interface_name}}>::value,
        "Expected {{interface_name}} 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 %}
          // Note that we use "attribute.interface_name", and not
          // "attribute.idl_name", because of named constructors.
          V8c{{attribute.interface_name}}::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();
  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.name}}::{{interface.name}}WrappableType(),
      base::Bind(V8c{{interface.name}}::CreateWrapper),
      base::Bind(V8c{{interface.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 %}
