{#
 # 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 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 "base/lazy_instance.h"
#include "cobalt/script/mozjs/callback_function_conversion.h"
#include "cobalt/script/exception_state.h"
#include "cobalt/script/mozjs/conversion_helpers.h"
#include "cobalt/script/mozjs/mozjs_exception_state.h"
#include "cobalt/script/mozjs/mozjs_callback_function.h"
#include "cobalt/script/mozjs/mozjs_global_environment.h"
#include "cobalt/script/mozjs/mozjs_object_handle.h"
#include "cobalt/script/mozjs/mozjs_property_enumerator.h"
#include "cobalt/script/mozjs/mozjs_user_object_holder.h"
#include "cobalt/script/mozjs/proxy_handler.h"
#include "cobalt/script/mozjs/type_traits.h"
#include "cobalt/script/mozjs/wrapper_factory.h"
#include "cobalt/script/mozjs/wrapper_private.h"
#include "cobalt/script/property_enumerator.h"
#include "third_party/mozjs/js/src/jsapi.h"
{% if is_exception_interface %}
#include "third_party/mozjs/js/src/jsexn.h"
{% endif %}
#include "third_party/mozjs/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::mozjs::FromJSValue;
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;
using cobalt::script::mozjs::InterfaceData;
using cobalt::script::mozjs::MozjsCallbackFunction;
using cobalt::script::mozjs::MozjsExceptionState;
using cobalt::script::mozjs::MozjsGlobalEnvironment;
using cobalt::script::mozjs::MozjsUserObjectHolder;
using cobalt::script::mozjs::MozjsPropertyEnumerator;
using cobalt::script::mozjs::ProxyHandler;
using cobalt::script::mozjs::ToJSValue;
using cobalt::script::mozjs::TypeTraits;
using cobalt::script::mozjs::WrapperPrivate;
using cobalt::script::mozjs::WrapperFactory;
using cobalt::script::Wrappable;
{% 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);
}

JSBool GetNamedProperty(
    JSContext* context, JS::HandleObject object, JS::HandleId id,
    JS::MutableHandleValue vp) {
  JS::RootedValue id_value(context);
  if (!JS_IdToValue(context, id, id_value.address())) {
    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 %}
JSBool SetNamedProperty(
    JSContext* context, JS::HandleObject object, JS::HandleId id,
    JSBool strict, JS::MutableHandleValue vp) {
  JS::RootedValue id_value(context);
  if (!JS_IdToValue(context, id, id_value.address())) {
    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) }}
  return !exception_state.is_exception_set();
}

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

JSBool GetIndexedProperty(
    JSContext* context, JS::HandleObject object, JS::HandleId id,
    JS::MutableHandleValue vp) {
  JS::RootedValue id_value(context);
  if (!JS_IdToValue(context, id, id_value.address())) {
    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 %}
JSBool SetIndexedProperty(
    JSContext* context, JS::HandleObject object, JS::HandleId id,
    JSBool strict, JS::MutableHandleValue vp) {
  JS::RootedValue id_value(context);
  if (!JS_IdToValue(context, id, id_value.address())) {
    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) }}
  return !exception_state.is_exception_set();
}

{% 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 %}
JSBool Constructor(JSContext* context, unsigned int argc, JS::Value* vp);
{% endif %}
{% for constant in constants %}
JSBool get_{{constant.idl_name}}(
    JSContext* context, JS::HandleObject object, JS::HandleId id,
    JS::MutableHandleValue 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 %}
  MozjsExceptionState exception_state(context);
  JS::RootedValue result_value(context);
  ToJSValue(context, {{constant.value}}, &result_value);
  if (!exception_state.is_exception_set()) {
    vp.set(result_value);
  }
  return !exception_state.is_exception_set();
}

{% endfor %}
JSBool HasInstance(JSContext *context, JS::HandleObject type,
                   JS::MutableHandleValue vp, JSBool *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;
}

InterfaceData* CreateCachedInterfaceData() {
  InterfaceData* interface_data = new InterfaceData();
  memset(&interface_data->instance_class_definition, 0,
         sizeof(interface_data->instance_class_definition));
  memset(&interface_data->prototype_class_definition, 0,
         sizeof(interface_data->prototype_class_definition));
  memset(&interface_data->interface_object_class_definition, 0,
         sizeof(interface_data->interface_object_class_definition));

  JSClass* instance_class = &interface_data->instance_class_definition;
  const int kGlobalFlags = {{
      "JSCLASS_GLOBAL_FLAGS" if is_global_interface else 0 }};
  instance_class->name = "{{interface_name}}";
  instance_class->flags = kGlobalFlags | JSCLASS_HAS_PRIVATE;
  instance_class->addProperty = JS_PropertyStub;
  instance_class->delProperty = JS_DeletePropertyStub;
  instance_class->getProperty = JS_PropertyStub;
  instance_class->setProperty = JS_StrictPropertyStub;
  instance_class->enumerate = JS_EnumerateStub;
  instance_class->resolve = JS_ResolveStub;
  instance_class->convert = JS_ConvertStub;
  // Function to be called before on object of this class is garbage collected.
  instance_class->finalize = &WrapperPrivate::Finalizer;
  // Called to trace objects that can be referenced from this object.
  instance_class->trace = &WrapperPrivate::Trace;

  JSClass* prototype_class = &interface_data->prototype_class_definition;
  prototype_class->name = "{{interface_name}}Prototype";
  prototype_class->flags = 0;
  prototype_class->addProperty = JS_PropertyStub;
  prototype_class->delProperty = JS_DeletePropertyStub;
  prototype_class->getProperty = JS_PropertyStub;
  prototype_class->setProperty = JS_StrictPropertyStub;
  prototype_class->enumerate = JS_EnumerateStub;
  prototype_class->resolve = JS_ResolveStub;
  prototype_class->convert = JS_ConvertStub;

  JSClass* interface_object_class =
      &interface_data->interface_object_class_definition;
  interface_object_class->name = "{{interface_name}}Constructor";
  interface_object_class->flags = 0;
  interface_object_class->addProperty = JS_PropertyStub;
  interface_object_class->delProperty = JS_DeletePropertyStub;
  interface_object_class->getProperty = JS_PropertyStub;
  interface_object_class->setProperty = JS_StrictPropertyStub;
  interface_object_class->enumerate = JS_EnumerateStub;
  interface_object_class->resolve = JS_ResolveStub;
  interface_object_class->convert = JS_ConvertStub;
  interface_object_class->hasInstance = &HasInstance;
{% if constructor %}
  interface_object_class->construct = Constructor;
{% endif %}
  return interface_data;
}

{% for attribute in attributes + static_attributes %}
{% if attribute.conditional %}
#if defined({{attribute.conditional}})
{% endif %}
{% if attribute.is_constructor_attribute %}
JSBool get_{{attribute.idl_name}}(
    JSContext* context, JS::HandleObject object, JS::HandleId id,
    JS::MutableHandleValue vp) {
  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));
  vp.set(JS::ObjectValue(*interface_object));
  return true;
}

{% else %}
{% if attribute.is_static %}
JSBool staticget_{{attribute.idl_name}}(
    JSContext* context, JS::HandleObject object, JS::HandleId id,
    JS::MutableHandleValue vp) {
{{ static_function_prologue() -}}
{% else %}
JSBool get_{{attribute.idl_name}}(
    JSContext* context, JS::HandleObject object, JS::HandleId id,
    JS::MutableHandleValue vp) {
  MozjsGlobalEnvironment* global_environment =
      static_cast<MozjsGlobalEnvironment*>(JS_GetContextPrivate(context));
  WrapperFactory* wrapper_factory = global_environment->wrapper_factory();
  if (!wrapper_factory->DoesObjectImplementInterface(
        object, base::GetTypeId<{{impl_class}}>())) {
    MozjsExceptionState exception(context);
    exception.SetSimpleException(script::kDoesNotImplementInterface);
    vp.set(JS::UndefinedValue());
    return false;
  }

{{ 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()) {
    vp.set(result_value);
  }
  return !exception_state.is_exception_set();
}

{% if attribute.has_setter %}
{% if attribute.is_static %}
JSBool staticset_{{attribute.idl_name}}(
    JSContext* context, JS::HandleObject object, JS::HandleId id,
    JSBool strict, JS::MutableHandleValue vp) {
{{ static_function_prologue() }}
{% else %}
JSBool set_{{attribute.idl_name}}(
    JSContext* context, JS::HandleObject object, JS::HandleId id,
    JSBool strict, JS::MutableHandleValue vp) {
{{ 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 %}
JSBool {{boundFunctionPrefix}}{{operation.idl_name}}{{overload.overload_index}}(
    JSContext* context, uint32_t argc, JS::Value *vp) {
{{ function_implementation(overload) -}}
}

{% endfor %}
JSBool {{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 %}
JSBool 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.address())) {
    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}}", 0,
      JSPROP_PERMANENT | JSPROP_READONLY | JSPROP_ENUMERATE,
      JSOP_WRAPPER(&get_{{constant.idl_name}}),
      JSOP_NULLWRAPPER,
  },
{% 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}}", 0,
      JSPROP_SHARED | JSPROP_ENUMERATE,
      JSOP_WRAPPER(&get_{{attribute.idl_name}}),
      JSOP_WRAPPER(&set_{{attribute.idl_name}}),
  },
{% else %}
  {  // Readonly attribute
      "{{attribute.idl_name}}", 0,
      JSPROP_SHARED | JSPROP_ENUMERATE | JSPROP_READONLY,
      JSOP_WRAPPER(&get_{{attribute.idl_name}}),
      JSOP_NULLWRAPPER,
  },
{% endif %}
{% if attribute.conditional %}
#endif  // {{attribute.conditional}}
{% endif %}
{% endfor %}
  JS_PS_END
};

const JSFunctionSpec prototype_functions[] = {
{% if stringifier %}
  {
      "toString",
      JSOP_WRAPPER(&Stringifier),
      0,
      JSPROP_PERMANENT,
      NULL,
  },
{% endif %}
{% for operation in operations %}
{% if operation.conditional %}
#if defined({{operation.conditional}})
{% endif %}
  {
      "{{ operation.idl_name }}",
      JSOP_WRAPPER(&fcn_{{operation.idl_name}}),
      {{ 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}}", 0,
      JSPROP_PERMANENT | JSPROP_READONLY | JSPROP_ENUMERATE,
      JSOP_WRAPPER(&get_{{constant.idl_name}}),
      JSOP_NULLWRAPPER,
  },
{% 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}}", 0,
      JSPROP_SHARED | JSPROP_ENUMERATE,
      JSOP_WRAPPER(&staticget_{{attribute.idl_name}}),
      JSOP_WRAPPER(&staticset_{{attribute.idl_name}}),
  },
{% else %}
  {  // Static readonly attribute.
      "{{attribute.idl_name}}", 0,
      JSPROP_SHARED | JSPROP_ENUMERATE | JSPROP_READONLY,
      JSOP_WRAPPER(&staticget_{{attribute.idl_name}}),
      JSOP_NULLWRAPPER,
  },
{% 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 %}
  {
      "{{ operation.idl_name }}",
      JSOP_WRAPPER(&staticfcn_{{operation.idl_name}}),
      {{ 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}}", 0,
      JSPROP_SHARED,
      JSOP_WRAPPER(&get_{{attribute.idl_name}}),
      JSOP_NULLWRAPPER,
  },
{% 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, GetExceptionProtoKey(JSEXN_ERR), &parent_prototype);
  DCHECK(success_check);
  {% else %}
  JS::RootedObject parent_prototype(
      context, JS_GetObjectPrototype(context, global_object));
  {% endif %}
  DCHECK(parent_prototype);

  // Create the Prototype object.
  interface_data->prototype = JS_NewObjectWithGivenProto(
      context, &interface_data->prototype_class_definition, parent_prototype,
      NULL);
  bool success = JS_DefineProperties(
      context, interface_data->prototype, prototype_properties);
  DCHECK(success);
  success = JS_DefineFunctions(
      context, interface_data->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_data->interface_object_class_definition,
      function_prototype, NULL);

  // 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,
                        JS_PropertyStub, JS_StrictPropertyStub,
                        JSPROP_READONLY);
  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, JS_PropertyStub, JS_StrictPropertyStub,
                        JSPROP_READONLY);
  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);
  JS::RootedObject rooted_prototype(context, 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 = CreateCachedInterfaceData();
    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,
                                  &interface_data->instance_class_definition,
                                  NULL));
  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);

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

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

  JS::RootedObject proxy(context,
      ProxyHandler::NewProxy(context, global_object, prototype, NULL,
                             proxy_handler.Pointer()));
  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, &interface_data->instance_class_definition, prototype, NULL));
  DCHECK(new_object);
  JS::RootedObject proxy(context,
      ProxyHandler::NewProxy(context, new_object, prototype, NULL,
                             proxy_handler.Pointer()));
{% 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));
  JSClass* proto_class = JS_GetClass(*prototype.address());
  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 %}
JSBool Constructor{{overload.overload_index}}(
    JSContext* context, unsigned int argc, JS::Value* vp) {
{{ constructor_implementation(overload) -}}
}

{% endfor %}
JSBool 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);

  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_ValueToString(context, value));

  JSBool match = JS_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 %}
