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

// clang-format off

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

#ifndef {{class_name}}_h
#define {{class_name}}_h

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

{% endif %}
#include <string>

#include "base/optional.h"
#include "cobalt/script/array_buffer.h"
#include "cobalt/script/array_buffer_view.h"
#include "cobalt/script/script_value.h"
#include "cobalt/script/sequence.h"
#include "cobalt/script/typed_arrays.h"
#include "cobalt/script/value_handle.h"
{% for include in includes %}
#include "{{include}}"
{% endfor %}

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

{% 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 %}

{% if parent %}
class {{class_name}} : public {{parent}} {
{% else %}
class {{class_name}} {
{% endif %}
{% set initializer_list = [] %}
{% for member in members %}
{% if not member.default_value %}
{% do initializer_list.append(("has_" + member.name, "false")) %}
{% endif %}
{% if not member.is_script_value %}
{% if member.default_value %}
{% do initializer_list.append((member.name, member.default_value)) %}
{% else %}
{% do initializer_list.append((member.name, member.type + "()")) %}
{% endif %}
{% endif %}
{% endfor %}
{% if initializer_list %}
{% set formatted_initializer_list = [] %}
{% for name, value in initializer_list %}
{% do formatted_initializer_list.append(name + "_(" + value + ")") %}
{% endfor %}
 public:
  {{class_name}}()
    : {{ formatted_initializer_list|join(',\n      ') }} {
{% else %}
 public:
  {{class_name}}() {
{% endif %}
  }

{% if parent %}
  {{class_name}}(const {{class_name}}& other)
    : {{parent}}(other) {
{% else %}
  {{class_name}}(const {{class_name}}& other) {
{% endif %}
{% for member in members %}
{% if not member.default_value %}
    has_{{member.name}}_ = other.has_{{member.name}}_;
{% endif %}
{% if not member.is_script_value %}
    {{member.name}}_ = other.{{member.name}}_;
{% else %}
    if (other.{{member.name}}_) {
      {{member.name}}_.reset(
          new script::Handle<{{member.type}}>(
              *other.{{member.name}}_));
    }
{% endif %}
{% endfor %}
  }

  {{class_name}}& operator=(const {{class_name}}& other) {
{% if parent %}
    {{parent}}::operator=(other);
{% endif %}
{% for member in members %}
{% if not member.default_value %}
    has_{{member.name}}_ = other.has_{{member.name}}_;
{% endif %}
{% if not member.is_script_value %}
    {{member.name}}_ = other.{{member.name}}_;
{% else %}
    if (other.{{member.name}}_) {
      {{member.name}}_.reset(
          new script::Handle<{{member.type}}>(
              *other.{{member.name}}_));
    } else {
      {{member.name}}_.reset();
    }
{% endif %}
{% endfor %}
    return *this;
  }

{% for member in members %}
  bool has_{{member.name}}() const {
{% if member.default_value %}
    return true;
{% else %}
    return has_{{member.name}}_;
{% endif %}
  }
  {{member.arg_type}} {{member.name}}() const {
{% if not member.default_value %}
    DCHECK(has_{{member.name}}_);
{% endif %}
{% if member.is_script_value %}
    if (!{{member.name}}_) {
      return NULL;
    }
    return ({{member.name}}_->GetScriptValue());
{% else %}
    return {{member.name}}_;
{% endif %}
  }
  void set_{{member.name}}({{member.arg_type}} value) {
{% if not member.default_value %}
    has_{{member.name}}_ = true;
{% endif %}
{% if member.is_script_value %}
    if (value) {
      {{member.name}}_.reset(
          new script::Handle<{{member.type}}>(*value));
    } else {
      {{member.name}}_.reset();
    }
{% else %}
    {{member.name}}_ = value;
{% endif %}
  }

{% endfor %}

 using is_a_generated_dict = std::true_type;

 private:
{% for member in members %}
{% if not member.default_value %}
  bool has_{{member.name}}_;
{% endif %}
{% if member.is_script_value %}
  std::unique_ptr<script::Handle<{{member.type}}>> {{member.name}}_;
{% else %}
  {{member.type}} {{member.name}}_;
{% endif %}
{% endfor %}
};

// This ostream override is necessary for MOCK_METHODs commonly used
// in idl test code
inline std::ostream& operator<<(
    std::ostream& stream, const {{components|join('::')}}::{{class_name}}& in) {
  stream << "[{{class_name}}]";
  return stream;
}

{% for component in components %}
}  // namespace {{component}}
{% endfor %}

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

{% endif %}
#endif  // {{class_name}}_h
