{#
 # 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/script_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 %}
