{#
 # Copyright 2017 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.
 #}
/*
 * Copyright {{today.year}} 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.
 */

// clang-format off

// This file has been auto-generated by {{code_generator}}. DO NOT MODIFY!
// Auto-generated from template: {{template_path}}

{% if conditional %}
#if defined({{conditional}})

{% endif %}
{% block includes %}
#include "{{generated_conversion_include}}"

#include "{{header_file}}"

#include "cobalt/script/exception_state.h"
#include "third_party/mozjs/js/src/jsapi.h"
{% for include in includes %}
#include "{{include}}"
{% endfor %}
{% endblock includes %}

using {{components|join('::')}}::{{class_name}};
{% for used_class in forward_declarations %}
{% if used_class.conditional %}
#if defined({{used_class.conditional}})
{% endif %}
using {{used_class.fully_qualified_name}};
{% if used_class.conditional %}
#endif  // defined({{used_class.conditional}})
{% endif %}
{% endfor %}

namespace cobalt {
namespace script {
namespace mozjs {

void ToJSValue(
    JSContext* context,
    const {{class_name}}& in_dictionary,
    JS::MutableHandleValue out_value) {
  // Create a new object that will hold the dictionary values.
  JS::RootedObject dictionary_object(
      context, JS_NewObject(context, NULL, NULL, NULL));
  const int kPropertyAttributes = JSPROP_ENUMERATE;
{% for member in members %}
  if (in_dictionary.has_{{member.name}}()) {
    JS::RootedValue member_value(context);
    ToJSValue(context, in_dictionary.{{member.name}}(), &member_value);
    if (!JS_DefineProperty(context, dictionary_object,
                           "{{member.idl_name}}",
                           member_value, NULL, NULL, kPropertyAttributes)) {
      // Some internal error occurred.
      NOTREACHED();
      return;
    }
  }
{% endfor %}
  out_value.set(OBJECT_TO_JSVAL(dictionary_object));
}

void FromJSValue(JSContext* context, JS::HandleValue value,
                 int conversion_flags, ExceptionState* exception_state,
                 {{class_name}}* out_dictionary) {
  DCHECK_EQ(0, conversion_flags) << "Unexpected conversion flags.";
  // https://heycam.github.io/webidl/#es-dictionary

  if (value.isUndefined() || value.isNull()) {
    // The default constructor will assign appropriate values to dictionary
    // members with default values and leave the others unset.
    *out_dictionary = {{class_name}}();
    return;
  }
  if (!value.isObject()) {
    // 1. If Type(V) is not Undefined, Null or Object, then throw a TypeError.
    exception_state->SetSimpleException(kNotObjectType);
    return;
  }
  JS::RootedObject dictionary_object(context, JSVAL_TO_OBJECT(value));
{% for member in members %}
  JS::RootedValue {{member.name}}(context);
  if (!JS_GetProperty(context, dictionary_object,
                      "{{member.idl_name}}",
                      {{member.name}}.address())) {
    exception_state->SetSimpleException(kSimpleError);
    return;
  }
  if (!{{member.name}}.isUndefined()) {
    {{member.type}} converted_value;
    FromJSValue(context,
                {{member.name}},
                {{member.conversion_flags}},
                exception_state,
                &converted_value);
    if (context->isExceptionPending()) {
      return;
    }
    out_dictionary->set_{{member.name}}(converted_value);
  }
{% endfor %}
}

}  // namespace mozjs
}  // namespace script
}  // namespace cobalt

{% if conditional %}
#endif  // defined({{conditional}})
{% endif %}
