{% 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 {{snake_case_v8_class}}_wrapper_type_info = {
    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}}::GetWrapperTypeInfo()->interface_name,
      v8::Local<v8::FunctionTemplate>(),
      kV8DefaultWrapperInternalFieldCount);
  interface_template->SetLength(0);

  // Register IDL constants.
  {# |install_constants| requires |interface_template| and |prototype_template|. #}
  v8::Local<v8::ObjectTemplate> prototype_template =
      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*>(GetWrapperTypeInfo()),
      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 #}
