{##############################################################################}
{# FIXME: We should return a rejected Promise if an error occurs in this
function when ALL methods in this overload return Promise. In order to do so,
we must ensure either ALL or NO methods in this overload return Promise #}
{% macro overload_resolution_method(method) %}
{% set overloads = method.overloads %}
{% if method.is_static %}
  {% set offset = 0 %}
{% else %}
  {% set offset = 1 %}
{% endif %}
static void {{static_method_name(overloads.name)}}Dispatcher(Dart_NativeArguments args)
{
    Dart_Handle exception = nullptr;
    const int argOffset = {{offset}};
    int argCount = Dart_GetNativeArgumentCount(args) - argOffset;

    {# First resolve by length #}
    {# 2. Initialize argcount to be min(maxarg, n). #}
    switch (std::min({{overloads.maxarg}}, argCount)) {
    {# 3. Remove from S all entries whose type list is not of length argcount. #}
    {% for length, tests_methods in overloads.length_tests_methods %}
    {# 10. If i = d, then: #}
    case {{length}}:
        {# Then resolve by testing argument #}
        {% for test, method in tests_methods %}
        if ({{test}}) {
          {% if method.is_custom %}
            {{static_method_name(method.name)}}(args);
          {% else %}
            {{static_method_name(method.name, method.overload_index)}}(args);
          {% endif %}
            return;
        }
        {% endfor %}
        break;
    {% endfor %}
    default:
        {# Invalid arity, throw error #}
        {# Report full list of valid arities if gaps and above minimum #}
        {% if overloads.valid_arities %}
        if (argCount >= {{overloads.minarg}}) {
            const String message = "Wrong arity, expected one of {{overloads.valid_arities}}";
            // TODO(dart): exception = DartUtilities::coreArgumentErrorException(message);
            goto fail;
        }
        {% endif %}
        {# Otherwise just report "not enough arguments" #}
        {
            const String message = "Not enough arguments (at least {{overloads.minarg}} required)";
            // TODO(dart): exception = DartUtilities::coreArgumentErrorException(message);
            goto fail;
        }
        return;
    }
    {
        const String message = "No function was found that matched the signature provided.";
        // TODO(dart): exception = DartUtilities::coreArgumentErrorException(message);
        goto fail;
    }
    return;
fail:
    Dart_ThrowException(exception);
    ASSERT_NOT_REACHED();
}
{% endmacro %}


{##############################################################################}
{# arguments_count is normal method.number_of_arguments however for optional  #}
{# arguments then number_of_required_arguments is passed (sans optional).     #}
{# overload in the index if overloaded.                                       #}
{# interface is specified signals that it's a constructor being called the    #}
{# delegation to the create is emitted.
{##############################################################################}
{% macro generate_method(method, arguments_count) %}
{% set overload_index = method.overload_index %}
static void {{static_method_name(method.name, overload_index)}}(Dart_NativeArguments args)
{
{% if not method.is_static %}
    {{cpp_class}}* /* FIXME(vsm): Remove this. */ ALLOW_UNUSED receiver = GetReceiver<{{cpp_class}}>(args);
{% endif %}
{% if method.is_custom_element_callbacks %}
    CustomElementProcessingStack::CallbackDeliveryScope deliveryScope;
{% endif %}
{% if arguments_count > 0 or
      method.has_exception_state or
      method.is_call_with_script_state or
      method.is_call_with_execution_context or
      method.is_call_with_script_arguments %}
    Dart_Handle exception = nullptr;
{% endif %}
    {
        {% if method.is_call_with_script_state %}
        ScriptState* state = DartUtilities::currentScriptState();
        if (!state) {
            exception = ToDart("Failed to retrieve a script state");
            goto fail;
        }
        {% endif %}
        {% if method.is_call_with_execution_context %}
        ExecutionContext* context = DOMDartState::CurrentDocument();
        if (!context) {
            exception = ToDart("Failed to retrieve a context");
            goto fail;
        }
        {% endif %}
        {% if method.is_call_with_script_arguments %}
        {# Last parameter is the customArgument #}
        Dart_Handle customArgument = Dart_GetNativeArgument(args, Dart_GetNativeArgumentCount(args) - 1);
        RefPtr<ScriptArguments> scriptArguments(DartUtilities::createScriptArguments(customArgument, exception));
        if (!scriptArguments)
            goto fail;
        {% endif %}
        {% if method.number_of_arguments != method.number_of_required_arguments %}
        int argCount /* FIXME(vsm): Remove this. */ ALLOW_UNUSED = Dart_GetNativeArgumentCount(args);
        {% endif %}
        {% if method.has_exception_state %}
        ExceptionState es;
        {% endif %}
        {{generate_arguments(method) | indent(8)}}
        {{callback_return(method, method.dart_set_return_value, method.cpp_value)}}
        {% if method.has_exception_state %}
        if (es.had_exception()) {
            exception = es.GetDartException(args, {{method.auto_scope}});
            goto fail;
        }

        {% endif %}
       return;
    }

{% if arguments_count > 0 or method.has_exception_state or method.is_call_with_script_state or method.is_call_with_execution_context or method.is_call_with_script_arguments %}
fail:
    Dart_ThrowException(exception);
    ASSERT_NOT_REACHED();
{% endif %}
}
{% endmacro %}


{##############################################################################}
{% macro callback_return(method, dart_set_return_value, cpp_value) %}
{%- if method.union_arguments -%}
{{callback_union_return(method) | indent(8)}}
{%- elif method.idl_type == 'void' -%}
{{cpp_value}};
{%- elif method.is_constructor -%}
DartConverter<{{cpp_class}}*>::SetReturnValue(args, WTF::getPtr({{cpp_value}}), {{method.auto_scope}});
{%- else -%}
{{dart_set_return_value}};
{%- endif -%}
{% endmacro %}


{##############################################################################}
{% macro callback_union_return(method, argument_count) %}
  {% set type_index = 0 %}
  {% for union_argument in method.union_arguments %}
{{method.cpp_type[type_index]}} {{union_argument}};
    {% set type_index = type_index + 1 %}
  {% endfor %}
{{method.cpp_value}};

  {% set union_set_result_index = 0 %}
  {% for union_argument in method.union_arguments %}
if ({{union_argument}}) {
    {{method.dart_set_return_value[union_set_result_index]}};
    return;
}
    {% set union_set_result_index = union_set_result_index + 1 %}
  {% endfor %}
{% endmacro %}


{##############################################################################}
{% macro generate_argument(method, argument) %}
{# If sequence result is passed as an argument not as function return value. #}
{% if argument.is_optional and
      not argument.has_default and
      not argument.is_callback_interface %}
{# Optional arguments without a default value generate an early call with
   fewer arguments if they are omitted. #}
if (UNLIKELY(argCount <= {{argument.arg_index}})) {
    {{callback_return(method, argument.dart_set_return_value, argument.cpp_value)}}
    if (exception)
        goto fail;
    return;
}
{% endif %}
{% if argument.is_callback_interface %}
{# Callback functions must be functions:
   http://www.w3.org/TR/WebIDL/#es-callback-function #}
{% if argument.is_optional %}
{{argument.local_cpp_type}} {{argument.name}};
if (argCount > {{argument.arg_index}}) {
    {{argument.name}} = DartConverter<{{argument.implemented_as}}*>::FromArgumentsWithNullCheck(args, {{argument.arg_index}}, exception);
}
{% else %}{# argument.is_optional #}
{{argument.local_cpp_type}} {{argument.name}} = DartConverter<{{argument.implemented_as}}*>::FromArgumentsWithNullCheck(args, {{argument.arg_index}}, exception);
{% endif %}{# argument.is_optional #}
{% else %}{# argument.is_callback_interface #}
{% if argument.is_optional and argument.has_default -%}
{{argument.local_cpp_type}} {{argument.name}} =
    (argCount <= {{argument.arg_index}}) ? ({{argument.default_value}}) : {{argument.dart_value_to_local_cpp_value}};
{% elif argument.is_array_or_sequence_type %}
{{argument.local_cpp_type}} {{argument.name}};
{{argument.dart_value_to_local_cpp_value}};
{% else %}
{{argument.local_cpp_type}} {{argument.name}} = {{argument.dart_value_to_local_cpp_value}};
{% endif %}
{% endif %}{# argument.is_callback_interface #}
if (exception)
    goto fail;
{% endmacro %}


{######################################}
{% macro generate_arguments(method) %}
{%- for argument in method.arguments -%}
{{generate_argument(method, argument)}}
{%- endfor -%}
{% endmacro %}

{##############################################################################}
{% macro static_method_name(name, overload_index) %}
{% set name = 'constructor' if not name else name -%}
{% if overload_index -%}
{{name}}Callback_{{overload_index}}
{%- else -%}
{{name}}Callback
{%- endif %}
{% endmacro -%}


{##############################################################################}
{% macro generate_resolver_body(dart_class, class_name, method) %}
{% for native_entry_group in method.native_entries|groupby('resolver_string') %}
{% set uses_script_args = method.is_call_with_script_arguments %}
{% if method.overload_index %}
  {% set method_name = static_method_name(method.name) + "Dispatcher" %}
{% else %}
  {% set method_name = static_method_name(method.name) %}
{% endif %}
{% set resolver_string = native_entry_group.grouper %}
{% if method.is_custom %}
// FIXME: we are missing changes from dart.idl so we don't always know how many
// args custom methods will take so we ignore that check which could hurt perf
// and security but lets us get everything running quicker.
if (name == "{{resolver_string}}") {
    *autoSetupScope = {{method.auto_scope}};
    return {{dart_class}}Internal::{{method_name}};
}
{% else %}
  {% set args_one_based = method.number_of_arguments %}
  {% set args_required_one_based = method.number_of_required_arguments %}
  {% if not method.is_static %}
    {% set args_one_based = args_one_based + 1 %}
    {% set args_required_one_based = args_required_one_based + 1 %}
  {% endif %}

  {% if uses_script_args %}
    {# FIXME(vsm): At least one script argument is expected.  Generalize? #}
    {% set args_one_based = args_one_based + 1 %}
    {% set args_required_one_based = args_required_one_based + 1 %}
  {% endif %}

  {% if args_one_based == args_required_one_based %}
if (argumentCount == {{args_one_based}} && name == "{{resolver_string}}") {
    *autoSetupScope = {{method.auto_scope}};
    return {{dart_class}}Internal::{{method_name}};
}
  {% else %}
if (argumentCount >= {{args_required_one_based}} && argumentCount <= {{args_one_based}} && name == "{{resolver_string}}") {
    *autoSetupScope = {{method.auto_scope}};
    return {{dart_class}}Internal::{{method_name}};
}
  {% endif %}
{% endif %}
{% endfor %}
{% endmacro %}


{##############################################################################}
{% macro generate_symbolizer_body(dart_class, class_name, method) %}
{% for native_entry_group in method.native_entries|groupby('resolver_string') %}
{% set uses_script_args = method.is_call_with_script_arguments %}
{% if method.overload_index %}
  {% set method_name = static_method_name(method.name) + "Dispatcher" %}
{% else %}
  {% set method_name = static_method_name(method.name) %}
{% endif %}
{% set resolver_string = native_entry_group.grouper %}
if (native_function == {{dart_class}}Internal::{{method_name}}) {
    return reinterpret_cast<const uint8_t*>("{{resolver_string}}");
}
{% endfor %}
{% endmacro %}


{##############################################################################}
{% macro generate_constructor(constructor, arguments_count, overload='') %}
{% if overload == '' %}
  {% set overload_index = constructor.overload_index %}
{% else %}
  {% set overload_index = overload %}
{% endif %}
static void {{static_method_name(constructor.name, overload_index)}}(Dart_NativeArguments args)
{
{% if arguments_count > 0 or
      constructor.has_exception_state or
      is_constructor_call_with_execution_context or
      is_constructor_call_with_document or
      (constructor == named_constructor) %}
    Dart_Handle exception = nullptr;
{% endif %}
    {
{% if is_constructor_call_with_execution_context %}
        ExecutionContext* context = DOMDartState::CurrentDocument();
        if (!context) {
            exception = ToDart("Failed to retrieve a context");
            goto fail;
        }
{% endif %}
{% if is_constructor_call_with_document or (constructor == named_constructor) %}
        LocalDOMWindow* domWindow = DOMDartState::CurrentWindow();
        if (!domWindow) {
            exception = ToDart("Failed to fetch domWindow");
            goto fail;
        }
        Document& document = *domWindow->document();
{% endif %}
        int argCount /* FIXME(vsm): Remove this. */ ALLOW_UNUSED = Dart_GetNativeArgumentCount(args);
{% if constructor.has_exception_state %}
        ExceptionState es;
{% endif %}
        {{generate_arguments(constructor) | indent(8)}}
        {{callback_return(constructor, constructor.dart_set_return_value, constructor.cpp_value) | indent(8)}}
{% if constructor.has_exception_state %}
        if (es.had_exception()) {
            exception = es.GetDartException(args, {{constructor.auto_scope}});
            goto fail;
        }

{% endif %}
        return;
    }

{% if arguments_count > 0 or constructor.has_exception_state or is_constructor_call_with_execution_context or is_constructor_call_with_document or (constructor == named_constructor) %}
fail:
    Dart_ThrowException(exception);
    ASSERT_NOT_REACHED();
{% endif %}
}
{% endmacro %}


{##############################################################################}
{% macro generate_event_constructor() %}
static void eventConstructorCallback(Dart_NativeArguments args)
{
    Dart_SetReturnValue(args, Dart_Null());
}
{% endmacro %}

,
{##############################################################################}
{% macro generate_resolver_constructor(dart_class, class_name, constructor) %}
{% for native_entry in constructor.native_entries %}
{% set resolver_string = native_entry.resolver_string %}
{% if constructor.overload_index %}
  {% set constructor_name = static_method_name(constructor.name) + "Dispatcher" %}
{% else %}
  {% set constructor_name = static_method_name(constructor.name) %}
{% endif %}
{% if has_custom_constructor %}
if (name == "{{resolver_string}}") {
{% elif constructor.number_of_arguments == constructor.number_of_required_arguments %}
if (argumentCount == {{constructor.number_of_arguments}} && name == "{{resolver_string}}") {
{% else %}
if (argumentCount >= {{constructor.number_of_required_arguments}} && argumentCount <= {{constructor.number_of_arguments}} && name == "{{resolver_string}}") {
{% endif %}
    *autoSetupScope = {{constructor.auto_scope}};
    return {{dart_class}}Internal::{{constructor_name}};
}
{% endfor %}
{% endmacro %}

{##############################################################################}
{% macro generate_resolver_event_constructor(dart_class, class_name) %}
{% set resolver_string = interface_name + "_constructorCallback" %}
if (argumentCount == 2 && name == "{{resolver_string}}") {
    *autoSetupScope = 1;
    return {{dart_class}}Internal::eventConstructorCallback;
}
{% endmacro %}

{##############################################################################}
{% macro generate_symbolizer_constructor(dart_class, class_name, constructor) %}
{% for native_entry in constructor.native_entries %}
{% set resolver_string = native_entry.resolver_string %}
if (native_function == {{dart_class}}Internal::{{static_method_name(constructor.name, constructor.overload_index)}}) {
  return reinterpret_cast<const uint8_t*>("{{resolver_string}}");
}
{% endfor %}
{% endmacro %}
