{#
 # Copyright 2016 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 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 "base/lazy_instance.h"
#include "cobalt/script/exception_state.h"
#include "cobalt/script/mozjs-45/callback_function_conversion.h"
#include "cobalt/script/mozjs-45/conversion_helpers.h"
#include "cobalt/script/mozjs-45/mozjs_array_buffer.h"
#include "cobalt/script/mozjs-45/mozjs_array_buffer_view.h"
#include "cobalt/script/mozjs-45/mozjs_callback_function.h"
#include "cobalt/script/mozjs-45/mozjs_data_view.h"
#include "cobalt/script/mozjs-45/mozjs_exception_state.h"
#include "cobalt/script/mozjs-45/mozjs_global_environment.h"
#include "cobalt/script/mozjs-45/mozjs_property_enumerator.h"
#include "cobalt/script/mozjs-45/mozjs_typed_arrays.h"
#include "cobalt/script/mozjs-45/mozjs_user_object_holder.h"
#include "cobalt/script/mozjs-45/mozjs_value_handle.h"
#include "cobalt/script/mozjs-45/native_promise.h"
#include "cobalt/script/mozjs-45/proxy_handler.h"
#include "cobalt/script/mozjs-45/type_traits.h"
#include "cobalt/script/mozjs-45/wrapper_factory.h"
#include "cobalt/script/mozjs-45/wrapper_private.h"
#include "cobalt/script/property_enumerator.h"
#include "cobalt/script/sequence.h"
#include "third_party/mozjs-45/js/src/jsapi.h"
{% if is_exception_interface %}
#include "third_party/mozjs-45/js/src/jsexn.h"
{% endif %}
#include "third_party/mozjs-45/js/src/jsfriendapi.h"

{% endblock includes %}

{% block using_directives %}
{{ super() }}
using cobalt::script::CallbackFunction;
using cobalt::script::CallbackInterfaceTraits;
using cobalt::script::ExceptionState;
using cobalt::script::Wrappable;
using cobalt::script::mozjs::FromJSValue;
using cobalt::script::mozjs::InterfaceData;
using cobalt::script::mozjs::MozjsCallbackFunction;
using cobalt::script::mozjs::MozjsExceptionState;
using cobalt::script::mozjs::MozjsGlobalEnvironment;
using cobalt::script::mozjs::MozjsPropertyEnumerator;
using cobalt::script::mozjs::MozjsUserObjectHolder;
using cobalt::script::mozjs::ProxyHandler;
using cobalt::script::mozjs::ToJSValue;
using cobalt::script::mozjs::TypeTraits;
using cobalt::script::mozjs::WrapperFactory;
using cobalt::script::mozjs::WrapperPrivate;
using cobalt::script::mozjs::kConversionFlagClamped;
using cobalt::script::mozjs::kConversionFlagNullable;
using cobalt::script::mozjs::kConversionFlagRestricted;
using cobalt::script::mozjs::kConversionFlagTreatNullAsEmptyString;
using cobalt::script::mozjs::kConversionFlagTreatUndefinedAsEmptyString;
using cobalt::script::mozjs::kConversionFlagObjectOnly;
using cobalt::script::mozjs::kNoConversionFlags;
{% 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(JSContext* context, {{impl_class}}::{{enumeration.name}} in_enum,
               JS::MutableHandleValue out_value);
void FromJSValue(JSContext* context, JS::HandleValue value,
                 int conversion_flags, ExceptionState* exception_state,
                 {{impl_class}}::{{enumeration.name}}* out_enum);
{% endfor %}
{% endif %}
{% endblock enumeration_declarations %}

{% block top_level_unnamed_namespace %}
{% if is_global_interface %}
JSObject* DummyFunctor(
    JSContext* context, const scoped_refptr<Wrappable>& wrappable) {
  NOTREACHED();
  return NULL;
}
{% endif %}
{% endblock top_level_unnamed_namespace %}

{% block implementation %}

namespace {

{% if named_property_getter %}

bool IsSupportedNamedProperty(JSContext* context, JS::HandleObject object,
                              const std::string& property_name) {
{{ get_impl_class_instance(impl_class) }}
  return impl->CanQueryNamedProperty(property_name);
}

void EnumerateSupportedNames(JSContext* context, JS::HandleObject object,
                             JS::AutoIdVector* properties) {
{{ get_impl_class_instance(impl_class) }}
  MozjsPropertyEnumerator enumerator(context, properties);
  impl->EnumerateNamedProperties(&enumerator);
}

bool GetNamedProperty(
    JSContext* context, JS::HandleObject object, JS::HandleId id,
    JS::MutableHandleValue vp) {
  JS::RootedValue id_value(context);
  if (!JS_IdToValue(context, id, &id_value)) {
    NOTREACHED();
    return false;
  }

{{ nonstatic_function_prologue(impl_class) }}
  std::string property_name;
  FromJSValue(context, id_value, kNoConversionFlags, &exception_state,
              &property_name);
  if (exception_state.is_exception_set()) {
    // The ID should be an integer or a string, so we shouldn't have any
    // exceptions converting to string.
    NOTREACHED();
    return false;
  }
{{ 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()) {
    vp.set(result_value);
  }
  return !exception_state.is_exception_set();
}

{% endif %}

{% if named_property_setter %}

bool SetNamedProperty(
  JSContext* context, JS::HandleObject object, JS::HandleId id,
  JS::MutableHandleValue vp, JS::ObjectOpResult& object_op_result) {
  JS::RootedValue id_value(context);
  if (!JS_IdToValue(context, id, &id_value)) {
    NOTREACHED();
    return false;
  }
{{ nonstatic_function_prologue(impl_class) }}
  std::string property_name;
  FromJSValue(context, id_value, kNoConversionFlags, &exception_state,
              &property_name);
  if (exception_state.is_exception_set()) {
    // The ID should be an integer or a string, so we shouldn't have any
    // exceptions converting to string.
    NOTREACHED();
    return false;
  }
  TypeTraits<{{named_property_setter.type}} >::ConversionType value;
  FromJSValue(context, vp, {{named_property_setter.conversion_flags}},
              &exception_state, &value);
  if (exception_state.is_exception_set()) {
    return false;
  }
{{ call_cobalt_function(impl_class, "void",
                        named_property_setter.name, ["property_name", "value"],
                        named_property_setter.raises_exception,
                        named_property_setter.call_with) }}

  if (!exception_state.is_exception_set()) {
    return object_op_result.succeed();
  } else {
    return false;
  }
}

{% endif %}

{% if named_property_deleter %}

bool DeleteNamedProperty(JSContext* context, JS::HandleObject object,
                         const std::string& property_name) {
{{ nonstatic_function_prologue(impl_class) }}
{{ call_cobalt_function(impl_class, "void",
                        named_property_deleter.name, ["property_name"],
                        named_property_deleter.raises_exception,
                        named_property_deleter.call_with) }}
  return !exception_state.is_exception_set();
}

{% endif %}

{% if indexed_property_getter %}

bool IsSupportedIndexProperty(JSContext* context, JS::HandleObject object,
                              uint32_t index) {
{{ get_impl_class_instance(impl_class) }}
  return index < impl->length();
}

void EnumerateSupportedIndexes(JSContext* context, JS::HandleObject object,
                               JS::AutoIdVector* properties) {
{{ get_impl_class_instance(impl_class) }}
  const uint32_t kNumIndexedProperties = impl->length();
  for (uint32_t i = 0; i < kNumIndexedProperties; ++i) {
    properties->append(INT_TO_JSID(i));
  }
}

bool GetIndexedProperty(
    JSContext* context, JS::HandleObject object, JS::HandleId id,
    JS::MutableHandleValue vp) {
  JS::RootedValue id_value(context);
  if (!JS_IdToValue(context, id, &id_value)) {
    NOTREACHED();
    return false;
  }
{{ nonstatic_function_prologue(impl_class) }}
  uint32_t index;
  FromJSValue(context, id_value, kNoConversionFlags, &exception_state, &index);
  if (exception_state.is_exception_set()) {
    // The ID should be an integer or a string, so we shouldn't have any
    // exceptions converting to string.
    NOTREACHED();
    return false;
  }
{{ call_cobalt_function(impl_class, indexed_property_getter.type,
                        indexed_property_getter.name, ["index"],
                        indexed_property_getter.raises_exception,
                        indexed_property_getter.call_with) }}
  if (!exception_state.is_exception_set()) {
    vp.set(result_value);
  }
  return !exception_state.is_exception_set();
}

{% endif %}

{% if indexed_property_setter %}

bool SetIndexedProperty(
  JSContext* context, JS::HandleObject object, JS::HandleId id,
  JS::MutableHandleValue vp, JS::ObjectOpResult& object_op_result) {
  JS::RootedValue id_value(context);
  if (!JS_IdToValue(context, id, &id_value)) {
    NOTREACHED();
    return false;
  }
{{ nonstatic_function_prologue(impl_class) }}
  uint32_t index;
  FromJSValue(context, id_value, kNoConversionFlags, &exception_state, &index);
  if (exception_state.is_exception_set()) {
    // The ID should be an integer or a string, so we shouldn't have any
    // exceptions converting to string.
    NOTREACHED();
    return false;
  }
  TypeTraits<{{indexed_property_setter.type}} >::ConversionType value;
  FromJSValue(context, vp, {{indexed_property_setter.conversion_flags}},
              &exception_state, &value);
  if (exception_state.is_exception_set()) {
    return false;
  }
{{ call_cobalt_function(impl_class, "void",
                        indexed_property_setter.name, ["index", "value"],
                        indexed_property_setter.raises_exception,
                        indexed_property_setter.call_with) }}
  if (!exception_state.is_exception_set()) {
    return object_op_result.succeed();
  } else {
    return false;
  }
}

{% endif %}

{% if indexed_property_deleter %}

bool DeleteIndexedProperty(
    JSContext* context, JS::HandleObject object, uint32_t index) {
{{ nonstatic_function_prologue(impl_class) }}
{{ call_cobalt_function(impl_class, "void",
                        indexed_property_deleter.name, ["index"],
                        indexed_property_deleter.raises_exception,
                        indexed_property_deleter.call_with) }}
  return !exception_state.is_exception_set();
}

{% endif %}

class {{binding_class}}Handler : public ProxyHandler {
 public:
  {{binding_class}}Handler()
      : ProxyHandler(indexed_property_hooks, named_property_hooks) {}

 private:
  static NamedPropertyHooks named_property_hooks;
  static IndexedPropertyHooks indexed_property_hooks;
};

ProxyHandler::NamedPropertyHooks
{{binding_class}}Handler::named_property_hooks = {
  {{ "IsSupportedNamedProperty" if named_property_getter else "NULL" }},
  {{ "EnumerateSupportedNames" if named_property_getter else "NULL" }},
  {{ "GetNamedProperty" if named_property_getter else "NULL" }},
  {{ "SetNamedProperty" if named_property_setter else "NULL" }},
  {{ "DeleteNamedProperty" if named_property_deleter else "NULL" }},
};

ProxyHandler::IndexedPropertyHooks
{{binding_class}}Handler::indexed_property_hooks = {
  {{ "IsSupportedIndexProperty" if indexed_property_getter else "NULL" }},
  {{ "EnumerateSupportedIndexes" if indexed_property_getter else "NULL" }},
  {{ "GetIndexedProperty" if indexed_property_getter else "NULL" }},
  {{ "SetIndexedProperty" if indexed_property_setter else "NULL" }},
  {{ "DeleteIndexedProperty" if indexed_property_deleter else "NULL" }},
};

static base::LazyInstance<{{binding_class}}Handler>::DestructorAtExit
    proxy_handler;

{% if constructor %}
bool Constructor(JSContext* context, unsigned int argc, JS::Value* vp);
{% else %}
bool DummyConstructor(JSContext* context, unsigned int argc, JS::Value* vp) {
  MozjsExceptionState exception(context);
  exception.SetSimpleException(
      script::kTypeError, "{{interface_name}} is not constructible.");
  return false;
}
{% endif %}

bool HasInstance(JSContext *context, JS::HandleObject type,
                 JS::MutableHandleValue vp, bool *success) {
  JS::RootedObject global_object(
      context, JS_GetGlobalForObject(context, type));
  DCHECK(global_object);

  JS::RootedObject prototype(
      context, {{binding_class}}::GetPrototype(context, global_object));

  // |IsDelegate| walks the prototype chain of an object returning true if
  // .prototype is found.
  bool is_delegate;
  if (!IsDelegate(context, prototype, vp, &is_delegate)) {
    *success = false;
    return false;
  }

  *success = is_delegate;
  return true;
}

const JSClass instance_class_definition = {
    "{{interface_name}}",
    {{ "JSCLASS_GLOBAL_FLAGS" if is_global_interface else 0 }} | JSCLASS_HAS_PRIVATE,
    NULL,  // addProperty
    NULL,  // delProperty
    NULL,  // getProperty
    NULL,  // setProperty
    NULL,  // enumerate
    NULL,  // resolve
    NULL,  // mayResolve
    &WrapperPrivate::Finalizer,  // finalize
    NULL,  // call
    NULL,  // hasInstance
    NULL,  // construct
    {{ "JS_GlobalObjectTraceHook" if is_global_interface else "&WrapperPrivate::Trace" }},  // trace
};

const JSClass prototype_class_definition = {
    "{{interface_name}}Prototype",
};

const JSClass interface_object_class_definition = {
    "{{interface_name}}Constructor",
    0,
    NULL,  // addProperty
    NULL,  // delProperty
    NULL,  // getProperty
    NULL,  // setProperty
    NULL,  // enumerate
    NULL,  // resolve
    NULL,  // mayResolve
    NULL,  // finalize
    NULL,  // call
    &HasInstance,
{% if constructor %}
    Constructor,
{% else %}
    NULL,
{% endif %}
};

{% for attribute in attributes + static_attributes %}
{% if attribute.conditional %}
#if defined({{attribute.conditional}})
{% endif %}
{% if attribute.is_constructor_attribute %}
bool get_{{attribute.idl_name}}(
    JSContext* context, unsigned argc, JS::Value* vp) {
  JS::CallArgs args = JS::CallArgsFromVp(argc, vp);
  if (!args.thisv().isObject()) {
    MozjsExceptionState exception(context);
    exception.SetSimpleException(script::kTypeError, "Invalid this.");
    return false;
  }
  JS::RootedObject object(context, &args.thisv().toObject());
  JS::RootedObject global_object(
    context, JS_GetGlobalForObject(context, object));
  DCHECK(global_object);
  JS::RootedObject interface_object(context,
      Mozjs{{attribute.interface_name}}::GetInterfaceObject(
          context, global_object));
  args.rval().setObject(*interface_object);
  return true;
}
{% else %}
{% if attribute.is_static %}
bool staticget_{{attribute.idl_name}}(
    JSContext* context, unsigned argc, JS::Value* vp) {
{{ static_function_prologue() -}}
{% else %}
bool get_{{attribute.idl_name}}(
    JSContext* context, unsigned argc, JS::Value* vp) {
{% endif %}
  JS::CallArgs args = JS::CallArgsFromVp(argc, vp);
  if (!args.thisv().isObject()) {
    MozjsExceptionState exception(context);
    exception.SetSimpleException(script::kTypeError, "Invalid this.");
    return false;
  }
  JS::RootedObject object(context, &args.thisv().toObject());
{% if not attribute.is_static %}
{{ check_if_object_implements_interface() }}
{{ nonstatic_function_prologue(impl_class) }}
{% endif %}
{{ call_cobalt_function(impl_class, attribute.type,
                        attribute.getter_function_name, [],
                        attribute.raises_exception, attribute.call_with,
                        attribute.is_static) }}
  if (!exception_state.is_exception_set()) {
    args.rval().set(result_value);
  }
  return !exception_state.is_exception_set();
}

{% if attribute.has_setter %}
{% if attribute.is_static %}
bool staticset_{{attribute.idl_name}}(
  JSContext* context, unsigned argc, JS::Value* vp) {
{% else %}
bool set_{{attribute.idl_name}}(
    JSContext* context, unsigned argc, JS::Value* vp) {
{% endif %}

  JS::CallArgs args = JS::CallArgsFromVp(argc, vp);
  if (!args.thisv().isObject()) {
    MozjsExceptionState exception(context);
    exception.SetSimpleException(script::kTypeError, "Invalid this.");
    return false;
  }
  JS::RootedObject object(context, &args.thisv().toObject());

{% if attribute.is_static %}
{{ static_function_prologue() }}
{% else %}
{{ check_if_object_implements_interface() }}
{{ nonstatic_function_prologue(impl_class)}}
{% endif %} {#- attribute.is_static #}
{{ set_attribute_implementation(attribute, impl_class) -}}
}
{% endif %} {#- attribute.has_setter #}

{% endif %}
{% if attribute.conditional %}
#endif  // {{attribute.conditional}}
{% endif %} {#- attribute.is_constructor_attribute #}
{% endfor %}

{%- for operation in operations + static_operations %}
{% if operation.conditional %}
#if defined({{operation.conditional}})

{% endif %}
{% set boundFunctionPrefix = "staticfcn_" if operation.is_static else "fcn_" %}
{% for overload in operation.overloads if operation.overloads|length > 1 %}
bool {{boundFunctionPrefix}}{{operation.idl_name}}{{overload.overload_index}}(
    JSContext* context, uint32_t argc, JS::Value *vp) {
{{ function_implementation(overload) -}}
}
{% endfor %}

bool {{boundFunctionPrefix}}{{operation.idl_name}}(
    JSContext* context, uint32_t argc, JS::Value *vp) {
{% if operation.overloads|length == 1 %}
{{ function_implementation(operation.overloads[0]) -}}
{% else %}
{{ overload_resolution_implementation(
      operation, boundFunctionPrefix + operation.idl_name) }}
{% endif %}
}
{% if operation.conditional %}

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

bool Stringifier(JSContext* context, unsigned argc, JS::Value *vp) {
  MozjsExceptionState exception_state(context);
  // Compute the 'this' value.
  JS::RootedValue this_value(context, JS_ComputeThis(context, vp));
  // 'this' should be an object.
  JS::RootedObject object(context);

  if (JS_TypeOfValue(context, this_value) != JSTYPE_OBJECT) {
    return false;
  }
  if (!JS_ValueToObject(context, this_value, &object)) {
    NOTREACHED();
    return false;
  }

  {{ check_if_object_implements_interface() }}

  WrapperPrivate* wrapper_private =
      WrapperPrivate::GetFromObject(context, object);

  // |WrapperPrivate::GetFromObject| can fail if |object| is not a |Wrapper|
  // object.
  if (!wrapper_private) {
    exception_state.SetSimpleException(cobalt::script::kStringifierProblem);
    return false;
  }

  {{impl_class}}* impl =
      wrapper_private->wrappable<{{impl_class}}>().get();
  if (!impl) {
    exception_state.SetSimpleException(cobalt::script::kStringifierProblem);
    NOTREACHED();
    return false;
  }
  std::string stringified = impl->{{stringifier.name}}();
  JS::CallArgs args = JS::CallArgsFromVp(argc, vp);
  JS::RootedString rooted_string(context,
      JS_NewStringCopyN(context, stringified.c_str(), stringified.length()));
  args.rval().set(JS::StringValue(rooted_string));
  return true;
}
{% endif %}

const JSPropertySpec prototype_properties[] = {
{% for attribute in attributes if not attribute.is_constructor_attribute %}
{% if attribute.conditional %}
#if defined({{attribute.conditional}})
{% endif %}
{% if attribute.has_setter %}
  {  // Read/Write property
    "{{attribute.idl_name}}",
    JSPROP_SHARED | JSPROP_ENUMERATE,
    { { &get_{{attribute.idl_name}}, NULL } },
    { { &set_{{attribute.idl_name}}, NULL } },
  },
{% else %}
  {  // Readonly attribute
    "{{attribute.idl_name}}",
    JSPROP_SHARED | JSPROP_ENUMERATE,
    { { &get_{{attribute.idl_name}}, NULL } },
    JSNATIVE_WRAPPER(NULL),
  },
{% endif %}
{% if attribute.conditional %}
#endif  // {{attribute.conditional}}
{% endif %}
{% endfor %}
  JS_PS_END
};

const JSFunctionSpec prototype_functions[] = {
{% if stringifier %}
  JS_FNSPEC("toString", Stringifier, NULL, 0, JSPROP_ENUMERATE, NULL),
{% endif %}
{% for operation in operations %}
{% if operation.conditional %}
#if defined({{operation.conditional}})
{% endif %}
  JS_FNSPEC(
      "{{ operation.idl_name }}", fcn_{{operation.idl_name}}, NULL,
      {{ operation.length }}, JSPROP_ENUMERATE, NULL),
{% if operation.conditional %}
#endif  // {{operation.conditional}}
{% endif %}
{% endfor %}
  JS_FS_END
};

const JSPropertySpec interface_object_properties[] = {
{% for attribute in static_attributes %}
{% if attribute.conditional %}
#if defined({{attribute.conditional}})
{% endif %}
{% if attribute.has_setter %}
  {  // Static read/write attribute.
    "{{attribute.idl_name}}",
    JSPROP_SHARED | JSPROP_ENUMERATE,
    { { &staticget_{{attribute.idl_name}}, NULL } },
    { { &staticset_{{attribute.idl_name}}, NULL } },
  },
{% else %}
  {  // Static readonly attribute.
    "{{attribute.idl_name}}",
    JSPROP_SHARED | JSPROP_ENUMERATE,
    { { &staticget_{{attribute.idl_name}} } },
    JSNATIVE_WRAPPER(NULL),
  },
{% endif %}
{% if attribute.conditional %}
#endif  // {{attribute.conditional}}
{% endif %}
{% endfor %}
  JS_PS_END
};

const JSFunctionSpec interface_object_functions[] = {
{% for operation in static_operations %}
{% if operation.conditional %}
#if defined({{operation.conditional}})
{% endif %}
  JS_FNSPEC(
      "{{ operation.idl_name }}", staticfcn_{{operation.idl_name}}, NULL,
      {{ operation.length }}, JSPROP_ENUMERATE, NULL),
{% if operation.conditional %}
#endif  // {{operation.conditional}}
{% endif %}
{% endfor %}
  JS_FS_END
};

const JSPropertySpec own_properties[] = {
{% for attribute in attributes if attribute.is_constructor_attribute %}
{% if attribute.conditional %}
#if defined({{attribute.conditional}})
{% endif %}
  {  // Constructor attribute
      "{{attribute.idl_name}}",
      JSPROP_SHARED | JSPROP_ENUMERATE,
      { { &get_{{attribute.idl_name}}, NULL } },
      JSNATIVE_WRAPPER(NULL),
  },
{% if attribute.conditional %}
#endif  // {{attribute.conditional}}
{% endif %}
{% endfor %}
  JS_PS_END
};

void InitializePrototypeAndInterfaceObject(
    InterfaceData* interface_data, JSContext* context,
    JS::HandleObject global_object) {
  DCHECK(!interface_data->prototype);
  DCHECK(!interface_data->interface_object);
  DCHECK(JS_IsGlobalObject(global_object));

{% if parent_interface %}
  JS::RootedObject parent_prototype(
      context, {{parent_interface}}::GetPrototype(context, global_object));
  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 %}
  // Get Error prototype.
  JS::RootedObject parent_prototype(context);
  bool success_check = JS_GetClassPrototype(
      context, js::GetExceptionProtoKey(JSEXN_ERR), &parent_prototype);
  DCHECK(success_check);
{% else %}
  JS::RootedObject parent_prototype(
      context, JS_GetObjectPrototype(context, global_object));
  {% endif %}
  DCHECK(parent_prototype);

  interface_data->prototype = JS_NewObjectWithGivenProto(
    context, &prototype_class_definition, parent_prototype
  );

  JS::RootedObject rooted_prototype(context, interface_data->prototype);
  bool success = JS_DefineProperties(
      context,
      rooted_prototype,
      prototype_properties);

  DCHECK(success);
  success = JS_DefineFunctions(
      context, rooted_prototype, prototype_functions);
  DCHECK(success);

{% if has_interface_object %}
  JS::RootedObject function_prototype(
      context, JS_GetFunctionPrototype(context, global_object));
  DCHECK(function_prototype);

  const char name[] =
      "{{ named_constructor if named_constructor else interface.name }}";

  JSFunction* function = js::NewFunctionWithReserved(
      context,
{% if constructor %}
      Constructor,
      {{constructor.length}},
{% else %}
      DummyConstructor,
      0,
{% endif %}
      JSFUN_CONSTRUCTOR,
      name);
  interface_data->interface_object = JS_GetFunctionObject(function);

  // Add the InterfaceObject.name property.
  JS::RootedObject rooted_interface_object(
      context, interface_data->interface_object);
  JS::RootedValue name_value(context);

  js::SetPrototype(context, rooted_interface_object, function_prototype);

  name_value.setString(JS_NewStringCopyZ(context, name));
  success = JS_DefineProperty(
      context, rooted_interface_object, "name", name_value, JSPROP_READONLY,
      NULL, NULL);
  DCHECK(success);
{% if constructor %}

  // Add the InterfaceObject.length property. It is set to the length of the
  // shortest argument list of all overload constructors.
  JS::RootedValue length_value(context);
  length_value.setInt32({{constructor.length}});
  success = JS_DefineProperty(
      context, rooted_interface_object, "length", length_value,
      JSPROP_READONLY, NULL, NULL);
  DCHECK(success);
{% endif %}
{% if constants %}

  // Define constants.
{% for constant in constants %}
  {
    success = JS_DefineProperty(context, rooted_prototype,
        "{{constant.idl_name}}", {{constant.value}},
        JSPROP_READONLY | JSPROP_ENUMERATE | JSPROP_PERMANENT, NULL, NULL);
    DCHECK(success);
    success = JS_DefineProperty(context, rooted_interface_object,
        "{{constant.idl_name}}", {{constant.value}},
        JSPROP_READONLY | JSPROP_ENUMERATE | JSPROP_PERMANENT, NULL, NULL);
    DCHECK(success);
  }
{% endfor %}
{% endif %}

  // Define interface object properties (excluding constants).
  success = JS_DefineProperties(context, rooted_interface_object,
                                interface_object_properties);
  DCHECK(success);

  // Define interface object functions (static).
  success = JS_DefineFunctions(context, rooted_interface_object,
                               interface_object_functions);
  DCHECK(success);

  // Set the Prototype.constructor and Constructor.prototype properties.
  DCHECK(interface_data->interface_object);
  DCHECK(interface_data->prototype);
  success = JS_LinkConstructorAndPrototype(
      context,
      rooted_interface_object,
      rooted_prototype);
  DCHECK(success);
{% endif %}
}

inline InterfaceData* GetInterfaceData(JSContext* context) {
  const int kInterfaceUniqueId = {{unique_id}};
  MozjsGlobalEnvironment* global_environment =
      static_cast<MozjsGlobalEnvironment*>(JS_GetContextPrivate(context));
  // By convention, the |MozjsGlobalEnvironment| that we are associated with
  // will hold our |InterfaceData| at index |kInterfaceUniqueId|, as we asked
  // for it to be there in the first place, and could not have conflicted with
  // any other interface.
  return global_environment->GetInterfaceData(kInterfaceUniqueId);
}

}  // namespace

{% if is_global_interface %}
JSObject* {{binding_class}}::CreateProxy(
    JSContext* context, const scoped_refptr<Wrappable>& wrappable) {

  InterfaceData* interface_data = GetInterfaceData(context);

  JS::RootedObject global_object(
      context, JS_NewGlobalObject(context,
          &instance_class_definition, NULL,
          JS::FireOnNewGlobalHook,
          JS::CompartmentOptions().setTrace(WrapperPrivate::Trace)));
  DCHECK(global_object);

  // Initialize standard JS constructors prototypes and top-level functions such
  // as Object, isNan, etc.
  JSAutoCompartment auto_compartment(context, global_object);
  bool success = JS_InitStandardClasses(context, global_object);
  DCHECK(success);

  JS::RootedObject prototype(
      context, {{binding_class}}::GetPrototype(context, global_object));
  DCHECK(prototype);
  JS_SetPrototype(context, global_object, prototype);

  JS_SetImmutablePrototype(context, global_object, &success);
  DCHECK(success);

  // Add own properties.
  success = JS_DefineProperties(context, global_object, own_properties);
  DCHECK(success);

  JS::RootedObject proxy(context,
      ProxyHandler::NewProxy(
          context, proxy_handler.Pointer(), global_object, prototype));
  WrapperPrivate::AddPrivateData(context, proxy, wrappable);

  // Set the global object proxy pointer, so we can access the standard classes
  // such as the base Object prototype when looking up our prototype.
  MozjsGlobalEnvironment* global_environment =
      static_cast<MozjsGlobalEnvironment*>(JS_GetContextPrivate(context));
  global_environment->SetGlobalObjectProxyAndWrapper(proxy, wrappable);
  return proxy;
}
{% else %}
// static
JSObject* {{binding_class}}::CreateProxy(
    JSContext* context, const scoped_refptr<Wrappable>& wrappable) {
  DCHECK(MozjsGlobalEnvironment::GetFromContext(context));
  JS::RootedObject global_object(
      context,
      MozjsGlobalEnvironment::GetFromContext(context)->global_object());
  DCHECK(global_object);

  JSAutoCompartment auto_compartment(context, global_object);
  InterfaceData* interface_data = GetInterfaceData(context);
  JS::RootedObject prototype(context, GetPrototype(context, global_object));
  DCHECK(prototype);
  JS::RootedObject new_object(
      context,
      JS_NewObjectWithGivenProto(
          context, &instance_class_definition, prototype));
  DCHECK(new_object);
  JS::RootedObject proxy(context,
      ProxyHandler::NewProxy(
          context, proxy_handler.Pointer(), new_object, prototype));
  WrapperPrivate::AddPrivateData(context, proxy, wrappable);
  return proxy;
}
{% endif %}

// static
const JSClass* {{binding_class}}::PrototypeClass(
      JSContext* context) {
  DCHECK(MozjsGlobalEnvironment::GetFromContext(context));
  JS::RootedObject global_object(
      context,
      MozjsGlobalEnvironment::GetFromContext(context)->global_object());
  DCHECK(global_object);

  JS::RootedObject prototype(context, GetPrototype(context, global_object));
  const JSClass* proto_class = JS_GetClass(prototype);
  return proto_class;
}

// static
JSObject* {{binding_class}}::GetPrototype(
    JSContext* context, JS::HandleObject global_object) {
  DCHECK(JS_IsGlobalObject(global_object));

  InterfaceData* interface_data = GetInterfaceData(context);
  if (!interface_data->prototype) {
    // Create new prototype that has all the props and methods
    InitializePrototypeAndInterfaceObject(
        interface_data, context, global_object);
  }
  DCHECK(interface_data->prototype);
  return interface_data->prototype;
}

{% if has_interface_object %}
// static
JSObject* {{binding_class}}::GetInterfaceObject(
    JSContext* context, JS::HandleObject global_object) {
  DCHECK(JS_IsGlobalObject(global_object));

  InterfaceData* interface_data = GetInterfaceData(context);
  if (!interface_data->interface_object) {
    InitializePrototypeAndInterfaceObject(
        interface_data, context, global_object);
  }
  DCHECK(interface_data->interface_object);
  return interface_data->interface_object;
}
{% endif %} {#- has_interface_object #}

namespace {

{% if constructor %}

{% for overload in constructor.overloads if constructor.overloads|length > 1 %}
bool Constructor{{overload.overload_index}}(
    JSContext* context, unsigned int argc, JS::Value* vp) {
{{ constructor_implementation(overload) -}}
}
{% endfor %}

bool Constructor(JSContext* context, unsigned int argc, JS::Value* vp) {
{% if constructor.overloads|length == 1 %}
{{ constructor_implementation(constructor.overloads[0]) -}}
{% else %}
{{ overload_resolution_implementation(constructor, "Constructor")}}
{% endif %}
}

{% endif %}

}  // namespace

{% endblock implementation %}

{% block create_global_object_impl %}

namespace cobalt {
namespace script {
namespace mozjs {

template <typename GlobalInterface>
void MozjsGlobalEnvironment::CreateGlobalObject(
    const scoped_refptr<GlobalInterface>& global_interface,
    EnvironmentSettings* environment_settings) {
  JSAutoRequest auto_request(context_);
  {{binding_class}}::CreateProxy(context_, global_interface);

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

{% for interface in all_interfaces %}
{% if interface.conditional %}
#if defined({{interface.conditional}})
{% endif %}
{# Pass in a dummy CreateProxy for global interface #}
{% if interface.name == impl_class %}
  wrapper_factory_->RegisterWrappableType(
      {{interface.name}}::{{interface.name}}WrappableType(),
      base::Bind(DummyFunctor),
      base::Bind(Mozjs{{interface.name}}::PrototypeClass));
{% else %}
  wrapper_factory_->RegisterWrappableType(
      {{interface.name}}::{{interface.name}}WrappableType(),
      base::Bind(Mozjs{{interface.name}}::CreateProxy),
      base::Bind(Mozjs{{interface.name}}::PrototypeClass));
{% endif %}
{% if interface.conditional %}
#endif  // defined({{interface.conditional}})
{% endif %}
{% endfor %}

}

}  // namespace mozjs

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

}  // namespace script
}  // namespace cobalt

{% endblock create_global_object_impl %}

{%  block enumeration_definitions %}

{% for enumeration in enumerations %}

inline void ToJSValue(
    JSContext* context,
    {{impl_class}}::{{enumeration.name}} in_enum,
    JS::MutableHandleValue out_value) {

  switch (in_enum) {
{% for value, idl_value in enumeration.value_pairs %}
    case {{impl_class}}::{{value}}:
      ToJSValue(context, std::string("{{idl_value}}"), out_value);
      return;
{% endfor %}
    default:
      NOTREACHED();
      out_value.set(JS::UndefinedValue());
  }
}

inline void FromJSValue(JSContext* context, JS::HandleValue value,
                 int conversion_flags, ExceptionState* exception_state,
                 {{impl_class}}::{{enumeration.name}}* out_enum) {
  DCHECK_EQ(0, conversion_flags) << "Unexpected conversion flags.";
  // JSValue -> IDL enum algorithm described here:
  // http://heycam.github.io/webidl/#es-enumeration
  // 1. Let S be the result of calling ToString(V).
  JS::RootedString rooted_string(context, JS::ToString(context, value));

  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 (JS_StringEqualsAscii(
      context, rooted_string, "{{idl_value}}", &match)
      && match) {
    *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 %}
