{#
 # 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 get_opaque_root %}
Wrappable* GetOpaqueRootFromWrappable(
    const scoped_refptr<Wrappable>& wrappable) {
  {{impl_class}}* impl =
      base::polymorphic_downcast<{{impl_class}}*>(wrappable.get());
  return impl->{{get_opaque_root}}();
}

{% endif %}
{% if add_opaque_roots %}
void GetReachableWrappables(const scoped_refptr<Wrappable>& wrappable,
    WrapperPrivate::WrappableVector* reachable) {
  DCHECK(reachable);
  {{impl_class}}* impl =
      base::polymorphic_downcast<{{impl_class}}*>(wrappable.get());
{% for reachable_object in add_opaque_roots %}
  Wrappable* reachable_{{loop.index0}} = impl->{{reachable_object}}();
  if (reachable_{{loop.index0}}) {
    reachable->push_back(reachable_{{loop.index0}});
  }
{% endfor %}
}

{% endif %}
{% 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));
{% if add_opaque_roots or get_opaque_root %}
  WrapperPrivate::GetOpaqueRootFunction get_root;
  WrapperPrivate::GetReachableWrappablesFunction get_reachable_wrappables;
{% if get_opaque_root %}
  get_root = base::Bind(&GetOpaqueRootFromWrappable);
{% endif %}
{% if add_opaque_roots %}
  get_reachable_wrappables = base::Bind(&GetReachableWrappables);
{% endif %}
  WrapperPrivate::AddPrivateData(
      context, proxy, wrappable, get_root, get_reachable_wrappables);
{% else %}
  WrapperPrivate::AddPrivateData(context, proxy, wrappable);
{% endif %}
  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 %}
