{#
 # Copyright 2016 Google Inc. 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_callback_function.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_object_handle.h"
#include "cobalt/script/mozjs-45/mozjs_property_enumerator.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::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>
    proxy_handler;

{% if constructor %}
bool Constructor(JSContext* context, unsigned int argc, JS::Value* vp);
{% endif %}
{% for constant in constants %}
bool get_{{constant.idl_name}}(
    JSContext* context, unsigned argc, JS::Value* vp) {
{% if constant.can_use_compile_assert %}
  COMPILE_ASSERT({{impl_class}}::{{constant.name}} == {{constant.value}},
                 ValueFor{{impl_class}}_{{constant.name}}DoesNotMatchIDL);
{% else %}
  DCHECK_EQ({{constant.value}}, {{impl_class}}::{{constant.name}}) <<
      "The value for {{impl_class}}::{{constant.name}} does not match "
      "the value in the interface definition.";
{% endif %}
  JS::CallArgs args = JS::CallArgsFromVp(argc, vp);
  JS::RootedObject object(context, &args.thisv().toObject());
  MozjsExceptionState exception_state(context);
  JS::RootedValue result_value(context);
  ToJSValue(context, {{constant.value}}, &result_value);
  if (!exception_state.is_exception_set()) {
    args.rval().set(result_value);
  }
  return !exception_state.is_exception_set();
}

{% endfor %}
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);
  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);
  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);
  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) {
    NOTREACHED();
    return false;
  }
  if (!JS_ValueToObject(context, this_value, &object)) {
    NOTREACHED();
    return false;
  }
  WrapperPrivate* wrapper_private =
      WrapperPrivate::GetFromObject(context, object);
  {{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 constant in constants %}
  {
      "{{constant.idl_name}}",
      JSPROP_PERMANENT | JSPROP_SHARED | JSPROP_ENUMERATE,
      { { &get_{{constant.idl_name}}, NULL } },
      JSNATIVE_WRAPPER(NULL)
  },
{% endfor %}
{% 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 constant in constants %}
  {
    "{{constant.idl_name}}",
    JSPROP_SHARED | JSPROP_ENUMERATE,
    { { &get_{{constant.idl_name}}, NULL } },
    JSNATIVE_WRAPPER(NULL),
  },

{% endfor %}
{% 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));
  {% 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);
  // Create the Interface object.
  interface_data->interface_object = JS_NewObjectWithGivenProto(
      context, &interface_object_class_definition,
      function_prototype);

  // Add the InterfaceObject.name property.
  JS::RootedObject rooted_interface_object(
      context, interface_data->interface_object);
  JS::RootedValue name_value(context);
  const char name[] =
      "{{ named_constructor if named_constructor else interface.name }}";
  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 %}

  // Define interface object properties (including 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 %}
}

InterfaceData* GetInterfaceData(JSContext* context) {
  MozjsGlobalEnvironment* global_environment =
      static_cast<MozjsGlobalEnvironment*>(JS_GetContextPrivate(context));
  // Use the address of the properties definition for this interface as a
  // unique key for looking up the InterfaceData for this interface.
  intptr_t key = reinterpret_cast<intptr_t>(&own_properties);
  InterfaceData* interface_data = global_environment->GetInterfaceData(key);
  if (!interface_data) {
    interface_data = new InterfaceData();
    DCHECK(interface_data);
    global_environment->CacheInterfaceData(key, interface_data);
    DCHECK_EQ(interface_data, global_environment->GetInterfaceData(key));
  }
  return interface_data;
}

}  // 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);

  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 %}
  MozjsGlobalEnvironment* mozjs_global_environment =
      base::polymorphic_downcast<MozjsGlobalEnvironment*>(this);
  JSContext* context = mozjs_global_environment->context();

  JSAutoRequest auto_request(context);
  {{binding_class}}::CreateProxy(
      context, global_interface);
  mozjs_global_environment->SetEnvironmentSettings(environment_settings);
  mozjs_global_environment->EvaluateAutomatics();

  WrapperFactory* wrapper_factory =
      mozjs_global_environment->wrapper_factory();
{% 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 %}

{% 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 %}
