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

 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) {
  SB_UNREFERENCED_PARAMETER(in);
  stream << "[{{class_name}}]";
  return stream;
}

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

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

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