{% from 'utilities.cc.tmpl' import declare_enum_validation_variable, v8_value_to_local_cpp_value %}

{##############################################################################}
{% macro runtime_timer_scope(counter) %}
RUNTIME_CALL_TIMER_SCOPE(info.GetIsolate(), RuntimeCallStats::CounterId::{{counter}});
{% endmacro %}

{% macro runtime_timer_scope_disabled_by_default(counter) %}
RUNTIME_CALL_TIMER_SCOPE_DISABLED_BY_DEFAULT(info.GetIsolate(), "{{counter}}");
{% endmacro %}

{% macro trace_event(name) %}
BLINK_BINDINGS_TRACE_EVENT("{{name}}");
{% endmacro %}

{% macro generate_method(method, world_suffix) %}
static void {{method.camel_case_name}}{{method.overload_index}}Method{{world_suffix}}(const v8::FunctionCallbackInfo<v8::Value>& info) {
  {% filter format_remove_duplicates([
      'ExceptionState exception_state',
      'ScriptState* script_state = ']) %}
  {% set define_exception_state -%}
  ExceptionState exception_state(info.GetIsolate(), ExceptionState::kExecutionContext, "{{interface_name}}", "{{method.name}}");
  {%- endset %}

  {% set function_call = func_call_with_prep_of_args(method, world_suffix) %}

  {% if 'exception_state' in function_call or
        (method.returns_promise and not method.is_static) %}
  {{define_exception_state}}
  {% if method.returns_promise %}
  ExceptionToRejectPromiseScope reject_promise_scope(info, exception_state);
  {% endif %}
  {% endif %}
  {% if method.is_ce_reactions %}
  CEReactionsScope ce_reactions_scope;
  {% endif %}

  {% if not method.is_static %}
  {% if method.returns_promise %}
  // V8DOMConfiguration::kDoNotCheckHolder
  // Make sure that info.Holder() really points to an instance of the type.
  if (!{{v8_class}}::HasInstance(info.Holder(), info.GetIsolate())) {
    {{throw_type_error(method, '"Illegal invocation"')}}
    return;
  }
  {% endif %}
  {% if interface_name == 'Window' and not method.is_cross_origin %}
  // Same-origin methods are never exposed via the cross-origin interceptors.
  // Since same-origin access requires a LocalDOMWindow, it is safe to downcast
  // here.
  LocalDOMWindow* impl = To<LocalDOMWindow>({{v8_class}}::ToImpl(info.Holder()));
  {% else %}
  {{cpp_class}}* impl = {{v8_class}}::ToImpl(info.Holder());
  {% endif %}{# interface_name == 'Window' and not method.is_cross_origin #}
  {% endif %}{# not method.is_static #}

  {% if interface_name == "Window" and method.is_cross_origin %}
  impl->ReportCoopAccess("{{method.name}}");
  {% endif %}

  {# Security checks #}
  {% if method.is_check_security_for_return_value %}
  {{define_exception_state}}
  if (!BindingSecurity::ShouldAllowAccessTo(
          CurrentDOMWindow(info.GetIsolate()), {{method.cpp_value}},
          BindingSecurity::ErrorReportOption::kDoNotReport)) {
    UseCounter::Count(CurrentExecutionContext(info.GetIsolate()),
                      WebFeature::kCrossOrigin{{interface_name}}{{method.camel_case_name}});
    V8SetReturnValueNull(info);
    return;
  }
  {% endif %}

  {% if 'script_state' in function_call %}
  {% if method.is_static %}
  ScriptState* script_state = ScriptState::ForCurrentRealm(info);
  {% else %}
  ScriptState* script_state = ScriptState::ForRelevantRealm(info);
  {% endif %}
  {% endif %}

  {{function_call | trim | indent(2)}}
}
{% endfilter %}
{% endmacro %}


{######################################}
{% macro func_call_with_prep_of_args(method, world_suffix) %}
{{generate_arguments(method, world_suffix)}}
{% if world_suffix %}
{{cpp_method_call(method, method.v8_set_return_value_for_main_world, method.cpp_value)}}
{% else %}
{{cpp_method_call(method, method.v8_set_return_value, method.cpp_value)}}
{% endif %}
{% endmacro %}


{######################################}
{% macro generate_arguments(method, world_suffix) %}
{% if method.arguments %}

{# Overloaded methods/constructors have length checked during overload resolution #}
{% if method.number_of_required_arguments and not method.overload_index %}
if (UNLIKELY(info.Length() < {{method.number_of_required_arguments}})) {
  {{throw_type_error(method,
        'ExceptionMessages::NotEnoughArguments(%(expected)d, info.Length())'
        | format(expected=method.number_of_required_arguments))}}
  return;
}
{% endif %}

{% for argument in method.arguments %}
{{argument.cpp_type}} {{argument.local_cpp_variable}};
{% endfor %}
{% if method.has_optional_argument_without_default_value %}
{# Count the effective number of arguments.  (arg1, arg2, undefined) is
   interpreted as two arguments are passed and (arg1, undefined, arg3) is
   interpreted as three arguments are passed. #}
int num_args_passed = info.Length();
while (num_args_passed > 0) {
  if (!info[num_args_passed - 1]->IsUndefined())
    break;
  --num_args_passed;
}
{% endif %}
{% for argument in method.arguments %}
{% if argument.set_default_value %}
if (!info[{{argument.index}}]->IsUndefined()) {
  {{generate_argument(method, argument, world_suffix) | trim | indent(2)}}
} else {
  {{argument.set_default_value | trim | indent(2)}};
}
{% else %}
{{generate_argument(method, argument, world_suffix)}}
{% endif %}
{% endfor %}

{% endif %}{# method.arguments #}
{% endmacro %}


{######################################}
{% macro generate_argument(method, argument, world_suffix) %}
{% if argument.is_optional_without_default_value %}
{# Optional arguments without a default value generate an early call with
   fewer arguments if they are omitted.
   Optional Dictionary arguments default to empty dictionary. #}
if (UNLIKELY(num_args_passed <= {{argument.index}})) {
  {% if world_suffix %}
  {{cpp_method_call(method, argument.v8_set_return_value_for_main_world, argument.cpp_value) | trim | indent(2)}}
  {% else %}
  {{cpp_method_call(method, argument.v8_set_return_value, argument.cpp_value) | trim | indent(2)}}
  {% endif %}
  return;
}
{% endif %}
{% if argument.is_callback_interface %}
if (info[{{argument.index}}]->IsObject()) {
  {{argument.local_cpp_variable}} = V8{{argument.idl_type}}::Create(info[{{argument.index}}].As<v8::Object>());
{% if argument.is_nullable %}
} else if (info[{{argument.index}}]->IsNullOrUndefined()) {
  {{argument.local_cpp_variable}} = nullptr;
{% elif argument.is_optional %}
} else if (info[{{argument.index}}]->IsUndefined()) {
  {{argument.local_cpp_variable}} = nullptr;
{% endif %}
} else {
  {{throw_argument_error(method, argument, "The callback provided as parameter %(index)d is not an object.")}}
  return;
}
{% elif argument.is_callback_function %}
if (info[{{argument.index}}]->IsFunction()) {
  {{v8_value_to_local_cpp_value(argument)}}
{% if argument.is_nullable %}
} else if (info[{{argument.index}}]->IsNullOrUndefined()) {
  {{argument.local_cpp_variable}} = nullptr;
{% elif argument.is_optional %}
} else if (info[{{argument.index}}]->IsUndefined()) {
  {{argument.local_cpp_variable}} = nullptr;
{% endif %}
} else {
  {{throw_argument_error(method, argument, "The callback provided as parameter %(index)d is not a function.")}}
  return;
}
{% elif argument.is_variadic_wrapper_type %}
for (int i = {{argument.index}}; i < info.Length(); ++i) {
  if (!V8{{argument.idl_type}}::HasInstance(info[i], info.GetIsolate())) {
    {{throw_type_error(method, "ExceptionMessages::ArgumentNotOfType(%(index)d, \"%(type)s\")" | format(index=argument.index, type=argument.idl_type))}}
    return;
  }
  {{argument.local_cpp_variable}}.push_back(V8{{argument.idl_type}}::ToImpl(v8::Local<v8::Object>::Cast(info[i])));
}
{% elif argument.is_dictionary %}
{% if not argument.use_permissive_dictionary_conversion %}
{# Dictionaries must have type Undefined, Null or Object:
   http://heycam.github.io/webidl/#es-dictionary #}
if (!info[{{argument.index}}]->IsNullOrUndefined() && !info[{{argument.index}}]->IsObject()) {
  {{throw_argument_error(method, argument, "parameter %(index)d ('%(name)s') is not an object.")}}
  return;
}
{% endif %}{# not argument.use_permissive_dictionary_conversion #}
{{v8_value_to_local_cpp_value(argument)}}
{% elif argument.is_explicit_nullable %}
if (!info[{{argument.index}}]->IsNullOrUndefined()) {
  {{v8_value_to_local_cpp_value(argument) | trim | indent(2)}}
}
{% else %}{# argument is something else #}
{{v8_value_to_local_cpp_value(argument)}}
{% endif %}{# end of the dispatch by the argument type #}
{# Type checking, possibly throw a TypeError, per:
   http://www.w3.org/TR/WebIDL/#es-type-mapping #}
{% if argument.has_type_checking_interface and not argument.is_variadic_wrapper_type %}
{# Type checking for wrapper interface types (if interface not implemented,
   throw a TypeError), per http://www.w3.org/TR/WebIDL/#es-interface
   Note: for variadic arguments, the type checking is done for each matched
   argument instead; see argument.is_variadic_wrapper_type code-path above. #}
if (!{{argument.local_cpp_variable}}{% if argument.is_nullable %} && !IsUndefinedOrNull(info[{{argument.index}}]){% endif %}) {
  {{throw_type_error(method, "ExceptionMessages::ArgumentNotOfType(%(index)d, \"%(type)s\")" | format(index=argument.index, type=argument.idl_type))}}
  return;
}
{% elif argument.enum_values %}
{# Invalid enum values: http://www.w3.org/TR/WebIDL/#idl-enums #}
{% set enum_variable = 'kValid' + argument.name[0].upper() + argument.name[1:] + 'Values' %}
{{declare_enum_validation_variable(argument.enum_values, enum_variable)}}
if (!IsValidEnum({{argument.local_cpp_variable}}, {{enum_variable}}, base::size({{enum_variable}}), "{{argument.enum_type}}", exception_state)) {
  return;
}
{% elif argument.idl_type == 'Promise' %}
{# We require this for our implementation of promises, though not in spec:
http://heycam.github.io/webidl/#es-promise #}
if (!{{argument.local_cpp_variable}}.IsUndefinedOrNull() && !{{argument.local_cpp_variable}}.IsObject()) {
  {{throw_argument_error(method, argument, "parameter %(index)d ('%(name)s') is not an object.")}}
  return;
}
{% endif %}
{% endmacro %}


{######################################}
{% macro cpp_method_call(method, v8_set_return_value, cpp_value) %}
{# Local variables #}
{% if method.is_call_with_execution_context or method.high_entropy == 'Direct' %}
{# [ConstructorCallWith=ExecutionContext] or [CallWith=ExecutionContext] #}
{% if method.is_constructor %}
ExecutionContext* execution_context = ToExecutionContext(
    info.NewTarget().As<v8::Object>()->CreationContext());
{% elif method.is_static %}
ExecutionContext* execution_context = ExecutionContext::ForCurrentRealm(info);
{% else %}
ExecutionContext* execution_context = ExecutionContext::ForRelevantRealm(info);
{% endif %}
{% endif %}
{% if method.is_call_with_document %}
{# [ConstructorCallWith=Document] #}
Document& document = *ToLocalDOMWindow(
    info.NewTarget().As<v8::Object>()->CreationContext())->document();
{% endif %}
{# Call #}
{% if method.idl_type == 'void' %}
{{cpp_value}};
{% elif method.use_output_parameter_for_result %}
{{method.cpp_type}} result;
{{cpp_value}};
{% elif method.is_constructor %}
{{method.cpp_type}} impl = {{cpp_value}};
{% elif method.use_local_result %}
{{method.cpp_type}} result = {{cpp_value}};
{% if method.high_entropy == 'Direct' %}
Dactyloscoper::RecordDirectSurface(execution_context, WebFeature::k{{method.measure_as('Method')}}, result);
{% endif %}
{% endif %}
{# Post-call #}
{% if method.is_raises_exception %}
if (exception_state.HadException()) {
  return;
}
{% endif %}
{# Set return value #}
{% if method.is_new_object and not method.do_not_test_new_object %}
{% if not method.returns_promise %}
{# We currently only add the DCHECK for IDL interfaces. Even though #}
{# [NewObject] also applies to promises, there is nothing for us to check at #}
{# the moment. #}
// [NewObject] must always create a new wrapper.  Check that a wrapper
// does not exist yet.
DCHECK(!result || DOMDataStore::GetWrapper(result, info.GetIsolate()).IsEmpty());
{% endif %}{# not method.returns_promise #}
{% endif %}
{% if method.is_constructor %}
{{generate_constructor_wrapper(method)}}
{%- elif v8_set_return_value %}
{% if method.is_explicit_nullable %}
if (!result)
  V8SetReturnValueNull(info);
else
  {{v8_set_return_value}};
{% else %}
{{v8_set_return_value}};
{% endif %}
{%- endif %}{# None for void #}
{% endmacro %}


{##############################################################################}
{% macro throw_type_error(method, error_message) %}
{% if method.has_exception_state or method.returns_promise %}
exception_state.ThrowTypeError({{error_message}});
{%- elif method.is_constructor %}
V8ThrowException::ThrowTypeError(info.GetIsolate(), ExceptionMessages::FailedToConstruct("{{interface_name}}", {{error_message}}));
{%- else %}
V8ThrowException::ThrowTypeError(info.GetIsolate(), ExceptionMessages::FailedToExecute("{{method.name}}", "{{interface_name}}", {{error_message}}));
{%- endif %}
{%- endmacro %}


{##############################################################################}
{% macro throw_argument_error(method, argument, error_message) %}
{% set quoted_message = '"%s"' % (error_message | replace('\"', '\\\"')) %}
{{throw_type_error(method, quoted_message | format(index=(argument.index + 1), name=argument.name, type=argument.idl_type))}}
{%- endmacro %}


{##############################################################################}
{% macro runtime_determined_length_method(overloads) %}
static int {{overloads.camel_case_name}}MethodLength() {
  {% for length, runtime_enabled_features in overloads.runtime_determined_lengths %}
  {% for runtime_enabled_feature in runtime_enabled_features %}
  {% filter runtime_enabled(runtime_enabled_feature) %}
  return {{length}};
  {% endfilter %}
  {% endfor %}
  {% endfor %}
}
{% endmacro %}


{##############################################################################}
{% macro runtime_determined_maxarg_method(overloads) %}
static int {{overloads.camel_case_name}}MethodMaxArg() {
  {% for length, runtime_enabled_features in overloads.runtime_determined_maxargs %}
  {% for name in runtime_enabled_features %}
  {% filter runtime_enabled(name) %}
  return {{length}};
  {% endfilter %}
  {% endfor %}
  {% endfor %}
}
{% endmacro %}


{##############################################################################}
{% macro overload_resolution_method(overloads, world_suffix) %}
static void {{overloads.camel_case_name}}Method{{world_suffix}}(const v8::FunctionCallbackInfo<v8::Value>& info) {
  scheduler::CooperativeSchedulingManager::Instance()->Safepoint();

  {% set fall_through_to_partial_overloads = not is_partial and overloads.has_partial_overloads %}

  {% if overloads.measure_all_as %}
  UseCounter::Count(CurrentExecutionContext(info.GetIsolate()), WebFeature::k{{overloads.measure_all_as}});
  {% endif %}
  {% if overloads.deprecate_all_as %}
  Deprecation::CountDeprecation(CurrentExecutionContext(info.GetIsolate()), WebFeature::k{{overloads.deprecate_all_as}});
  {% endif %}

  {# First resolve by length #}
  {% if not fall_through_to_partial_overloads %}
  bool is_arity_error = false;
  {% endif %}

  {# This follows the overload resolution algorithm. #}
  {# https://heycam.github.io/webidl/#dfn-overload-resolution-algorithm #}
  {# 3. Initialize argcount to be min(maxarg, n). #}
  switch (std::min({{overloads.maxarg}}, info.Length())) {
    {# 4. Remove from S all entries whose type list is not of length argcount. #}
    {% for length, tests_methods in overloads.length_tests_methods %}
    {# 12. If i = d, then: #}
    case {{length}}:
      {# Then resolve by testing argument #}
      {% for test, method in tests_methods %}
      {% if method.visible %}
      {% filter runtime_enabled(not overloads.runtime_enabled_all and method.runtime_enabled_feature_name) %}
      {% if "exception_state" in test %}
      {
        ExceptionState exception_state(info.GetIsolate(), ExceptionState::kExecutionContext,
                                      "{{interface_name}}", "{{overloads.name}}");
        {{ test_and_call_overloaded_method(test, method, overloads, world_suffix) | trim | indent(8) }}
        if (exception_state.HadException()) {
          exception_state.RethrowV8Exception(exception_state.GetException());
          return;
        }
      }
      {% else %}{# exception_state #}
      {{ test_and_call_overloaded_method(test, method, overloads, world_suffix) | trim | indent(6) }}
      {% endif %}{# exception_state #}
      {% endfilter %}
      {% endif %}
      {% endfor %}
      break;
    {% endfor %}{# length, tests_methods #}
    {% if not fall_through_to_partial_overloads %}
    default:
      {# 12.19. Otherwise: throw a TypeError. #}
      is_arity_error = true;
    {% endif %}
  }

  {% if fall_through_to_partial_overloads %}
  DCHECK({{overloads.name}}MethodForPartialInterface);
  ({{overloads.name}}MethodForPartialInterface)(info);
  {% else %}{# fall_through_to_partial_overloads #}
  ExceptionState exception_state(info.GetIsolate(), ExceptionState::kExecutionContext, "{{interface_name}}", "{{overloads.name}}");
  {% if overloads.returns_promise_all %}
  ExceptionToRejectPromiseScope reject_promise_scope(info, exception_state);
  {% endif %}
  if (is_arity_error) {
    {% if overloads.length != 0 %}
    if (info.Length() < {{overloads.length}}) {
      exception_state.ThrowTypeError(ExceptionMessages::NotEnoughArguments({{overloads.length}}, info.Length()));
      return;
    }
    {% endif %}
    {% if overloads.valid_arities %}
    if (info.Length() >= {{overloads.length}}) {
      exception_state.ThrowTypeError(ExceptionMessages::InvalidArity("{{overloads.valid_arities}}", info.Length()));
      return;
    }
    {% endif %}
  }
  exception_state.ThrowTypeError("No function was found that matched the signature provided.");
  {% endif %}{# fall_through_to_partial_overloads #}
}
{% endmacro %}

{% macro test_and_call_overloaded_method(test, method, overloads, world_suffix) %}
if ({{test}}) {
  {% if method.measure_as and not overloads.measure_all_as %}
  ExecutionContext* execution_context_for_measurement = CurrentExecutionContext(info.GetIsolate());
  UseCounter::Count(execution_context_for_measurement, WebFeature::k{{method.measure_as('Method')}});
  {% if method.high_entropy %}
  Dactyloscoper::Record(execution_context_for_measurement, WebFeature::k{{method.measure_as('Method')}});
  {% endif %}
  {% endif %}
  {% if method.deprecate_as and not overloads.deprecate_all_as %}
  Deprecation::CountDeprecation(CurrentExecutionContext(info.GetIsolate()), WebFeature::k{{method.deprecate_as}});
  {% endif %}
  {{method.camel_case_name}}{{method.overload_index}}Method{{world_suffix}}(info);
  return;
}
{% endmacro %}



{##############################################################################}
{% macro method_callback(method, world_suffix) %}
void {{v8_class_or_partial}}::{{method.camel_case_name}}MethodCallback{{world_suffix}}(const v8::FunctionCallbackInfo<v8::Value>& info) {
  {{ trace_event(method.runtime_call_stats.trace_event_name) | trim | indent(2) }}
  {% if method.runtime_call_stats.extended_attribute_defined %}
  {{ runtime_timer_scope(method.runtime_call_stats.method_counter) | trim | indent(2) }}
  {% else %}
  {{ runtime_timer_scope_disabled_by_default(method.runtime_call_stats.method_counter) }}
  {% endif %}
  {% if not method.overloads %}{# Overloaded methods are measured in overload_resolution_method() #}
  {% if method.measure_as %}
  ExecutionContext* execution_context_for_measurement = CurrentExecutionContext(info.GetIsolate());
  UseCounter::Count(execution_context_for_measurement, WebFeature::k{{method.measure_as('Method')}});
  {% if method.high_entropy %}
  Dactyloscoper::Record(execution_context_for_measurement, WebFeature::k{{method.measure_as('Method')}});
  {% endif %}
  {% endif %}
  {% if method.deprecate_as %}
  Deprecation::CountDeprecation(CurrentExecutionContext(info.GetIsolate()), WebFeature::k{{method.deprecate_as}});
  {% endif %}
  {% endif %}{# not method.overloads #}
  {% if world_suffix in method.activity_logging_world_list %}
  {% if method.is_static %}
  ScriptState* script_state = ScriptState::ForCurrentRealm(info);
  {% else %}
  ScriptState* script_state = ScriptState::ForRelevantRealm(info);
  {% endif %}
  V8PerContextData* context_data = script_state->PerContextData();
  if (context_data && context_data->ActivityLogger()) {
    context_data->ActivityLogger()->LogMethod("{{interface_name}}.{{method.name}}", info);
  }
  {% endif %}
  {% if method.is_custom %}
  {{v8_class}}::{{method.camel_case_name}}MethodCustom(info);
  {% else %}
  {{internal_namespace}}::{{method.camel_case_name}}Method{{world_suffix}}(info);
  {% endif %}
}
{% endmacro %}


{##############################################################################}
{% macro origin_safe_method_getter(method, world_suffix) %}
static void {{method.camel_case_name}}OriginSafeMethodGetter{{world_suffix}}(const v8::PropertyCallbackInfo<v8::Value>& info) {
  v8::Isolate* isolate = info.GetIsolate();
  V8PerIsolateData* data = V8PerIsolateData::From(isolate);
  const DOMWrapperWorld& world =
      DOMWrapperWorld::World(isolate->GetCurrentContext());
  v8::Local<v8::FunctionTemplate> interface_template =
      data->FindInterfaceTemplate(world, {{v8_class}}::GetWrapperTypeInfo());
  v8::Local<v8::Signature> signature =
      v8::Signature::New(isolate, interface_template);

  static int dom_template_key; // This address is used for a key to look up the dom template.
  v8::Local<v8::FunctionTemplate> method_template =
      data->FindOrCreateOperationTemplate(
          world,
          &dom_template_key,
          {{v8_class_or_partial}}::{{method.camel_case_name}}MethodCallback{{world_suffix}},
          v8::Local<v8::Value>(),
          signature,
          {{method.length}});

  V8SetReturnValue(
      info,
      method_template->GetFunction(
          isolate->GetCurrentContext()).ToLocalChecked());
}
{% endmacro %}

{% macro origin_safe_method_getter_callback(method, world_suffix) %}
void {{v8_class_or_partial}}::{{method.camel_case_name}}OriginSafeMethodGetterCallback{{world_suffix}}(v8::Local<v8::Name>, const v8::PropertyCallbackInfo<v8::Value>& info) {
  {{ runtime_timer_scope_disabled_by_default(method.runtime_call_stats.origin_safe_method_getter_counter) }}
  {{internal_namespace}}::{{method.camel_case_name}}OriginSafeMethodGetter{{world_suffix}}(info);
}
{% endmacro %}


{##############################################################################}
{% macro generate_constructor(constructor) %}
{% set name = '%sConstructorCallback' % v8_class
              if constructor.is_named_constructor else
              'Constructor%s' % (constructor.overload_index or '') %}
static void {{name}}(const v8::FunctionCallbackInfo<v8::Value>& info) {
  {{ runtime_timer_scope_disabled_by_default(constructor.rcs_counter) }}
  {% set function_call = func_call_with_prep_of_args(constructor) %}

  {% if constructor.is_named_constructor %}
  if (!info.IsConstructCall()) {
    V8ThrowException::ThrowTypeError(info.GetIsolate(), ExceptionMessages::ConstructorNotCallableAsFunction("{{constructor.name}}"));
    return;
  }

  if (ConstructorMode::Current(info.GetIsolate()) == ConstructorMode::kWrapExistingObject) {
    V8SetReturnValue(info, info.Holder());
    return;
  }
  {% endif %}

  {% if 'exception_state' in function_call %}
  ExceptionState exception_state(info.GetIsolate(), ExceptionState::kConstructionContext, "{{interface_name}}");
  {% endif %}
  {% if 'script_state' in function_call %}
  ScriptState* script_state = ScriptState::From(
      info.NewTarget().As<v8::Object>()->CreationContext());
  {% endif %}

  {{function_call | trim | indent(2)}}
}
{% endmacro %}


{##############################################################################}
{% macro generate_constructor_wrapper(constructor) %}
{% set constructor_class = v8_class + ('Constructor'
                                       if constructor.is_named_constructor else
                                       '') %}
v8::Local<v8::Object> wrapper = info.Holder();
wrapper = impl->AssociateWithWrapper(info.GetIsolate(), {{constructor_class}}::GetWrapperTypeInfo(), wrapper);
V8SetReturnValue(info, wrapper);
{% endmacro %}


{##############################################################################}
{% macro method_configuration(method) %}
{% from 'utilities.cc.tmpl' import property_location %}
{% set method_callback =
       '%s::%sMethodCallback' % (v8_class_or_partial, method.camel_case_name) %}
{% set method_callback_for_main_world =
       '%s::%sMethodCallbackForMainWorld' % (v8_class_or_partial, method.camel_case_name)
       if method.is_per_world_bindings else 'nullptr' %}
{% set property_attribute =
       'static_cast<v8::PropertyAttribute>(%s)' % ' | '.join(method.property_attributes)
       if method.property_attributes else 'v8::None' %}
{% set holder_check = 'V8DOMConfiguration::kDoNotCheckHolder'
       if method.returns_promise else 'V8DOMConfiguration::kCheckHolder' %}
{% set access_check = 'V8DOMConfiguration::kCheckAccess'
       if method.is_check_security_for_receiver else 'V8DOMConfiguration::kDoNotCheckAccess' %}
{% if method.is_per_world_bindings %}
{% set method_callback_for_main_world =
       '%s::%sMethodCallbackForMainWorld' % (v8_class_or_partial, method.camel_case_name) %}
{"{{method.name}}", {{method_callback_for_main_world}}, {{method.length}}, {{property_attribute}}, {{property_location(method)}}, {{holder_check}}, {{access_check}}, {{method.side_effect_type}}, V8DOMConfiguration::kMainWorld},
{"{{method.name}}", {{method_callback}}, {{method.length}}, {{property_attribute}}, {{property_location(method)}}, {{holder_check}}, {{access_check}}, {{method.side_effect_type}}, V8DOMConfiguration::kNonMainWorlds}
{%- else %}
{"{{method.name}}", {{method_callback}}, {{method.length}}, {{property_attribute}}, {{property_location(method)}}, {{holder_check}}, {{access_check}}, {{method.side_effect_type}}, V8DOMConfiguration::kAllWorlds}
{%- endif %}
{%- endmacro %}


{######################################}
{% macro install_custom_signature(method, instance_template, prototype_template, interface_template, signature) %}
{
  // Install {{method.name}} configuration
  constexpr V8DOMConfiguration::MethodConfiguration kConfigurations[] = {
      {{method_configuration(method) | trim | indent(4)}}
  };
  for (const auto& config : kConfigurations) {
    V8DOMConfiguration::InstallMethod(
        isolate, world, {{instance_template}}, {{prototype_template}},
        {{interface_template}}, {{signature}}, config);
  }
}
{%- endmacro %}


{######################################}
{% macro install_conditional_methods(methods_to_install) %}
{% for method in methods_to_install %}
{% filter secure_context(method.overloads.secure_context_test_all
                         if method.overloads else
                         method.secure_context_test) %}
{% filter exposed(method.overloads.exposed_test_all
                  if method.overloads else
                  method.exposed_test) %}
{% filter runtime_enabled(method.overloads.runtime_enabled_all
                          if method.overloads else
                          method.runtime_enabled_feature_name) %}
{
  // Install {{method.name}} configuration
  const V8DOMConfiguration::MethodConfiguration kConfigurations[] = {
      {{method_configuration(method) | trim | indent(4)}}
  };
  for (const auto& config : kConfigurations) {
    V8DOMConfiguration::InstallMethod(
        isolate, world, instance_object, prototype_object,
        interface_object, signature, config);
  }
}
{% endfilter %}{# runtime_enabled() #}
{% endfilter %}{# exposed() #}
{% endfilter %}{# secure_context() #}
{% endfor %}
{%- endmacro %}
