{% 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.cc.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 MakeGarbageCollected<{{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, 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 %}

{% if interface_name == 'EventListener' %}
bool {{v8_class}}::IsRunnableOrThrowException(IgnorePause ignore_pause) {
  ScriptState* callback_relevant_script_state =
      CallbackRelevantScriptState();

  bool is_runnable =
      ignore_pause == IgnorePause::kIgnore ?
      IsCallbackFunctionRunnableIgnoringPause(
          callback_relevant_script_state, IncumbentScriptState()) :
      IsCallbackFunctionRunnable(
          callback_relevant_script_state, IncumbentScriptState());
  if (is_runnable)
    return true;

  // Wrapper-tracing for the callback function makes the function object and
  // its creation context alive. Thus it's safe to use the creation context
  // of the callback function here.
  ScriptState::Scope scope(callback_relevant_script_state);
  V8ThrowException::ThrowError(
      GetIsolate(),
      ExceptionMessages::FailedToExecute(
          "{{methods[0].name}}",
          "{{interface_name}}",
          "The provided callback is no longer runnable."));
  return false;
}

v8::Maybe<{{methods[0].cpp_type}}> {{v8_class}}::InvokeWithoutRunnabilityCheck({{methods[0].argument_declarations | join(', ')}}) {
{{callback_invoke(
    'callback interface', None,
    methods[0].cpp_type, methods[0].native_value_traits_tag, methods[0].arguments,
    False, True,
    interface_name, methods[0].name)}}
}
{% 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 #}
