{#
 # Copyright 2015 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.
 #}
{% extends "interface-base.cc.template" %}
{% block includes %}
#include "third_party/WebKit/Source/JavaScriptCore/config.h"

{{ super() }}
#include "cobalt/script/javascriptcore/constructor_base.h"
#include "cobalt/script/javascriptcore/conversion_helpers.h"
#include "cobalt/script/javascriptcore/prototype_base.h"
#include "cobalt/script/javascriptcore/jsc_callback_function.h"
#include "cobalt/script/javascriptcore/jsc_callback_interface_holder.h"
#include "cobalt/script/javascriptcore/jsc_exception_state.h"
#include "cobalt/script/javascriptcore/jsc_global_environment.h"
#include "cobalt/script/javascriptcore/jsc_global_object.h"
#include "cobalt/script/javascriptcore/jsc_object_handle.h"
#include "cobalt/script/javascriptcore/jsc_object_handle_holder.h"
{% if named_property_getter %}
#include "cobalt/script/javascriptcore/jsc_property_enumerator.h"
{% endif %}
#include "cobalt/script/javascriptcore/type_traits.h"
#include "cobalt/script/javascriptcore/util/binding_helpers.h"
#include "cobalt/script/javascriptcore/util/exception_helpers.h"
#include "third_party/WebKit/Source/JavaScriptCore/interpreter/Interpreter.h"
#include "third_party/WebKit/Source/JavaScriptCore/runtime/Error.h"
{% if is_exception_interface %}
#include "third_party/WebKit/Source/JavaScriptCore/runtime/ErrorPrototype.h"
{% endif %}
#include "third_party/WebKit/Source/JavaScriptCore/runtime/FunctionPrototype.h"
#include "third_party/WebKit/Source/JavaScriptCore/runtime/Identifier.h"
#include "third_party/WebKit/Source/JavaScriptCore/runtime/JSFunction.h"
#include "third_party/WebKit/Source/JavaScriptCore/runtime/JSGlobalObject.h"
#include "third_party/WebKit/Source/JavaScriptCore/runtime/ObjectPrototype.h"
{% endblock includes %}
{% block using_directives %}
{{ super() }}
using cobalt::script::javascriptcore::kConversionFlagNullable;
using cobalt::script::javascriptcore::kConversionFlagRestricted;
using cobalt::script::javascriptcore::kConversionFlagTreatNullAsEmptyString;
using cobalt::script::javascriptcore::kConversionFlagTreatUndefinedAsEmptyString;
using cobalt::script::javascriptcore::kNoConversionFlags;
using cobalt::script::javascriptcore::ConstructorBase;
using cobalt::script::javascriptcore::GetWrappableOrSetException;
using cobalt::script::javascriptcore::FromJSValue;
using cobalt::script::javascriptcore::FromWTFString;
using cobalt::script::javascriptcore::JSCCallbackFunction;
using cobalt::script::javascriptcore::JSCCallbackFunctionHolder;
using cobalt::script::javascriptcore::JSCCallbackInterfaceHolder;
using cobalt::script::javascriptcore::JSCEngine;
using cobalt::script::javascriptcore::JSCExceptionState;
using cobalt::script::javascriptcore::JSCGlobalEnvironment;
using cobalt::script::javascriptcore::JSCGlobalObject;
using cobalt::script::javascriptcore::JSCObjectHandle;
using cobalt::script::javascriptcore::JSCObjectHandleHolder;
{% if named_property_getter %}
using cobalt::script::javascriptcore::JSCPropertyEnumerator;
{% endif %}
using cobalt::script::javascriptcore::JSObjectToWrappable;
using cobalt::script::javascriptcore::PrototypeBase;
using cobalt::script::javascriptcore::ScriptObjectRegistry;
using cobalt::script::javascriptcore::ThreadLocalHashTable;
using cobalt::script::javascriptcore::ToJSValue;
using cobalt::script::javascriptcore::ToWTFString;
using cobalt::script::javascriptcore::TypeTraits;
using cobalt::script::javascriptcore::WrapperBase;
using cobalt::script::javascriptcore::util::HasPropertyOnPrototype;
using cobalt::script::javascriptcore::util::GetStackTrace;
{% 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 %}
JSC::JSValue ToJSValue(JSCGlobalObject*, {{impl_class}}::{{enumeration.name}} in_enum);
void FromJSValue(JSC::ExecState* exec_state, JSC::JSValue jsvalue,
    int conversion_flags, JSCExceptionState* exception_state,
    {{impl_class}}::{{enumeration.name}}* out_enum);
{% endfor %}
{% endif %}
{% endblock enumeration_declarations %}

{% from 'macros.cc.template' import add_extra_arguments %}
{% from 'macros.cc.template' import call_function %}
{% from 'macros.cc.template' import constructor_implementation with context %}
{% from 'macros.cc.template' import function_implementation with context %}
{% from 'macros.cc.template' import overload_resolution_implementation with context %}
{% from 'macros.cc.template' import set_attribute_implementation with context %}
{% from 'interface-object.template' import create_interface_object with context %}

{% block implementation %}
namespace {
{% for constant in constants %}
JSC::JSValue getJS{{constant.idl_name}}(
    JSC::ExecState* exec_state,
    JSC::JSValue slot_base,
    JSC::PropertyName property_name);
{% endfor %}
{% for attribute in attributes + static_attributes %}
{% if attribute.conditional %}
#if defined({{attribute.conditional}})
{% endif %}
JSC::JSValue getJS{{attribute.idl_name}}(
    JSC::ExecState* exec_state,
    JSC::JSValue slot_base,
    JSC::PropertyName property_name);
{% if attribute.has_setter %}
void setJS{{attribute.idl_name}}(
    JSC::ExecState* exec,
    JSC::JSObject* this_object,
    JSC::JSValue value);
{% endif %}
{% if attribute.conditional %}
#endif  // defined({{attribute.conditional}})
{% endif %}
{% endfor %}
{% if constructor %}
JSC::EncodedJSValue constructorJS{{impl_class}}(JSC::ExecState*);
{% for overload in constructor.overloads if constructor.overloads|length > 1 %}
JSC::EncodedJSValue constructorJS{{impl_class}}{{overload.overload_index}}(JSC::ExecState*);
{% endfor %}
{% endif %}
{% for operation in operations + static_operations %}
{% if operation.conditional %}
#if defined({{operation.conditional}})
{% endif %}
{% set boundFunctionPrefix = "staticFunctionJS" if operation.is_static else "functionJS" %}
JSC::EncodedJSValue {{boundFunctionPrefix}}{{operation.idl_name}}(JSC::ExecState*);
{% for overload in operation.overloads if operation.overloads|length > 1 %}
JSC::EncodedJSValue {{boundFunctionPrefix}}{{overload.idl_name}}{{overload.overload_index}}(JSC::ExecState*);
{% endfor %}
{% if operation.conditional %}
#endif  // defined({{operation.conditional}})
{% endif %}
{% endfor %}
{% if indexed_property_getter %}
JSC::JSValue IndexedPropertyGetter(JSC::ExecState* exec_state,
    JSC::JSValue slot_base, uint32_t index);
{% endif %}
{% if indexed_property_setter %}
void IndexedPropertySetter(JSC::JSCell* cell,
    JSC::ExecState* exec_state, uint32_t index, JSC::JSValue value);
{% endif %}
{% if stringifier %}
JSC::EncodedJSValue StringifierJS(JSC::ExecState*);
{% endif %}

// These are declared unconditionally, but only defined if needed by the
// interface.
JSC::JSValue NamedPropertyGetter(JSC::ExecState* exec_state,
    JSC::JSValue slot_base, JSC::PropertyName property_name);
void NamedPropertySetter(JSC::JSCell* cell, JSC::ExecState* exec_state,
    JSC::PropertyName property_name, JSC::JSValue jsc_value);
bool NamedPropertyDeleter(JSC::JSCell* cell, JSC::ExecState* exec_state,
    JSC::PropertyName property_name);
bool QueryNamedProperty(JSC::JSCell* cell, JSC::ExecState* exec_state,
    JSC::PropertyName property_name);
JSC::JSValue OnGetMissingProperty(JSC::ExecState* exec_state,
    JSC::JSValue slot_base, JSC::PropertyName property_name);
bool OnSetMissingProperty(JSC::JSCell* cell, JSC::ExecState* exec_state,
    JSC::PropertyName property_name, JSC::JSValue value);

const bool s_has_named_getter = {{'true' if named_property_getter else 'false'}};
const bool s_has_named_setter = {{'true' if named_property_setter else 'false'}};
#if !defined(COBALT_BUILD_TYPE_GOLD)
const bool s_use_debug_missing_property_handler = {{'true' if not parent_interface else 'false'}};
#else
const bool s_use_debug_missing_property_handler = false;
#endif
{% if get_opaque_root %}
scoped_refptr<Wrappable> GetOpaqueRootFromWrappable(
    const scoped_refptr<Wrappable>& wrappable) {
  {{impl_class}}* impl =
      base::polymorphic_downcast<{{impl_class}}*>(wrappable.get());
  Wrappable* opaque_root = impl->{{get_opaque_root}}();
  return make_scoped_refptr<Wrappable>(opaque_root);
}
{% endif %}
}  // namespace

{% if has_interface_object %}
{{create_interface_object("InterfaceObject", impl_class)}}
{% endif %}
{% if named_constructor %}
{{create_interface_object("NamedInterfaceObject", named_constructor)}}
{% endif %}
{% include "prototype-object.template" %}

const JSC::HashTableValue {{binding_class}}::property_table_values[] = {
{% for attribute in attributes %}
{% if attribute.conditional %}
#if defined({{attribute.conditional}})
{% endif %}
    { "{{attribute.idl_name}}",
        JSC::DontDelete {{'| JSC::ReadOnly' if not attribute.has_setter}},
        reinterpret_cast<intptr_t>(getJS{{attribute.idl_name}}),
        {% if attribute.has_setter %}
        reinterpret_cast<intptr_t>(setJS{{attribute.idl_name}}),
        {% else %}
        0,
        {% endif %}
        JSC::NoIntrinsic
    },
{% if attribute.conditional %}
#endif   // defined({{attribute.conditional}})
{% endif %}
{% endfor %}
{% if is_global_interface %}
{% for operation in operations %}
{% if operation.conditional %}
#if defined({{operation.conditional}})
{% endif %}
    { "{{operation.idl_name}}",
        JSC::DontDelete | JSC::Function,
        reinterpret_cast<intptr_t>(functionJS{{operation.idl_name}}),
        static_cast<intptr_t>({{operation.length}}),
        JSC::NoIntrinsic
    },
{% if operation.conditional %}
#endif  // defined({{operation.conditional}})
{% endif %}
{% endfor %}
{% endif %}
    { 0, 0, 0, 0, static_cast<JSC::Intrinsic>(0) }
};  // {{binding_class}}::property_table_values

// static
const JSC::HashTable {{binding_class}}::property_table_prototype = {
{# This doesn't take into account disabled properties, but this is okay. This
   value must be at least as large as the number of properties. #}
{% set num_properties = attributes|length %}
{% if is_global_interface %}
{% set num_properties = num_properties + operations|length %}
{% endif %}
    {{ calculate_jsc_lookup_size(num_properties) }},  // compactSize
    {{ calculate_jsc_lookup_size_mask(num_properties) }},  // compactSizeMask
    property_table_values,
    NULL  // table allocated at runtime
};  // {{binding_class}}::property_table_prototype

// static
const JSC::HashTable* {{binding_class}}::GetPropertyTable(
    JSC::ExecState* exec_state) {
  return ThreadLocalHashTable::GetInstance()->GetHashTable(
      {{binding_class}}::s_classinfo(), property_table_prototype);
}

#ifdef __LB_SHELL__FORCE_LOGGING__
base::LazyInstance<{{binding_class}}::NonTrivialStaticFields>
    {{binding_class}}::non_trivial_static_fields = LAZY_INSTANCE_INITIALIZER;
#endif  // __LB_SHELL__FORCE_LOGGING__

const JSC::ClassInfo {{binding_class}}::s_info = {
    "{{interface_name}}",  // className
    BaseClass::s_classinfo(),  // parentClass
    NULL,  // static hash-table of properties (not used)
    GetPropertyTable,  // function pointer to get hash-table of properties
    CREATE_METHOD_TABLE({{binding_class}})
};  // {{binding_class}}::s_info

// static
JSC::JSObject* {{binding_class}}::GetPrototype(
    JSC::JSGlobalObject* global_object) {
  return Prototype::GetInstance(global_object);
}

{% if has_interface_object %}
// static
JSC::JSObject* {{binding_class}}::GetConstructor(
    JSC::ExecState* exec_state) {
  return InterfaceObject::GetInstance(exec_state);
}

// static
JSC::JSValue {{binding_class}}::Prototype::GetConstructor(
      JSC::ExecState* exec_state,
      JSC::JSValue slot_base,
      JSC::PropertyName property_name) {
  return JSC::JSValue(InterfaceObject::GetInstance(exec_state));
}
{% endif %}
{% if named_constructor %}
JSC::JSObject* {{binding_class}}::GetNamedConstructor(
    JSC::ExecState* exec_state) {
  return NamedInterfaceObject::GetInstance(exec_state);
}
{% endif %}
{% if is_global_interface %}

// static
script::javascriptcore::JSCGlobalObject* {{binding_class}}::Create(
    const scoped_refptr<{{impl_class}}>& global_interface,
    script::EnvironmentSettings* environment_settings,
    JSC::JSGlobalData* global_data,
    ScriptObjectRegistry* script_object_registry) {
  scoped_ptr<script::javascriptcore::WrapperFactory> wrapper_factory =
      make_scoped_ptr(new script::javascriptcore::WrapperFactory());
{% for interface in all_interfaces %}
{% if interface.conditional %}
#if defined({{interface.conditional}})
{% endif %}
  {# Don't register a create method for the global interface, since we do not
     create a wrapper for it directly. #}
  {% if interface.name != impl_class %}
  wrapper_factory->RegisterWrappableType(
      {{interface.name}}::{{interface.name}}WrappableType(),
      JSC{{interface.name}}::s_classinfo(),
      JSC{{interface.name}}::GetCreateWrapperFunction());
  {% endif %}
{% if interface.conditional %}
#endif  // defined({{interface.conditional}})
{% endif %}
{% endfor %}

  JSC::JSLockHolder lock(global_data);
  JSC::Structure* structure = JSC::Structure::create(
      *global_data,
      NULL,           // JSC::JSGlobalObject*
      JSC::jsNull(),  // prototype
      JSC::TypeInfo(JSC::GlobalObjectType, StructureFlags),
      &s_info);
  {{binding_class}}* global_wrapper =
      new (NotNull, JSC::allocateCell<{{binding_class}}>(global_data->heap))
      {{binding_class}}(
          global_data,
          structure,
          script_object_registry,
          wrapper_factory.Pass(),
          environment_settings,
          global_interface);
  global_wrapper->finishCreation(*global_data);
  global_data->heap.addFinalizer(global_wrapper, {{binding_class}}::destroy);
  global_wrapper->setPrototype(
      global_wrapper->globalData(),
      {{binding_class}}::GetPrototype(global_wrapper));

  return global_wrapper;
}
{% else %}

// static
JSC::JSObject* {{binding_class}}::Create(
    JSCGlobalObject* global_object,
    const scoped_refptr<Wrappable>& wrappable) {
  if (!(wrappable->GetWrappableType() == {{impl_class}}::{{impl_class}}WrappableType())) {
    NOTREACHED() << "Type of wrappable does not match {{impl_class}}::{{impl_class}}WrappableType()";
    return NULL;
  }
  {{impl_class}}* impl_ptr =
      base::polymorphic_downcast<{{impl_class}}*>(wrappable.get());

  JSC::JSGlobalData& global_data = global_object->globalData();

  // Get or Create the prototype object for this interface.
  JSC::JSObject* prototype = Prototype::GetInstance(global_object);
  DCHECK(prototype);

  JSC::JSLockHolder lock(global_data);
  // Create a JSC::Structure object for this instance.
{% if is_exception_interface %}
  JSC::TypeInfo type_info(JSC::ErrorInstanceType, StructureFlags);
{% else %}
  JSC::TypeInfo type_info(JSC::ObjectType, StructureFlags);
{% endif %}
  JSC::Structure* structure = JSC::Structure::create(
      global_data,
      global_object,
      JSC::JSValue(prototype),
      type_info,
      &s_info);

  // Instantiate a new garbage-collected wrapper object.
  {{binding_class}}* wrapper =
      new (NotNull, JSC::allocateCell<{{binding_class}}>(global_data.heap))
      {{binding_class}}(
          &global_data,
          structure,
          global_object->script_object_registry(),
          make_scoped_refptr(impl_ptr));
  wrapper->finishCreation(global_data);
{% if is_exception_interface %}
  global_data.heap.addFinalizer(wrapper, destroy);
{% endif %}
  return wrapper;
}
{% endif %}
{{binding_class}}::{{binding_class}}(
    JSC::JSGlobalData* global_data,
    JSC::Structure* structure,
    ScriptObjectRegistry* script_object_registry,
{% if is_global_interface %}
    scoped_ptr<script::javascriptcore::WrapperFactory> wrapper_factory,
    script::EnvironmentSettings* environment_settings,
{% endif %}
    const scoped_refptr<{{impl_class}}>& impl)
    : BaseClass(global_data, structure, script_object_registry, impl{% if is_global_interface %},
      wrapper_factory.Pass(), environment_settings{% endif %}) {
{% if get_opaque_root %}
  set_get_opaque_root_function(base::Bind(&GetOpaqueRootFromWrappable));
{% endif %}
}

void {{binding_class}}::finishCreation(JSC::JSGlobalData& global_data) {
{% if is_exception_interface %}
  WTF::String error_message = ToWTFString(wrappable()->message());
  BaseClass::finishCreation(global_data, error_message);
{% else %}
  BaseClass::finishCreation(global_data);
{% endif %}
  DCHECK(inherits(&s_info));
}

{{binding_class}}::~{{binding_class}}() {
  // Empty destructor
}
{% if add_opaque_roots %}

void {{binding_class}}::visitChildren(JSC::JSCell* cell, JSC::SlotVisitor& visitor) {
  WrapperBase<JSC::JSDestructibleObject, Wrappable>::visitChildren(
      cell, visitor);

  JSCGlobalObject* global_object = JSC::jsCast<JSCGlobalObject*>(
      JSC::jsCast<JSObject*>(cell)->globalObject());

  {{impl_class}}* impl = base::polymorphic_downcast<{{impl_class}}*>(
      JSC::jsCast<WrapperBase*>(cell)->wrappable().get());

{% for opaque_root in add_opaque_roots %}
  Wrappable* opaque_root{{loop.index0}} = impl->{{opaque_root}}();
  if (opaque_root{{loop.index0}}) {
    visitor.addOpaqueRoot(opaque_root{{loop.index0}});
  }
{% endfor %}
}
{% endif %}

// Look up property slot for querying property values.
bool {{binding_class}}::getOwnPropertySlot(JSC::JSCell* cell,
    JSC::ExecState* exec, JSC::PropertyName property_name,
    JSC::PropertySlot& slot) {
  {{binding_class}}* this_object = JSC::jsCast<{{binding_class}}*>(cell);
  ASSERT_GC_OBJECT_INHERITS(this_object, &s_info);
{% if is_global_interface %}
  // Global interface may have both operations and properties as own properties
  // so we cannot use getStaticValueSlot.
  bool found_property_slot = JSC::getStaticPropertySlot<{{binding_class}}, BaseClass>(
      exec, GetPropertyTable(exec), this_object, property_name, slot);
{% else %}
  bool found_property_slot = JSC::getStaticValueSlot<{{binding_class}}, BaseClass>(
      exec, GetPropertyTable(exec), this_object, property_name, slot);
{% endif %}
  if (s_has_named_getter || s_use_debug_missing_property_handler) {
    bool found_property_on_prototype_chain = false;
    if (!found_property_slot && cell->isObject()) {
      JSC::JSValue prototype_value = JSC::asObject(cell)->prototype();
      if (prototype_value.isObject()) {
        JSC::JSObject* prototype = JSC::asObject(prototype_value);
        found_property_on_prototype_chain =
            prototype->hasProperty(exec, property_name);
      }
    }
    if (s_has_named_getter) {
      if (!found_property_slot && !found_property_on_prototype_chain) {
        if (QueryNamedProperty(this_object, exec, property_name)) {
          slot.setCustom(cell, &NamedPropertyGetter);
          found_property_slot = true;
        }
      }
    }
    if (s_use_debug_missing_property_handler) {
      // The property was not found as an own-property, nor was it found on the
      // prototype chain, so set the missing property handler to be called
      // when getting this property value.
      if (!found_property_slot && !found_property_on_prototype_chain) {
        slot.setCustom(cell, &OnGetMissingProperty);
        found_property_slot = true;
      }
    }
  }
  return found_property_slot;
}
{% if indexed_property_getter or named_property_getter %}

// static
bool {{binding_class}}::getOwnPropertySlotByIndex(JSC::JSCell* cell,
    JSC::ExecState* exec_state, uint32_t index, JSC::PropertySlot& slot) {
  {{impl_class}}* impl =
      GetWrappableOrSetException<{{impl_class}}>(exec_state, cell);
  if (!impl) {
    return false;
  }
{% if indexed_property_getter %}
  if (index < impl->length()) {
    slot.setCustomIndex(cell, index, IndexedPropertyGetter);
    return true;
  }
{% endif %}
  if (s_has_named_getter) {
    {{binding_class}}* this_object = JSC::jsCast<{{binding_class}}*>(cell);
    JSC::PropertyName property_name = JSC::Identifier::from(exec_state, index);
    bool has_property = HasOwnPropertyOrPrototypeProperty(
        cell, exec_state, property_name);
    if (!has_property) {
      if (QueryNamedProperty(this_object, exec_state, property_name)) {
        slot.setCustom(cell, &NamedPropertyGetter);
        return true;
      }
    }
  }
  return Base::getOwnPropertySlotByIndex(cell, exec_state, index, slot);
}

void {{binding_class}}::getOwnPropertyNames(JSC::JSObject* object,
    JSC::ExecState* exec_state, JSC::PropertyNameArray& property_names,
    JSC::EnumerationMode mode) {
  {{impl_class}}* impl =
      GetWrappableOrSetException<{{impl_class}}>(exec_state, object);
  if (impl) {
{% if indexed_property_getter %}
    for (uint32 i = 0; i < impl->length(); ++i) {
      property_names.add(JSC::Identifier::from(exec_state, i));
    }
{% endif %}
{% if named_property_getter %}
    JSCPropertyEnumerator enumerator(exec_state, &property_names);
    impl->EnumerateNamedProperties(&enumerator);
{% endif %}
    Base::getOwnPropertyNames(object, exec_state, property_names, mode);
  }
}
{% endif %}

// Look up property slot and put the |value|.
void {{binding_class}}::put(JSC::JSCell* cell, JSC::ExecState* exec,
    JSC::PropertyName property_name, JSC::JSValue value,
    JSC::PutPropertySlot& slot) {
  {{binding_class}}* this_object = JSC::jsCast<{{binding_class}}*>(cell);
  ASSERT_GC_OBJECT_INHERITS(this_object, &s_info);
  bool property_handled = false;
  if (s_has_named_setter || s_use_debug_missing_property_handler) {
    // Need to look up the property manually.
    bool has_property = HasOwnPropertyOrPrototypeProperty(
        cell, exec, property_name);

    if (s_has_named_setter) {
      // We didn't find the property on the object or prototype chain, so
      // set or create a new named property.
      if (!has_property) {
        std::string property_name_utf8 = FromWTFString(property_name.publicName());
        NamedPropertySetter(cell, exec, property_name, value);
        property_handled = true;
      }
    }
    if (s_use_debug_missing_property_handler) {
      if (!has_property && !property_handled) {
        property_handled = OnSetMissingProperty(cell, exec, property_name, value);
      }
    }
{% if not is_global_interface and not parent_interface %}
#ifdef __LB_SHELL__FORCE_LOGGING__
    std::string property_name_utf8 = FromWTFString(property_name.publicName());

    base::AutoLock lock(non_trivial_static_fields.Get().lock_);
    base::hash_set<std::string>& properties_warned_about =
        non_trivial_static_fields.Get().properties_warned_about;

    if (properties_warned_about.find(property_name_utf8) ==
        properties_warned_about.end()) {
      properties_warned_about.insert(property_name_utf8);
      WTF::String class_name = cell->className();
      DLOG_IF(WARNING, !has_property) << "Did not find property named " <<
              property_name_utf8 << " to set on wrapper for "
              << FromWTFString(class_name)
              << std::endl << StackTraceToString(GetStackTrace(exec, 32))
              << std::endl;
    }
#endif  // __LB_SHELL__FORCE_LOGGING__
{% endif %}
  }

  if (!property_handled) {
    JSC::lookupPut<{{binding_class}}, BaseClass>(
        exec, property_name, value, GetPropertyTable(exec), this_object, slot);
  }
}
{% if indexed_property_setter or named_property_setter %}

// static
void {{binding_class}}::putByIndex(JSC::JSCell* cell,
    JSC::ExecState* exec_state, uint32_t index, JSC::JSValue value,
    bool should_throw) {
  {{impl_class}}* impl =
      GetWrappableOrSetException<{{impl_class}}>(exec_state, cell);
  if (impl) {
    bool property_handled = false;
{% if indexed_property_setter %}
    if (index < impl->length()) {
      IndexedPropertySetter(cell, exec_state, index, value);
      property_handled = true;
    }
{% endif %}
    if (s_has_named_setter) {
      if (!property_handled) {
        JSC::PropertyName property_name = JSC::Identifier::from(exec_state, index);
        bool has_property = HasOwnPropertyOrPrototypeProperty(
            cell, exec_state, property_name);
        if (!has_property) {
          NamedPropertySetter(cell, exec_state, property_name, value);
          property_handled = true;
        }
      }
    }
    if (!property_handled) {
      Base::putByIndex(cell, exec_state, index, value, should_throw);
    }
  }
}

{% endif %}
{% if supports_named_properties %}

bool {{binding_class}}::deleteProperty(JSC::JSCell* cell,
                                       JSC::ExecState* exec_state,
                                       JSC::PropertyName property_name) {
  TRACE_EVENT1("{{binding_class}}", "deleteProperty", "property",
               TRACE_STR_COPY(WTF::String(property_name.publicName()).utf8().data()));
  {{impl_class}}* impl =
      GetWrappableOrSetException<{{impl_class}}>(exec_state, cell);
  if (impl) {
    bool has_property = HasOwnPropertyOrPrototypeProperty(
        cell, exec_state, property_name);
    if (!has_property &&
        QueryNamedProperty(cell, exec_state, property_name)) {
      return NamedPropertyDeleter(cell, exec_state, property_name);
    }
    return Base::deleteProperty(cell, exec_state, property_name);
  }
  return false;
}
{% endif %}
{% if supports_named_properties or supports_indexed_properties %}

bool {{binding_class}}::deletePropertyByIndex(JSC::JSCell* cell,
                                              JSC::ExecState* exec_state,
                                              uint32_t index) {
  TRACE_EVENT0("{{binding_class}}", "deletePropertyByIndex");
  {{impl_class}}* impl =
      GetWrappableOrSetException<{{impl_class}}>(exec_state, cell);
  if (impl) {
{% if supports_indexed_properties %}
    // https://heycam.github.io/webidl/#delete
    // Return true if index is not a supported property index.
    return index >= impl->length();
{% elif supports_named_properties %}
    JSC::PropertyName property_name = JSC::Identifier::from(exec_state, index);
    bool has_property = HasOwnPropertyOrPrototypeProperty(
        cell, exec_state, property_name);
    if (!has_property &&
        QueryNamedProperty(cell, exec_state, property_name)) {
      return NamedPropertyDeleter(cell, exec_state, property_name);
    }
    return Base::deletePropertyByIndex(cell, exec_state, index);
{% endif %}
  }
  return false;
}
{% endif %}

bool {{binding_class}}::HasOwnPropertyOrPrototypeProperty(
    JSC::JSCell* cell, JSC::ExecState* exec_state,
    JSC::PropertyName property_name) {
  {{binding_class}}* this_object = JSC::jsCast<{{binding_class}}*>(cell);
  JSC::PropertySlot lookup_slot;
  bool has_property = JSC::getStaticPropertySlot<{{binding_class}}, BaseClass>(
      exec_state, GetPropertyTable(exec_state), this_object, property_name,
      lookup_slot);
  return has_property || HasPropertyOnPrototype(exec_state, cell, property_name);
}

namespace {
{% for constant in constants %}

JSC::JSValue getJS{{constant.idl_name}}(
    JSC::ExecState* exec_state, JSC::JSValue, JSC::PropertyName) {
  TRACE_EVENT0("{{binding_class}}", "get {{constant.idl_name}}");
{% 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 %}
  // JSCGlobalObject* is only needed for non-primitive types.
  return ToJSValue(NULL, {{constant.value}});
}
{% endfor %}
{% for attribute in attributes + static_attributes %}

{% if attribute.conditional %}
#if defined({{attribute.conditional}})
{% endif %}
JSC::JSValue getJS{{attribute.idl_name}}(
    JSC::ExecState* exec_state,
    JSC::JSValue slot_base,
    JSC::PropertyName property_name) {
  TRACE_EVENT0("{{binding_class}}", "get {{attribute.idl_name}}");
  JSCGlobalObject* global_object =
      JSC::jsCast<JSCGlobalObject*>(exec_state->lexicalGlobalObject());
{% if not attribute.is_static %}
  {{impl_class}}* impl =
      GetWrappableOrSetException<{{impl_class}}>(exec_state, slot_base);
  if (!impl) {
    return exec_state->exception();
  }
{% endif %}
{% if attribute.raises_exception %}
  JSCExceptionState exception_state(global_object);
{% endif %}

{% if attribute.is_named_constructor_attribute %}
  JSC::JSObject* constructor_object =
      JSC{{attribute.interface_name}}::GetNamedConstructor(
          global_object->globalExec());
  DCHECK(constructor_object)
      << "NULL constructor returned for {{attribute.interface_name}}.";
  return JSC::JSValue(constructor_object);
{% elif attribute.is_constructor_attribute %}
  JSC::JSObject* constructor_object =
      JSC{{attribute.interface_name}}::GetConstructor(
          global_object->globalExec());
  DCHECK(constructor_object)
      << "NULL constructor returned for {{attribute.interface_name}}.";
  return JSC::JSValue(constructor_object);
{% else %}
{% call(arguments_list) add_extra_arguments('global_object', [], attribute) %}
  JSC::JSValue result = ToJSValue(
      global_object,
      {{ call_function("impl", impl_class, attribute.getter_function_name, arguments_list, attribute.is_static) -}});
{% if attribute.raises_exception %}
  if (exception_state.is_exception_set()) {
    return JSC::throwError(exec_state, exception_state.exception_object());
  }
{% endif %}
  return result;
{% endcall %}
{% endif %}
}
{% if attribute.has_setter %}

void setJS{{attribute.idl_name}}(
    JSC::ExecState* exec_state,
    JSC::JSObject* this_object,
    JSC::JSValue value) {
  TRACE_EVENT0("{{binding_class}}", "set {{attribute.idl_name}}");
  JSCGlobalObject* global_object =
      JSC::jsCast<JSCGlobalObject*>(exec_state->lexicalGlobalObject());
  JSCExceptionState exception_state(global_object);
{% if not attribute.is_static %}
  {{impl_class}}* impl =
      GetWrappableOrSetException<{{impl_class}}>(exec_state, this_object);
  if (!impl) {
    return;
  }
{% endif %}
{{ set_attribute_implementation(attribute, impl_class, "impl") }}
}
{% endif %}
{% if attribute.conditional %}
#endif  // defined({{attribute.conditional}})
{% endif %}
{% endfor %}
{% if constructor %}

JSC::EncodedJSValue constructorJS{{impl_class}}(JSC::ExecState* exec_state) {
{% if constructor.overloads|length == 1 %}
{{constructor_implementation(constructor.overloads[0])}}
{% else %}
{{overload_resolution_implementation(constructor, 'constructorJS' + impl_class)}}
{% endif %}
}
{% for overload in constructor.overloads if constructor.overloads|length > 1 %}

JSC::EncodedJSValue constructorJS{{impl_class}}{{overload.overload_index}}(JSC::ExecState* exec_state) {
{{constructor_implementation(overload)}}
}
{% endfor %}
{% endif %}
{% for operation in operations + static_operations %}
{% if operation.conditional %}
#if defined({{operation.conditional}})
{% endif %}

{% set boundFunctionPrefix = "staticFunctionJS" if operation.is_static else "functionJS" %}
JSC::EncodedJSValue {{boundFunctionPrefix}}{{operation.idl_name}}(
    JSC::ExecState* exec_state) {
  TRACE_EVENT0("{{binding_class}}", "call {{operation.idl_name}}");
{% if operation.overloads|length == 1 %}
{{function_implementation(operation.overloads[0])}}
{% else %}
{{overload_resolution_implementation(operation, boundFunctionPrefix + operation.idl_name)}}
{% endif %}
}
{% for overload in operation.overloads if operation.overloads|length > 1 %}

JSC::EncodedJSValue {{boundFunctionPrefix}}{{operation.idl_name}}{{overload.overload_index}}(
    JSC::ExecState* exec_state) {
{{function_implementation(overload)}}
}
{% endfor %}
{% if operation.conditional %}
#endif  // defined({{operation.conditional}})
{% endif %}
{% endfor %}
{% if indexed_property_getter %}

JSC::JSValue IndexedPropertyGetter(JSC::ExecState* exec_state,
    JSC::JSValue slot_base, uint32_t index) {
  TRACE_EVENT0("{{binding_class}}", "IndexedPropertyGetter");
  {{impl_class}}* impl =
      GetWrappableOrSetException<{{impl_class}}>(exec_state, slot_base);
  if (!impl) {
    return exec_state->exception();
  }
  JSCGlobalObject* global_object =
      JSC::jsCast<JSCGlobalObject*>(exec_state->lexicalGlobalObject());
  JSCExceptionState exception_state(global_object);
{% call(arguments_list)
    add_extra_arguments('global_object', ['index'], indexed_property_getter) %}
  JSC::JSValue result = ToJSValue(
      global_object,
      {{ call_function("impl", impl_class, indexed_property_getter.name,
                       arguments_list, False) -}});
{% if indexed_property_getter.raises_exception %}
  if (exception_state.is_exception_set()) {
    return JSC::throwError(exec_state, exception_state.exception_object());
  }
{% endif %}
  return result;
{% endcall %}
}
{% endif %}
{% if indexed_property_setter %}

void IndexedPropertySetter(JSC::JSCell* cell,
      JSC::ExecState* exec_state, uint32_t index, JSC::JSValue jsc_value) {
  TRACE_EVENT0("{{binding_class}}", "IndexedPropertySetter");
  {{impl_class}}* impl =
      GetWrappableOrSetException<{{impl_class}}>(exec_state, cell);
  if (!impl) {
    return;
  }

  JSCGlobalObject* global_object =
      JSC::jsCast<JSCGlobalObject*>(exec_state->lexicalGlobalObject());
  JSCExceptionState exception_state(global_object);
  {{indexed_property_setter.type}} value;
  FromJSValue(exec_state, jsc_value,
      {{indexed_property_setter.conversion_flags}},
      &exception_state, &value);
  if (exception_state.is_exception_set()) {
    JSC::throwError(exec_state, exception_state.exception_object());
    return;
  }
{% call(arguments_list) add_extra_arguments(
    'global_object', ['index', 'value'], indexed_property_setter) %}
  {{ call_function("impl", impl_class, indexed_property_setter.name,
                   arguments_list, False) -}};
{% if indexed_property_setter.raises_exception %}
  if (exception_state.is_exception_set()) {
    JSC::throwError(exec_state, exception_state.exception_object());
  }
{% endif %}
{% endcall %}
}
{% endif %}
{% if named_property_getter %}

JSC::JSValue NamedPropertyGetter(JSC::ExecState* exec_state,
    JSC::JSValue slot_base, JSC::PropertyName property_name) {
  TRACE_EVENT0("{{binding_class}}", "NamedPropertyGetter");
  {{impl_class}}* impl =
      GetWrappableOrSetException<{{impl_class}}>(exec_state, slot_base);
  if (!impl) {
    return exec_state->exception();
  }
  JSCGlobalObject* global_object =
      JSC::jsCast<JSCGlobalObject*>(exec_state->lexicalGlobalObject());
  JSCExceptionState exception_state(global_object);
  std::string property_name_utf8 = FromWTFString(property_name.publicName());
{% call(arguments_list) add_extra_arguments('global_object', ['property_name_utf8'], named_property_getter) %}
  JSC::JSValue result = ToJSValue(
      global_object,
      {{ call_function("impl", impl_class, named_property_getter.name, arguments_list, False) -}});
{% if named_property_getter.raises_exception %}
  if (exception_state.is_exception_set()) {
    return JSC::throwError(exec_state, exception_state.exception_object());
  }
{% endif %}
  return result;
{% endcall %}
}

bool QueryNamedProperty(JSC::JSCell* cell, JSC::ExecState* exec_state,
    JSC::PropertyName property_name) {
  {{impl_class}}* impl =
      GetWrappableOrSetException<{{impl_class}}>(exec_state, cell);
  if (!impl) {
    return false;
  }
  std::string property_name_utf8 = FromWTFString(property_name.publicName());
  return impl->CanQueryNamedProperty(property_name_utf8);
}
{% else %}
JSC::JSValue NamedPropertyGetter(JSC::ExecState* exec_state,
    JSC::JSValue slot_base, JSC::PropertyName property_name) {
  NOTREACHED();
  return JSC::jsUndefined();
}
bool QueryNamedProperty(JSC::JSCell* cell, JSC::ExecState* exec_state,
    JSC::PropertyName property_name) {
  NOTREACHED();
  return false;
}
{% endif %}
{% if named_property_setter %}

void NamedPropertySetter(JSC::JSCell* cell, JSC::ExecState* exec_state,
    JSC::PropertyName property_name, JSC::JSValue jsc_value) {
  TRACE_EVENT0("{{binding_class}}", "NamedPropertySetter");
  {{impl_class}}* impl =
      GetWrappableOrSetException<{{impl_class}}>(exec_state, cell);
  if (!impl) {
    return;
  }

  JSCGlobalObject* global_object =
      JSC::jsCast<JSCGlobalObject*>(exec_state->lexicalGlobalObject());
  JSCExceptionState exception_state(global_object);

  std::string property_name_utf8 = FromWTFString(property_name.publicName());
  {{named_property_setter.type}} value;
  FromJSValue(exec_state, jsc_value,
      {{named_property_setter.conversion_flags}},
      &exception_state, &value);
  if (exception_state.is_exception_set()) {
    JSC::throwError(exec_state, exception_state.exception_object());
    return;
  }
{% call(arguments_list) add_extra_arguments(
    'global_object', ['property_name_utf8', 'value'], named_property_setter) %}
  {{ call_function(
      "impl", impl_class, named_property_setter.name, arguments_list, False) -}};
{% if named_property_setter.raises_exception %}
  if (exception_state.is_exception_set()) {
    JSC::throwError(exec_state, exception_state.exception_object());
  }
{% endif %}
{% endcall %}
}
{% else %}
void NamedPropertySetter(JSC::JSCell* cell, JSC::ExecState* exec_state,
    JSC::PropertyName property_name, JSC::JSValue jsc_value) {
  NOTREACHED();
}
{% endif %}

bool NamedPropertyDeleter(JSC::JSCell* cell, JSC::ExecState* exec_state,
    JSC::PropertyName property_name) {
{% if named_property_deleter %}
    {{impl_class}}* impl =
      GetWrappableOrSetException<{{impl_class}}>(exec_state, cell);
  if (impl) {
    std::string property_name_utf8 = FromWTFString(property_name.publicName());
    impl->{{named_property_deleter.name}}(property_name_utf8);
    return true;
  }
{% endif %}
  return false;
}
{% if stringifier %}

JSC::EncodedJSValue StringifierJS(JSC::ExecState* exec_state) {
  JSC::JSObject* this_object =
      exec_state->hostThisValue().toThisObject(exec_state);
  {{impl_class}}* impl =
      GetWrappableOrSetException<{{impl_class}}>(exec_state, this_object);
  if (!impl) {
    return JSC::JSValue::encode(exec_state->exception());
  }
  JSCGlobalObject* global_object =
      JSC::jsCast<JSCGlobalObject*>(exec_state->lexicalGlobalObject());

  JSC::JSValue result = ToJSValue(global_object, impl->{{stringifier.name}}());
  return JSC::JSValue::encode(result);
}
{% endif %}

#if !defined(COBALT_BUILD_TYPE_GOLD)
JSC::JSValue OnGetMissingProperty(JSC::ExecState* exec_state,
    JSC::JSValue slot_base, JSC::PropertyName property_name) {
  JSCGlobalObject* global_object =
      JSC::jsCast<JSCGlobalObject*>(exec_state->lexicalGlobalObject());
  JSC::JSValue callable = global_object->get(
      exec_state, JSC::Identifier(exec_state, "__onGetMissingProperty"));
  if (!callable.isUndefined()) {
    JSC::CallData call_data;
    JSC::CallType call_type = JSC::getCallData(callable, call_data);
    if (call_type != JSC::CallTypeNone) {
      // The function called __onGetMissingProperty exists, so call this and
      // return the result as the value for this property.
      JSC::MarkedArgumentBuffer args;
      args.append(slot_base);
      args.append(JSC::JSValue(
              JSC::JSString::create(
                  global_object->globalData(), property_name.publicName())));
      JSC::JSValue retval = JSC::call(
          exec_state, callable, call_type, call_data, global_object, args);
      return retval;
    }
  }
  return JSC::jsUndefined();
}

bool OnSetMissingProperty(JSC::JSCell* cell, JSC::ExecState* exec_state,
    JSC::PropertyName property_name, JSC::JSValue value) {
  JSCGlobalObject* global_object =
      JSC::jsCast<JSCGlobalObject*>(exec_state->lexicalGlobalObject());
  JSC::JSValue callable = global_object->get(
      exec_state, JSC::Identifier(exec_state, "__onSetMissingProperty"));
  if (!callable.isUndefined()) {
    JSC::CallData call_data;
    JSC::CallType call_type = JSC::getCallData(callable, call_data);
    if (call_type != JSC::CallTypeNone) {
      // The function called __onSetMissingProperty exists, so call this with
      // the value to be set. The missing property handler returns true if it
      // has handled the setting of this property.
      JSC::MarkedArgumentBuffer args;
      args.append(cell);
      args.append(JSC::JSValue(
              JSC::JSString::create(
                  global_object->globalData(), property_name.publicName())));
      args.append(value);
      JSC::JSValue retval = JSC::call(
          exec_state, callable, call_type, call_data, global_object, args);
      return retval.toBoolean(exec_state);
    }
  }
  return false;
}
#else
JSC::JSValue OnGetMissingProperty(JSC::ExecState* exec_state,
    JSC::JSValue slot_base, JSC::PropertyName property_name) {
  NOTREACHED();
  return JSC::jsUndefined();
}
bool OnSetMissingProperty(JSC::JSCell* cell, JSC::ExecState* exec_state,
    JSC::PropertyName property_name, JSC::JSValue value) {
  NOTREACHED();
  return false;
}
#endif
}  // namespace
{% endblock implementation %}

{% block create_global_object_impl %}
  JSCGlobalEnvironment* jsc_global_environment =
      base::polymorphic_downcast<JSCGlobalEnvironment*>(this);
  JSCEngine* jsc_engine = jsc_global_environment->engine();

  JSCGlobalObject* global_object = {{binding_class}}::Create(
      global_interface, environment_settings,
      jsc_engine->global_data(), jsc_engine->script_object_registry());
  jsc_global_environment->SetGlobalObject(global_object);
{% endblock create_global_object_impl %}

{% block enumeration_definitions %}
{% for enumeration in enumerations %}
JSC::JSValue ToJSValue(JSCGlobalObject* global_object, {{impl_class}}::{{enumeration.name}} in_enum) {
  JSC::JSGlobalData* global_data = &(global_object->globalData());
  switch (in_enum) {
{% for value, idl_value in enumeration.value_pairs %}
    case {{impl_class}}::{{value}}: return JSC::jsString(global_data, "{{idl_value}}");
{% endfor %}
    default:
      NOTREACHED();
      return JSC::jsUndefined();
  }
}
void FromJSValue(JSC::ExecState* exec_state, JSC::JSValue jsvalue,
                 int conversion_flags, JSCExceptionState* 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).
  JSC::JSString* js_string = jsvalue.toString(exec_state);
  if (exec_state->hadException()) {
    DLOG(WARNING) << "Exception converting value to string";
    return;
  }
  const WTF::String& wtf_string = js_string->tryGetValue();
  // 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 (wtf_string == "{{idl_value}}") {
    *out_enum = {{impl_class}}::{{value}};
  }{% endfor %} else {
    // 2. If S is not one of E's enumeration values, then throw a TypeError.
    JSC::throwTypeError(exec_state);
  }
}
{% endfor %}
{% endblock enumeration_definitions %}
