{% filter format_blink_cpp_source_code %}

{% include 'copyright_block.txt' %}
#ifndef {{header_guard}}
#define {{header_guard}}

{% for filename in header_includes %}
#include "{{filename}}"
{% endfor %}

namespace blink {

{% if optional_features %}
class ScriptState;
{% endif %}
{% if named_constructor %}

extern const WrapperTypeInfo {{snake_case_v8_class}}_constructor_wrapper_type_info;

class {{v8_class}}Constructor {
  STATIC_ONLY({{v8_class}}Constructor);
 public:
  static v8::Local<v8::FunctionTemplate> DomTemplate(v8::Isolate*, const DOMWrapperWorld&);
  static void NamedConstructorAttributeGetter(v8::Local<v8::Name> property_name, const v8::PropertyCallbackInfo<v8::Value>& info);
  static constexpr const WrapperTypeInfo* GetWrapperTypeInfo() {
    return &{{snake_case_v8_class}}_constructor_wrapper_type_info;
  }
};

{% endif %}

{% if has_partial_interface %}
{{exported}}extern WrapperTypeInfo {{snake_case_v8_class}}_wrapper_type_info;
{% else %}
{{exported}}extern const WrapperTypeInfo {{snake_case_v8_class}}_wrapper_type_info;
{% endif %}

class {{v8_class}} {
  STATIC_ONLY({{v8_class}});
 public:
  {% if is_array_buffer_or_view %}
  // Migration adapter
  {{exported}}static bool HasInstance(v8::Isolate*, v8::Local<v8::Value> value) {
    return value->Is{{interface_name}}();
  }

  {{exported}}static {{cpp_class}}* ToImpl(v8::Local<v8::Object> object);
  {% else %}
  {{exported}}static bool HasInstance(v8::Local<v8::Value>, v8::Isolate*);
  static v8::Local<v8::Object> FindInstanceInPrototypeChain(v8::Local<v8::Value>, v8::Isolate*);
  {{exported}}static v8::Local<v8::FunctionTemplate> DomTemplate(v8::Isolate*, const DOMWrapperWorld&);
  {% if has_named_properties_object %}
  {{exported}}static v8::Local<v8::FunctionTemplate> DomTemplateForNamedPropertiesObject(v8::Isolate*, const DOMWrapperWorld&);
  {% endif %}
  static {{cpp_class}}* ToImpl(v8::Local<v8::Object> object) {
    return ToScriptWrappable(object)->ToImpl<{{cpp_class}}>();
  }
  {% endif %}
  {{exported}}static {{cpp_class}}* ToImplWithTypeCheck(v8::Isolate*, v8::Local<v8::Value>);

  {% if has_partial_interface %}
  {{exported}}static constexpr WrapperTypeInfo* GetWrapperTypeInfo() {
  {% else %}
  {{exported}}static constexpr const WrapperTypeInfo* GetWrapperTypeInfo() {
  {% endif %}
    return &{{snake_case_v8_class}}_wrapper_type_info;
  }

  {% for method in methods %}
  {% if method.is_custom %}
  static void {{method.camel_case_name}}MethodCustom(const v8::FunctionCallbackInfo<v8::Value>&);
  {% endif %}
  {% endfor %}
  {% if has_custom_constructor %}
  static void ConstructorCustom(const v8::FunctionCallbackInfo<v8::Value>&);
  {% endif %}
  {% for attribute in attributes %}
  {% if attribute.has_custom_getter %}{# FIXME: and not attribute.implemented_by #}
  {% if attribute.is_data_type_property %}
  static void {{attribute.camel_case_name}}AttributeGetterCustom(const v8::PropertyCallbackInfo<v8::Value>&);
  {% else %}
  static void {{attribute.camel_case_name}}AttributeGetterCustom(const v8::FunctionCallbackInfo<v8::Value>&);
  {% endif %}
  {% endif %}
  {% if attribute.has_custom_setter %}{# FIXME: and not attribute.implemented_by #}
  {% if attribute.is_data_type_property %}
  static void {{attribute.camel_case_name}}AttributeSetterCustom(v8::Local<v8::Value>, const v8::PropertyCallbackInfo<void>&);
  {% else %}
  static void {{attribute.camel_case_name}}AttributeSetterCustom(v8::Local<v8::Value>, const v8::FunctionCallbackInfo<v8::Value>&);
  {% endif %}
  {% endif %}
  {% endfor %}
  {# Custom special operations #}
  {% if indexed_property_getter and indexed_property_getter.is_custom %}
  static void IndexedPropertyGetterCustom(uint32_t, const v8::PropertyCallbackInfo<v8::Value>&);
  {% endif %}
  {% if indexed_property_setter and indexed_property_setter.is_custom %}
  static void IndexedPropertySetterCustom(uint32_t, v8::Local<v8::Value>, const v8::PropertyCallbackInfo<v8::Value>&);
  {% endif %}
  {% if indexed_property_deleter and indexed_property_deleter.is_custom %}
  static void IndexedPropertyDeleterCustom(uint32_t, const v8::PropertyCallbackInfo<v8::Boolean>&);
  {% endif %}
  {% if named_property_getter and named_property_getter.is_custom %}
  static void NamedPropertyGetterCustom(const AtomicString&, const v8::PropertyCallbackInfo<v8::Value>&);
  {% endif %}
  {% if named_property_setter and named_property_setter.is_custom %}
  static void NamedPropertySetterCustom(const AtomicString&, v8::Local<v8::Value>, const v8::PropertyCallbackInfo<v8::Value>&);
  {% endif %}
  {% if named_property_getter and named_property_getter.is_custom_property_query %}
  static void NamedPropertyQueryCustom(const AtomicString&, const v8::PropertyCallbackInfo<v8::Integer>&);
  {% endif %}
  {% if named_property_deleter and named_property_deleter.is_custom %}
  static void NamedPropertyDeleterCustom(const AtomicString&, const v8::PropertyCallbackInfo<v8::Boolean>&);
  {% endif %}
  {% if named_property_getter and named_property_getter.is_custom_property_enumerator %}
  static void NamedPropertyEnumeratorCustom(const v8::PropertyCallbackInfo<v8::Array>&);
  {% endif %}
  {# END custom special operations #}
  {% if has_custom_legacy_call_as_function %}
  static void LegacyCallCustom(const v8::FunctionCallbackInfo<v8::Value>&);
  {% endif %}
  {# Custom internal fields #}
  {# persistentHandleIndex must be the last field, if it is present.
     Detailed explanation: https://codereview.chromium.org/139173012
     FIXME: Remove this internal field, and share one field for either:
     * a persistent handle (if the object is in oilpan) or
     * a C++ pointer to the DOM object (if the object is not in oilpan) #}
  static constexpr int kInternalFieldCount = kV8DefaultWrapperInternalFieldCount;
  {# End custom internal fields #}

  {% if install_conditional_features_func %}
  {{exported}}static void InstallConditionalFeatures(
      v8::Local<v8::Context>,
      const DOMWrapperWorld&,
      v8::Local<v8::Object> instance_object,
      v8::Local<v8::Object> prototype_object,
      v8::Local<v8::Function> interface_object,
      v8::Local<v8::FunctionTemplate> interface_template);
  {% elif has_partial_interface %}
  {{exported}}static void InstallConditionalFeatures(
      v8::Local<v8::Context>,
      const DOMWrapperWorld&,
      v8::Local<v8::Object> instance_object,
      v8::Local<v8::Object> prototype_object,
      v8::Local<v8::Function> interface_object,
      v8::Local<v8::FunctionTemplate> interface_template) {}
  {% endif %}

  {% if has_partial_interface %}
  {{exported}}static void UpdateWrapperTypeInfo(
      InstallTemplateFunction,
      InstallRuntimeEnabledFeaturesFunction,
      InstallRuntimeEnabledFeaturesOnTemplateFunction,
      InstallConditionalFeaturesFunction);
  {{exported}}static void Install{{v8_class}}Template(v8::Isolate*, const DOMWrapperWorld&, v8::Local<v8::FunctionTemplate> interface_template);
  {% for method in methods if method.overloads and method.overloads.has_partial_overloads %}
  {{exported}}static void Register{{method.camel_case_name}}MethodForPartialInterface(void (*)(const v8::FunctionCallbackInfo<v8::Value>&));
  {% endfor %}
  {% endif %}

  {% for feature in optional_features %}

  static void Install{{feature.name}}(v8::Isolate*, const DOMWrapperWorld&, v8::Local<v8::Object> instance, v8::Local<v8::Object> prototype, v8::Local<v8::Function> interface);
  static void Install{{feature.name}}(ScriptState*, v8::Local<v8::Object> instance);
  {% if not feature.needs_instance %}
  static void Install{{feature.name}}(ScriptState*);
  {% endif %}
  {% endfor %}

  // Callback functions
  {% for constant in constants | has_special_getter %}
  {{exported}}static void {{constant.camel_case_name}}ConstantGetterCallback(v8::Local<v8::Name>, const v8::PropertyCallbackInfo<v8::Value>&);
  {% endfor %}

  {% for attribute in attributes %}
  {% if attribute.is_cached_accessor %}
  {{exported}}static v8::Local<v8::Private> {{attribute.camel_case_name}}CachedPropertyKey(v8::Isolate*);
  {% endif %}
  {% for world_suffix in attribute.world_suffixes %}
  {% if not attribute.constructor_type %}
  {{exported}}static void {{attribute.camel_case_name}}AttributeGetterCallback{{world_suffix}}(
    {%- if attribute.is_data_type_property -%}
    v8::Local<v8::Name>, const v8::PropertyCallbackInfo<v8::Value>&
    {%- else -%}
    const v8::FunctionCallbackInfo<v8::Value>&
    {%- endif -%});
  {% else %}
  {{exported}}static void {{attribute.camel_case_name}}ConstructorGetterCallback{{world_suffix}}(v8::Local<v8::Name>, const v8::PropertyCallbackInfo<v8::Value>&);
  {% endif %}
  {% if attribute.has_setter %}
  {{exported}}static void {{attribute.camel_case_name}}AttributeSetterCallback{{world_suffix}}(
    {%- if attribute.is_data_type_property -%}
    v8::Local<v8::Name>, v8::Local<v8::Value>, const v8::PropertyCallbackInfo<void>&
    {%- else -%}
    const v8::FunctionCallbackInfo<v8::Value>&
    {%- endif -%});
  {% endif %}
  {% endfor %}
  {% endfor %}

  {% for method in methods %}
  {% for world_suffix in method.world_suffixes %}
  {% if not method.overload_index or method.overloads %}
  {# Document about the following condition: #}
  {# https://docs.google.com/document/d/1qBC7Therp437Jbt_QYAtNYMZs6zQ_7_tnMkNUG_ACqs/edit?usp=sharing #}
  {% if (method.overloads and method.overloads.visible and
         (not method.overloads.has_partial_overloads or not is_partial)) or
        (not method.overloads and method.visible) %}
  {# A single callback is generated for overloaded methods #}
  {# with considering partial overloads #}
  {{exported}}static void {{method.camel_case_name}}MethodCallback{{world_suffix}}(const v8::FunctionCallbackInfo<v8::Value>&);
  {% endif %}
  {% if method.is_cross_origin and method.visible %}
  {{exported}}static void {{method.camel_case_name}}OriginSafeMethodGetterCallback{{world_suffix}}(v8::Local<v8::Name>, const v8::PropertyCallbackInfo<v8::Value>&);
  {% endif %}
  {% endif %}
  {% endfor %}
  {% endfor %}
  {% if iterator_method %}
  {{exported}}static void {{iterator_method.camel_case_name}}MethodCallback(const v8::FunctionCallbackInfo<v8::Value>&);
  {% endif %}

  {% if has_access_check_callbacks and not is_partial %}
  {{exported}}static bool SecurityCheck(v8::Local<v8::Context>, v8::Local<v8::Object>, v8::Local<v8::Value>);
  {% if has_cross_origin_named_getter %}
  {{exported}}static void CrossOriginNamedGetter(v8::Local<v8::Name>, const v8::PropertyCallbackInfo<v8::Value>&);
  {% endif %}
  {% if has_cross_origin_named_setter %}
  {{exported}}static void CrossOriginNamedSetter(v8::Local<v8::Name>, v8::Local<v8::Value>, const v8::PropertyCallbackInfo<v8::Value>&);
  {% endif %}
  {% if has_cross_origin_named_enumerator %}
  {{exported}}static void CrossOriginNamedEnumerator(const v8::PropertyCallbackInfo<v8::Array>&);
  {% endif %}
  {% if has_cross_origin_indexed_getter %}
  {{exported}}static void CrossOriginIndexedGetter(uint32_t index, const v8::PropertyCallbackInfo<v8::Value>&);
  {% endif %}
  {% endif %}

  {% if named_property_getter %}
  {{exported}}static void NamedPropertyGetterCallback(v8::Local<v8::Name>, const v8::PropertyCallbackInfo<v8::Value>&);
  {% endif %}
  {% if named_property_setter %}
  {{exported}}static void NamedPropertySetterCallback(v8::Local<v8::Name>, v8::Local<v8::Value>, const v8::PropertyCallbackInfo<v8::Value>&);
  {% endif %}
  {% if named_property_deleter %}
  {{exported}}static void NamedPropertyDeleterCallback(v8::Local<v8::Name>, const v8::PropertyCallbackInfo<v8::Boolean>&);
  {% endif %}
  {% if named_property_getter and named_property_getter.is_enumerable %}
  {{exported}}static void NamedPropertyQueryCallback(v8::Local<v8::Name>, const v8::PropertyCallbackInfo<v8::Integer>&);
  {% endif %}
  {% if named_property_getter and named_property_getter.is_enumerable %}
  {{exported}}static void NamedPropertyEnumeratorCallback(const v8::PropertyCallbackInfo<v8::Array>&);
  {% endif %}
  {% if indexed_property_getter or named_property_getter %}
  {{exported}}static void IndexedPropertyGetterCallback(uint32_t index, const v8::PropertyCallbackInfo<v8::Value>&);
  {% endif %}
  {% if indexed_property_getter or named_property_setter %}
  {{exported}}static void IndexedPropertySetterCallback(uint32_t index, v8::Local<v8::Value>, const v8::PropertyCallbackInfo<v8::Value>&);
  {% endif %}
  {% if indexed_property_getter or named_property_getter %}
  {{exported}}static void IndexedPropertyDescriptorCallback(uint32_t index, const v8::PropertyCallbackInfo<v8::Value>&);
  {% endif %}
  {% if indexed_property_deleter or named_property_deleter %}
  {{exported}}static void IndexedPropertyDeleterCallback(uint32_t index, const v8::PropertyCallbackInfo<v8::Boolean>&);
  {% endif %}
  {% if indexed_property_getter %}
  {{exported}}static void IndexedPropertyDefinerCallback(uint32_t index, const v8::PropertyDescriptor&, const v8::PropertyCallbackInfo<v8::Value>&);
  {% endif %}

  {% if needs_runtime_enabled_installer %}
  {{exported if has_partial_interface else ''}}static void InstallRuntimeEnabledFeatures(
      v8::Isolate*,
      const DOMWrapperWorld& world,
      v8::Local<v8::Object> instance,
      v8::Local<v8::Object> prototype,
      v8::Local<v8::Function> interface);
  {% endif %}{# needs_runtime_enabled_installer #}

  {% if not is_array_buffer_or_view %}
  {{exported if has_partial_interface else ''}}static void InstallRuntimeEnabledFeaturesOnTemplate(
      v8::Isolate*,
      const DOMWrapperWorld&,
      v8::Local<v8::FunctionTemplate> interface_template);
  {% if has_partial_interface %}
  static InstallRuntimeEnabledFeaturesOnTemplateFunction
  install_runtime_enabled_features_on_template_function_;
  {% endif %}
  {% endif %}{# not is_array_buffer_or_view #}

  {% if needs_runtime_enabled_installer or has_partial_interface %}
 private:
  {% if needs_runtime_enabled_installer %}
  static void InstallRuntimeEnabledFeaturesImpl(
      v8::Isolate*,
      const DOMWrapperWorld& world,
      v8::Local<v8::Object> instance,
      v8::Local<v8::Object> prototype,
      v8::Local<v8::Function> interface);
  {% endif %}{# needs_runtime_enabled_installer #}
  {% if has_partial_interface %}
  static InstallTemplateFunction install_{{snake_case_v8_class}}_template_function_;
  {% if needs_runtime_enabled_installer %}
  static InstallRuntimeEnabledFeaturesFunction
  install_runtime_enabled_features_function_;
  {% endif %}
  {% endif %}{# has_partial_interface #}
  {% endif %}
};

template <>
struct V8TypeOf<{{cpp_class}}> {
  typedef {{v8_class}} Type;
};

}  // namespace blink

#endif  // {{header_guard}}

{% endfilter %}{# format_blink_cpp_source_code #}
