/*
 * 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.
 */

// clang-format off

// This file has been auto-generated by bindings/code_generator_cobalt.py. DO NOT MODIFY!
// Auto-generated from template: bindings/templates/dictionary.h.template

#ifndef TestDictionary_h
#define TestDictionary_h

#include <string>

#include "cobalt/script/sequence.h"
#include "cobalt/bindings/testing/arbitrary_interface.h"

using cobalt::bindings::testing::ArbitraryInterface;

namespace cobalt {
namespace bindings {
namespace testing {

class TestDictionary {
 public:
  TestDictionary() {
    has_boolean_member_ = false;
    boolean_member_ = bool();
    has_short_clamp_member_ = false;
    short_clamp_member_ = int16_t();
    has_long_member_ = false;
    long_member_ = int32_t();
    has_double_member_ = false;
    double_member_ = double();
    has_string_member_ = false;
    string_member_ = std::string();
    has_interface_member_ = false;
    interface_member_ = scoped_refptr<ArbitraryInterface>();
    has_member_with_default_ = true;
    member_with_default_ = 5;
    has_non_default_member_ = false;
    non_default_member_ = int32_t();
  }

  bool has_boolean_member() const {
    return has_boolean_member_;
  }
  bool boolean_member() const {
    DCHECK(has_boolean_member_);
    return boolean_member_;
  }
  void set_boolean_member(bool value) {
    has_boolean_member_ = true;
    boolean_member_ = value;
  }

  bool has_short_clamp_member() const {
    return has_short_clamp_member_;
  }
  int16_t short_clamp_member() const {
    DCHECK(has_short_clamp_member_);
    return short_clamp_member_;
  }
  void set_short_clamp_member(int16_t value) {
    has_short_clamp_member_ = true;
    short_clamp_member_ = value;
  }

  bool has_long_member() const {
    return has_long_member_;
  }
  int32_t long_member() const {
    DCHECK(has_long_member_);
    return long_member_;
  }
  void set_long_member(int32_t value) {
    has_long_member_ = true;
    long_member_ = value;
  }

  bool has_double_member() const {
    return has_double_member_;
  }
  double double_member() const {
    DCHECK(has_double_member_);
    return double_member_;
  }
  void set_double_member(double value) {
    has_double_member_ = true;
    double_member_ = value;
  }

  bool has_string_member() const {
    return has_string_member_;
  }
  std::string string_member() const {
    DCHECK(has_string_member_);
    return string_member_;
  }
  void set_string_member(const std::string& value) {
    has_string_member_ = true;
    string_member_ = value;
  }

  bool has_interface_member() const {
    return has_interface_member_;
  }
  scoped_refptr<ArbitraryInterface> interface_member() const {
    DCHECK(has_interface_member_);
    return interface_member_;
  }
  void set_interface_member(const scoped_refptr<ArbitraryInterface>& value) {
    has_interface_member_ = true;
    interface_member_ = value;
  }

  bool has_member_with_default() const {
    return has_member_with_default_;
  }
  int32_t member_with_default() const {
    DCHECK(has_member_with_default_);
    return member_with_default_;
  }
  void set_member_with_default(int32_t value) {
    has_member_with_default_ = true;
    member_with_default_ = value;
  }

  bool has_non_default_member() const {
    return has_non_default_member_;
  }
  int32_t non_default_member() const {
    DCHECK(has_non_default_member_);
    return non_default_member_;
  }
  void set_non_default_member(int32_t value) {
    has_non_default_member_ = true;
    non_default_member_ = value;
  }

 private:
  bool has_boolean_member_;
  bool boolean_member_;
  bool has_short_clamp_member_;
  int16_t short_clamp_member_;
  bool has_long_member_;
  int32_t long_member_;
  bool has_double_member_;
  double double_member_;
  bool has_string_member_;
  std::string string_member_;
  bool has_interface_member_;
  scoped_refptr<ArbitraryInterface> interface_member_;
  bool has_member_with_default_;
  int32_t member_with_default_;
  bool has_non_default_member_;
  int32_t non_default_member_;
};

// This ostream override is necessary for MOCK_METHODs commonly used
// in idl test code
inline std::ostream& operator<<(
    std::ostream& stream, const cobalt::bindings::testing::TestDictionary& in) {
  UNREFERENCED_PARAMETER(in);
  stream << "[TestDictionary]";
  return stream;
}

}  // namespace cobalt
}  // namespace bindings
}  // namespace testing

#endif  // TestDictionary_h
