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

{% for component in components %}
namespace {{component}} {
{% 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
