{#
 # Copyright 2016 Google Inc. 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 %}
