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

{# Implements callback interface\'s "call a user object's operation", or
   callback function\'s "invoke" and/or "construct".
   https://heycam.github.io/webidl/#call-a-user-objects-operation
   https://heycam.github.io/webidl/#es-invoking-callback-functions

   Args:
      interface_or_function = 'callback interface' or 'callback function'
      invoke_or_construct = 'invoke', 'construct', or None
      return_cpp_type = Blink (C++) return type
      return_native_value_traits_tag = tag of NativeValueTraits for return type
      arguments = dict of arguments\' info
      is_treat_non_object_as_null = True if [TreatNonObjectAsNull]
      bypass_runnability_check = Skip IsCallbackFunctionRunnable check if True
      interface_name = interface name used for exception
      operation_name = interface name used for exception and property lookup
#}
{% macro callback_invoke(
    interface_or_function, invoke_or_construct,
    return_cpp_type, return_native_value_traits_tag, arguments,
    is_treat_non_object_as_null, bypass_runnability_check,
    interface_name, operation_name) %}
  {% if not bypass_runnability_check %}
  if (!IsCallbackFunctionRunnable(CallbackRelevantScriptState(),
                                  IncumbentScriptState())) {
    // 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.
    v8::HandleScope handle_scope(GetIsolate());
    v8::Local<v8::Object> callback_object = CallbackObject();
    CHECK(!callback_object.IsEmpty());
    v8::Context::Scope context_scope(callback_object->CreationContext());
    V8ThrowException::ThrowError(
        GetIsolate(),
        ExceptionMessages::FailedToExecute(
            "{{operation_name}}",
            "{{interface_name}}",
            "The provided callback is no longer runnable."));
    return v8::Nothing<{{return_cpp_type}}>();
  }
  {% endif %}

  // step: Prepare to run script with relevant settings.
  ScriptState::Scope callback_relevant_context_scope(
      CallbackRelevantScriptState());
  // step: Prepare to run a callback with stored settings.
  v8::Context::BackupIncumbentScope backup_incumbent_scope(
      IncumbentScriptState()->GetContext());

  {% if invoke_or_construct == 'construct' %}
  // step 3. If ! IsConstructor(F) is false, throw a TypeError exception.
  //
  // Note that step 7. and 8. are side effect free (except for a very rare
  // exception due to no incumbent realm), so it's okay to put step 3. after
  // step 7. and 8.
  if (!IsConstructor()) {
    V8ThrowException::ThrowTypeError(
        GetIsolate(),
        ExceptionMessages::FailedToExecute(
            "{{operation_name}}",
            "{{interface_name}}",
            "The provided callback is not a constructor."));
    return v8::Nothing<{{return_cpp_type}}>();
  }
  {% endif %}

  v8::Local<v8::Function> function;
  {# Fill |function|. #}
  {% if interface_or_function == 'callback function' %}
  // callback function's invoke:
  // step 4. If ! IsCallable(F) is false:
  {% if is_treat_non_object_as_null %}
  if (!CallbackObject()->IsFunction()) {
    // Handle the special case of [TreatNonObjectAsNull].
    //
    {% if return_cpp_type == 'void' %}
    // step 4.1. If the callback function's return type is void, return.
    return v8::JustVoid();
    {% else %}
    // step 4.2. Return the result of converting undefined to the callback
    //   function's return type.
    ExceptionState exception_state(GetIsolate(),
                                   ExceptionState::kExecutionContext,
                                   "{{interface_name}}",
                                   "{{operation_name}}");
    auto native_result =
        NativeValueTraits<{{return_native_value_traits_tag}}>::NativeValue(
            GetIsolate(), v8::Undefined(GetIsolate()), exception_state);
    if (exception_state.HadException())
      return v8::Nothing<{{return_cpp_type}}>();
    else
      return v8::Just<{{return_cpp_type}}>(native_result);
    {% endif %}{# if return_cpp_type == 'void' #}
  }
  {% else %}
  //
  // No [TreatNonObjectAsNull] presents.  Must be always callable.
  DCHECK(CallbackObject()->IsFunction());
  {% endif %}
  function = CallbackFunction();
  {% else %}
  if (IsCallbackObjectCallable()) {
    // step 9.1. If value's interface is a single operation callback interface
    //   and !IsCallable(O) is true, then set X to O.
    function = CallbackObject().As<v8::Function>();
  } else {
    // step 9.2.1. Let getResult be Get(O, opName).
    // step 9.2.2. If getResult is an abrupt completion, set completion to
    //   getResult and jump to the step labeled return.
    v8::Local<v8::Value> value;
    if (!CallbackObject()->Get(CallbackRelevantScriptState()->GetContext(),
                               V8String(GetIsolate(), "{{operation_name}}"))
        .ToLocal(&value)) {
      return v8::Nothing<{{return_cpp_type}}>();
    }
    // step 10. If !IsCallable(X) is false, then set completion to a new
    //   Completion{[[Type]]: throw, [[Value]]: a newly created TypeError
    //   object, [[Target]]: empty}, and jump to the step labeled return.
    if (!value->IsFunction()) {
      V8ThrowException::ThrowTypeError(
          GetIsolate(),
          ExceptionMessages::FailedToExecute(
              "{{operation_name}}",
              "{{interface_name}}",
              "The provided callback is not callable."));
      return v8::Nothing<{{return_cpp_type}}>();
    }
    function = value.As<v8::Function>();
  }
  {% endif %}

  {% if invoke_or_construct != 'construct' %}
  v8::Local<v8::Value> this_arg;
  {% endif %}
  {# Fill |this_arg|. #}
  {% if invoke_or_construct == 'invoke' %}
  this_arg = ToV8(callback_this_value, CallbackRelevantScriptState());
  {% elif interface_or_function == 'callback interface' %}
  if (!IsCallbackObjectCallable()) {
    // step 11. If value's interface is not a single operation callback
    //   interface, or if !IsCallable(O) is false, set thisArg to O (overriding
    //   the provided value).
    this_arg = CallbackObject();
  } else if (!callback_this_value) {
    // step 2. If thisArg was not given, let thisArg be undefined.
    this_arg = v8::Undefined(GetIsolate());
  } else {
    this_arg = ToV8(callback_this_value, CallbackRelevantScriptState());
  }
  {% endif %}

  {% for argument in arguments if argument.enum_values %}
  // Enum values provided by Blink must be valid, otherwise typo.
#if DCHECK_IS_ON()
  {
    {% set valid_enum_variables = 'valid_' + argument.name + '_values' %}
    {{declare_enum_validation_variable(argument.enum_values, valid_enum_variables) | trim | indent(4)}}
    ExceptionState exception_state(GetIsolate(),
                                   ExceptionState::kExecutionContext,
                                   "{{interface_name}}",
                                   "{{operation_name}}");
    if (!IsValidEnum({{argument.name}}, {{valid_enum_variables}}, base::size({{valid_enum_variables}}), "{{argument.enum_type}}", exception_state)) { //
      NOTREACHED();
      return v8::Nothing<{{return_cpp_type}}>();
    }
  }
#endif
  {% endfor %}

  // step: Let esArgs be the result of converting args to an ECMAScript
  //   arguments list. If this throws an exception, set completion to the
  //   completion value representing the thrown exception and jump to the step
  //   labeled return.
  {% if arguments %}
  v8::Local<v8::Object> argument_creation_context =
      CallbackRelevantScriptState()->GetContext()->Global();
  ALLOW_UNUSED_LOCAL(argument_creation_context);
  {% set has_variadic_argument = arguments[-1].is_variadic %}
  {% set non_variadic_arguments = arguments | rejectattr('is_variadic') | list %}
  {% set variadic_argument = arguments[-1] if has_variadic_argument else None %}
  {% set arguments_length = '%d + %s.size()' % (non_variadic_arguments|length, variadic_argument.name) if has_variadic_argument else non_variadic_arguments|length %}
  {% for argument in non_variadic_arguments %}
  v8::Local<v8::Value> {{argument.v8_name}} = {{argument.cpp_value_to_v8_value}};
  {% endfor %}
  {% if has_variadic_argument %}
  const int argc = {{arguments_length}};
  v8::Local<v8::Value> argv[argc];
  {% for argument in non_variadic_arguments %}
  argv[{{loop.index0}}] = {{argument.v8_name}};
  {% endfor %}
  for (wtf_size_t i = 0; i < {{variadic_argument.name}}.size(); ++i) {
    argv[{{non_variadic_arguments|length}} + i] = ToV8({{variadic_argument.name}}[i], argument_creation_context, GetIsolate());
  }
  {% else %}{# if has_variadic_argument #}
  constexpr int argc = {{arguments_length}};
  v8::Local<v8::Value> argv[] = { {{non_variadic_arguments | join(', ', 'v8_name')}} };
  static_assert(static_cast<size_t>(argc) == base::size(argv), "size mismatch");
  {% endif %}
  {% else %}{# if arguments #}
  const int argc = 0;
  {# Zero-length arrays are ill-formed in C++. #}
  v8::Local<v8::Value> *argv = nullptr;
  {% endif %}

  v8::Local<v8::Value> call_result;
  {# Fill |call_result|. #}
  {% if invoke_or_construct == 'construct' %}
  if (!V8ScriptRunner::CallAsConstructor(
          GetIsolate(),
          function,
          ExecutionContext::From(CallbackRelevantScriptState()),
          argc,
          argv).ToLocal(&call_result)) {
    // step 11. If callResult is an abrupt completion, set completion to
    //   callResult and jump to the step labeled return.
    return v8::Nothing<{{return_cpp_type}}>();
  }
  {% else %}
  // step: Let callResult be Call(X, thisArg, esArgs).
  if (!V8ScriptRunner::CallFunction(
          function,
          ExecutionContext::From(CallbackRelevantScriptState()),
          this_arg,
          argc,
          argv,
          GetIsolate()).ToLocal(&call_result)) {
    // step: If callResult is an abrupt completion, set completion to callResult
    //   and jump to the step labeled return.
    return v8::Nothing<{{return_cpp_type}}>();
  }
  {% endif %}


  // step: Set completion to the result of converting callResult.[[Value]] to
  //   an IDL value of the same type as the operation's return type.
  {% if return_cpp_type == 'void' %}
  return v8::JustVoid();
  {% else %}
  {
    ExceptionState exception_state(GetIsolate(),
                                   ExceptionState::kExecutionContext,
                                   "{{interface_name}}",
                                   "{{operation_name}}");
    auto native_result =
        NativeValueTraits<{{return_native_value_traits_tag}}>::NativeValue(
            GetIsolate(), call_result, exception_state);
    if (exception_state.HadException())
      return v8::Nothing<{{return_cpp_type}}>();
    else
      return v8::Just<{{return_cpp_type}}>(native_result);
  }
  {% endif %}
{% endmacro %}
