{#
 # Copyright 2016 The Cobalt Authors. All Rights Reserved.
 #
 # Licensed under the Apache License, Version 2.0 (the "License");
 # you may not use this file except in compliance with the License.
 # You may obtain a copy of the License at
 #
 #     http://www.apache.org/licenses/LICENSE-2.0
 #
 # Unless required by applicable law or agreed to in writing, software
 # distributed under the License is distributed on an "AS IS" BASIS,
 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 # See the License for the specific language governing permissions and
 # limitations under the License.
 #}
{% extends "callback-interface-base.cc.template" %}

{% block includes %}
{{ super() }}
#include "{{generated_conversion_include}}"

#include "cobalt/script/logging_exception_state.h"
#include "cobalt/script/mozjs-45/conversion_helpers.h"
#include "cobalt/script/mozjs-45/mozjs_callback_interface.h"
#include "cobalt/script/mozjs-45/util/exception_helpers.h"
#include "cobalt/script/mozjs-45/util/stack_trace_helpers.h"
#include "third_party/mozjs-45/js/src/jsapi.h"
#include "third_party/mozjs-45/js/src/jscntxt.h"
{% endblock includes %}

{% block using_directives %}
{{ super() }}
using cobalt::script::LoggingExceptionState;
using cobalt::script::mozjs::FromJSValue;
using cobalt::script::mozjs::GetCallableForCallbackInterface;
using cobalt::script::mozjs::ToJSValue;
using cobalt::script::mozjs::util::GetExceptionString;
{% endblock using_directives %}

{% block implementation %}
{% for component in components %}
namespace {{component}} {
{% endfor %}

{{binding_class}}::{{binding_class}}(
    JSContext* context,
    JS::HandleValue implementing_object_value)
    : context_(context),
      implementing_object_(context, implementing_object_value) { }

{% for operation in operations %}
{% for overload in operation.overloads %}
{{overload.type}} {{binding_class}}::{{overload.name}}(
    const scoped_refptr<script::Wrappable>& callback_this,
  {% for arg in overload.arguments %}
    {{arg.arg_type}} {{arg.name}},
  {% endfor %}
    bool* had_exception) const {
  bool success = false;
{% if overload.type != 'void' %}
  {{overload.type}} cobalt_return_value;
{% endif %}
  JSAutoRequest auto_request(context_);
  JS::AutoSaveExceptionState auto_save_exception_state(context_);
  ENABLE_JS_STACK_TRACE_IN_SCOPE(context_);

  // This could be set to NULL if it was garbage collected.
  JS::RootedObject implementing_object(context_, implementing_object_.GetObject());
  DLOG_IF(WARNING, !implementing_object) << "Implementing object is NULL.";
  if (implementing_object) {
    JSAutoCompartment auto_compartment(context_, implementing_object);

    // Get callable object.
    JS::RootedValue callable(context_);
    if (GetCallableForCallbackInterface(context_, implementing_object,
                                        "{{overload.idl_name}}", &callable)) {
      // Convert the callback_this to a JSValue.
      JS::RootedValue this_value(context_);
      ToJSValue(context_, callback_this, &this_value);

      // Convert arguments.
      const int kNumArguments = {{overload.arguments|length}};
      JS::AutoValueArray<kNumArguments> args(context_);

{% for arg in overload.arguments %}
      ToJSValue(context_, {{arg.name}}, args[{{loop.index0}}]);
{% endfor %}

      // Call the function.
      JS::RootedValue return_value(context_);
      JS::RootedFunction function(
          context_, JS_ValueToFunction(context_, callable));
      DCHECK(function);
      success = JS::Call(context_, this_value, function, args, &return_value);
      DLOG_IF(WARNING, !success) << "Exception in callback: "
                                 << GetExceptionString(context_);
{% if overload.type != 'void' %}
      if (success) {
        LoggingExceptionState exception_state;
        FromJSValue(context_, return_value, 0, &exception_state,
                    &cobalt_return_value);
        success = !exception_state.is_exception_set();
      }
{% endif %}
    }
  }

  *had_exception = !success;
{% if overload.type != 'void' %}
  return cobalt_return_value;
{% endif %}
}
{% endfor %}
{% endfor %}

{% for component in components|reverse %}
}  // namespace {{component}}
{% endfor %}
{% endblock implementation %}
