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

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

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

{% endif %}
#include <string>

#include "cobalt/script/sequence.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 %}
 public:
  {{class_name}}() {
{% for member in members %}
{% if member.default_value %}
    has_{{member.name}}_ = true;
    {{member.name}}_ = {{member.default_value}};
{% else %}
    has_{{member.name}}_ = false;
    {{member.name}}_ = {{member.type}}();
{% endif %}
{% endfor %}
  }

{% for member in members %}
  bool has_{{member.name}}() const {
    return has_{{member.name}}_;
  }
  {{member.type}} {{member.name}}() const {
    DCHECK(has_{{member.name}}_);
    return {{member.name}}_;
  }
  void set_{{member.name}}({{member.arg_type}} value) {
    has_{{member.name}}_ = true;
    {{member.name}}_ = value;
  }

{% endfor %}
 private:
{% for member in members %}
  bool has_{{member.name}}_;
  {{member.type}} {{member.name}}_;
{% 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) {
  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
