{% from 'callback_invoke.cc.tmpl' import callback_invoke %}
{% filter format_blink_cpp_source_code %}

{% include 'copyright_block.txt' %}

#include "{{this_include_header_path}}"

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

namespace blink {

{% if is_legacy_callback_interface %}
// Support of "legacy callback interface"

// Suppress warning: global constructors, because struct WrapperTypeInfo is
// trivial and does not depend on another global objects.
#if defined(COMPONENT_BUILD) && defined(WIN32) && defined(__clang__)
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wglobal-constructors"
#endif
const WrapperTypeInfo {{v8_class}}::wrapperTypeInfo = {
    gin::kEmbedderBlink,
    {{v8_class}}::DomTemplate,
    nullptr,
    "{{interface_name}}",
    nullptr,
    WrapperTypeInfo::kWrapperTypeNoPrototype,
    WrapperTypeInfo::kObjectClassId,
    WrapperTypeInfo::kNotInheritFromActiveScriptWrappable,
};
#if defined(COMPONENT_BUILD) && defined(WIN32) && defined(__clang__)
#pragma clang diagnostic pop
#endif

{% from 'constants.cpp.tmpl' import install_constants with context %}
static void Install{{v8_class}}Template(v8::Isolate* isolate, const DOMWrapperWorld& world, v8::Local<v8::FunctionTemplate> interface_template) {
  // Legacy callback interface must not have a prototype object.
  interface_template->RemovePrototype();

  // Initialize the interface object's template.
  V8DOMConfiguration::InitializeDOMInterfaceTemplate(
      isolate, interface_template,
      {{v8_class}}::wrapperTypeInfo.interface_name,
      v8::Local<v8::FunctionTemplate>(),
      kV8DefaultWrapperInternalFieldCount);
  interface_template->SetLength(0);

  // Register IDL constants.
  {# |install_constants| requires |interfaceTemplate| and |prototypeTemplate|. #}
  v8::Local<v8::FunctionTemplate> interfaceTemplate = interface_template;
  v8::Local<v8::ObjectTemplate> prototypeTemplate =
      interface_template->PrototypeTemplate();
  {{install_constants() | trim | indent(2)}}
}

// static
v8::Local<v8::FunctionTemplate> {{v8_class}}::DomTemplate(v8::Isolate* isolate, const DOMWrapperWorld& world) {
  return V8DOMConfiguration::DomClassTemplate(
      isolate,
      world,
      const_cast<WrapperTypeInfo*>(&wrapperTypeInfo),
      Install{{v8_class}}Template);
}
{% endif %}{# is_legacy_callback_interface #}

const char* {{v8_class}}::NameInHeapSnapshot() const {
  return "{{v8_class}}";
}

// static
{{v8_class}}* {{v8_class}}::CreateOrNull(v8::Local<v8::Object> callback_object) {
  v8::Local<v8::Context> creation_context = callback_object->CreationContext();
  // When |callback_object| is an object in RemoteContext (i.e. RemoteInstance),
  // the object has no creation context, and no way to proceed.
  // TODO(crbug.com/886588): Make CreateOrNull into Create removing the early
  // return with nullptr.
  if (creation_context.IsEmpty())
    return nullptr;

  return new {{v8_class}}(callback_object, creation_context);
}

{% for method in methods %}

v8::Maybe<{{method.cpp_type}}> {{v8_class}}::{{method.name}}({{method.argument_declarations | join(', ')}}) {
{{callback_invoke(
    'callback interface', None,
    method.cpp_type, method.native_value_traits_tag, method.arguments,
    False,
    interface_name, method.name)}}
}

{% endfor %}

{% if methods|length == 1 and methods[0].idl_type == 'void' %}
void {{v8_class}}::InvokeAndReportException({{methods[0].argument_declarations | join(', ')}}) {
  v8::TryCatch try_catch(GetIsolate());
  try_catch.SetVerbose(true);

  v8::Maybe<void> maybe_result =
      {{methods[0].name}}({{
          (['callback_this_value'] +
           (methods[0].arguments|map(attribute='name')|list)
          )|join(', ')
      }});
  // An exception if any is killed with the v8::TryCatch above.
  ALLOW_UNUSED_LOCAL(maybe_result);
}
{% endif %}

{% for method in methods %}
v8::Maybe<{{method.cpp_type}}> V8PersistentCallbackInterface<{{v8_class}}>::{{method.name}}({{method.argument_declarations | join(', ')}}) {
  return Proxy()->{{method.name}}(
      {{
         (['callback_this_value'] +
          (method.arguments|map(attribute='name')|list)
         )|join(', ')
      }});
}

{% endfor %}

{% if methods|length == 1 and methods[0].idl_type == 'void' %}
void V8PersistentCallbackInterface<{{v8_class}}>::InvokeAndReportException({{methods[0].argument_declarations | join(', ')}}) {
  Proxy()->InvokeAndReportException(
      {{
         (['callback_this_value'] +
          (methods[0].arguments|map(attribute='name')|list)
         )|join(', ')
      }});
}
{% endif %}

}  // namespace blink

{% endfilter %}{# format_blink_cpp_source_code #}
