// WARNING: This file is machine generated by fidlgen.

// fidl_experiment = output_index_json

#pragma once

#include "lib/fidl/cpp/internal/header.h"

namespace test {
namespace doccomments {

//
// Domain objects declarations
//

/// strict bits comment #1
///
/// strict bits comment #2
enum class MyStrictBits : uint32_t {

  /// MY_FIRST_BIT member comment #1
  ///
  /// MY_FIRST_BIT member comment #3
  MY_FIRST_BIT = 1u,

  /// MY_OTHER_BIT member comment #1
  ///
  /// MY_OTHER_BIT member comment #3
  MY_OTHER_BIT = 2u,
};

const static MyStrictBits MyStrictBitsMask = static_cast<MyStrictBits>(3u);

constexpr inline ::test::doccomments::MyStrictBits operator|(::test::doccomments::MyStrictBits _lhs, ::test::doccomments::MyStrictBits _rhs) {
  return static_cast<::test::doccomments::MyStrictBits>(
      static_cast<uint32_t>(_lhs) | static_cast<uint32_t>(_rhs));
}

constexpr inline ::test::doccomments::MyStrictBits& operator|=(::test::doccomments::MyStrictBits& _lhs,
                                                               ::test::doccomments::MyStrictBits _rhs) {
  _lhs = _lhs | _rhs;
  return _lhs;
}

constexpr inline ::test::doccomments::MyStrictBits operator&(::test::doccomments::MyStrictBits _lhs,
                                                             ::test::doccomments::MyStrictBits _rhs) {
  return static_cast<::test::doccomments::MyStrictBits>(
      static_cast<uint32_t>(_lhs) & static_cast<uint32_t>(_rhs));
}

constexpr inline ::test::doccomments::MyStrictBits& operator&=(::test::doccomments::MyStrictBits& _lhs,
                                                               ::test::doccomments::MyStrictBits _rhs) {
  _lhs = _lhs & _rhs;
  return _lhs;
}

constexpr inline ::test::doccomments::MyStrictBits operator^(::test::doccomments::MyStrictBits _lhs,
                                                             ::test::doccomments::MyStrictBits _rhs) {
  return static_cast<::test::doccomments::MyStrictBits>(
      static_cast<uint32_t>(_lhs) ^ static_cast<uint32_t>(_rhs));
}

constexpr inline ::test::doccomments::MyStrictBits& operator^=(::test::doccomments::MyStrictBits& _lhs,
                                                               ::test::doccomments::MyStrictBits _rhs) {
  _lhs = _lhs ^ _rhs;
  return _lhs;
}

constexpr inline ::test::doccomments::MyStrictBits operator~(::test::doccomments::MyStrictBits _value) {
  return static_cast<::test::doccomments::MyStrictBits>(
      ~static_cast<uint32_t>(_value) & static_cast<uint32_t>(::test::doccomments::MyStrictBitsMask));
}

inline zx_status_t Clone(::test::doccomments::MyStrictBits value,
                         ::test::doccomments::MyStrictBits* result) {
  *result = value;
  return ZX_OK;
}

/// flexible bits comment #1
///
/// flexible bits comment #2
// |MyFlexibleBits| is flexible, hence may contain unknown members not
// defined in the FIDL schema.
class MyFlexibleBits final {
 public:
  constexpr MyFlexibleBits() = default;

  // Constructs an instance of |MyFlexibleBits| from an underlying primitive value
  // if the primitive does not contain any unknown members not defined in the
  // FIDL schema. Otherwise, returns |cpp17::nullopt|.
  constexpr inline static cpp17::optional<MyFlexibleBits> TryFrom(uint32_t value) {
    if (value & ~kMask.value_) {
      return cpp17::nullopt;
    }
    return MyFlexibleBits(value & MyFlexibleBits::kMask.value_);
  }

  // Constructs an instance of |MyFlexibleBits| from an underlying primitive value,
  // clearing any bit member not defined in the FIDL schema.
  constexpr inline static MyFlexibleBits TruncatingUnknown(uint32_t value) {
    return MyFlexibleBits(value & MyFlexibleBits::kMask.value_);
  }

  // Constructs an instance of |MyFlexibleBits| from an underlying primitive value,
  // preserving any bit member not defined in the FIDL schema.
  constexpr explicit MyFlexibleBits(uint32_t value) : value_(value) {}
  const static MyFlexibleBits MY_FIRST_BIT;
  const static MyFlexibleBits MY_OTHER_BIT;
  const static MyFlexibleBits kMask;

  explicit constexpr inline operator uint32_t() const { return value_; }
  explicit constexpr inline operator bool() const { return static_cast<bool>(value_); }
  constexpr inline bool operator==(const MyFlexibleBits& other) const { return value_ == other.value_; }
  constexpr inline bool operator!=(const MyFlexibleBits& other) const { return value_ != other.value_; }
  constexpr inline MyFlexibleBits operator~() const;
  constexpr inline MyFlexibleBits operator|(const MyFlexibleBits& other) const;
  constexpr inline MyFlexibleBits operator&(const MyFlexibleBits& other) const;
  constexpr inline MyFlexibleBits operator^(const MyFlexibleBits& other) const;
  constexpr inline void operator|=(const MyFlexibleBits& other);
  constexpr inline void operator&=(const MyFlexibleBits& other);
  constexpr inline void operator^=(const MyFlexibleBits& other);
  constexpr inline MyFlexibleBits unknown_bits() const {
    return *this & MyFlexibleBits(~kMask.value_);
  }
  constexpr inline bool has_unknown_bits() const { return static_cast<bool>(unknown_bits()); }

 private:
  uint32_t value_ = 0;
};

#if !(__cplusplus < 201703)
constexpr const ::test::doccomments::MyFlexibleBits MyFlexibleBits::MY_FIRST_BIT = ::test::doccomments::MyFlexibleBits(1u);
constexpr const ::test::doccomments::MyFlexibleBits MyFlexibleBits::MY_OTHER_BIT = ::test::doccomments::MyFlexibleBits(2u);
constexpr const ::test::doccomments::MyFlexibleBits MyFlexibleBits::kMask = ::test::doccomments::MyFlexibleBits(3u);

#endif  // !(__cplusplus < 201703)

constexpr inline ::test::doccomments::MyFlexibleBits MyFlexibleBits::operator~() const {
  return ::test::doccomments::MyFlexibleBits(static_cast<uint32_t>(~this->value_ & kMask.value_));
}

constexpr inline ::test::doccomments::MyFlexibleBits MyFlexibleBits::operator|(
    const ::test::doccomments::MyFlexibleBits& other) const {
  return ::test::doccomments::MyFlexibleBits(static_cast<uint32_t>(this->value_ | other.value_));
}

constexpr inline ::test::doccomments::MyFlexibleBits MyFlexibleBits::operator&(
    const ::test::doccomments::MyFlexibleBits& other) const {
  return ::test::doccomments::MyFlexibleBits(static_cast<uint32_t>(this->value_ & other.value_));
}

constexpr inline ::test::doccomments::MyFlexibleBits MyFlexibleBits::operator^(
    const ::test::doccomments::MyFlexibleBits& other) const {
  return ::test::doccomments::MyFlexibleBits(static_cast<uint32_t>(this->value_ ^ other.value_));
}

constexpr inline void MyFlexibleBits::operator|=(
    const ::test::doccomments::MyFlexibleBits& other) {
  this->value_ |= other.value_;
}

constexpr inline void MyFlexibleBits::operator&=(
    const ::test::doccomments::MyFlexibleBits& other) {
  this->value_ &= other.value_;
}

constexpr inline void MyFlexibleBits::operator^=(
    const ::test::doccomments::MyFlexibleBits& other) {
  this->value_ ^= other.value_;
}

inline zx_status_t Clone(::test::doccomments::MyFlexibleBits value,
                         ::test::doccomments::MyFlexibleBits* result) {
  *result = value;
  return ZX_OK;
}

/// strict enum comment #1.
///
/// strict enum comment #2.
enum class MyStrictEnum : uint32_t {

  /// FOO member comment #1
  ///
  /// FOO member comment #3
  FOO = 1u,

  /// BAR member comment #1
  ///
  /// BAR member comment #3
  BAR = 2u,
};

inline zx_status_t Clone(::test::doccomments::MyStrictEnum value,
                         ::test::doccomments::MyStrictEnum* result) {
  *result = value;
  return ZX_OK;
}

/// flexible enum comment #1.
///
/// flexible enum comment #2.
class MyFlexibleEnum final {
 public:
  constexpr MyFlexibleEnum() : value_(0) {}
  constexpr explicit MyFlexibleEnum(uint32_t value) : value_(value) {}
  constexpr operator uint32_t() const { return value_; }

  constexpr bool IsUnknown() const {
    switch (value_) {
      case 1u:

      case 2u:

        return false;
    }
    return true;
  }

  constexpr static MyFlexibleEnum Unknown() {
    return MyFlexibleEnum(0xffffffff);
  }

  /// FOO member comment #1
  ///
  /// FOO member comment #3
  static const MyFlexibleEnum FOO;

  /// BAR member comment #1
  ///
  /// BAR member comment #3
  static const MyFlexibleEnum BAR;

 private:
  uint32_t value_;
};

#if !(__cplusplus < 201703)
constexpr const ::test::doccomments::MyFlexibleEnum MyFlexibleEnum::FOO = ::test::doccomments::MyFlexibleEnum(1u);
constexpr const ::test::doccomments::MyFlexibleEnum MyFlexibleEnum::BAR = ::test::doccomments::MyFlexibleEnum(2u);
#endif  // !(__cplusplus < 201703)

inline zx_status_t Clone(::test::doccomments::MyFlexibleEnum value,
                         ::test::doccomments::MyFlexibleEnum* result) {
  *result = value;
  return ZX_OK;
}

class Struct;

class StrictUnion;

class FlexibleUnion;

class Table;

#ifdef __Fuchsia__

/// interface comment #1
///
/// interface comment #3
class Interface;
using InterfaceHandle = ::fidl::InterfaceHandle<Interface>;

#endif  // __Fuchsia__

#ifdef __Fuchsia__
class Service;

#endif  // __Fuchsia__

/// const comment #1
///
/// const comment #3
constexpr int32_t C = 4u;

/// struct comment #1
///
/// struct comment #3
class Struct final {
 public:
  static const fidl_type_t* FidlType;

  /// struct member comment #1
  ///
  /// struct member comment #3
  int32_t Field{};

  static inline ::std::unique_ptr<Struct> New() { return ::std::make_unique<Struct>(); }

  void Encode(::fidl::Encoder* _encoder, size_t _offset,
              cpp17::optional<::fidl::HandleInformation> maybe_handle_info = cpp17::nullopt);
  static void Decode(::fidl::Decoder* _decoder, Struct* value, size_t _offset);
  zx_status_t Clone(Struct* result) const;
};

inline zx_status_t Clone(const ::test::doccomments::Struct& _value,
                         ::test::doccomments::Struct* _result) {
  return _value.Clone(_result);
}

using StructPtr = ::std::unique_ptr<Struct>;

/// strict union comment #1
///
/// strict union comment #3
class StrictUnion final {
 public:
  static const fidl_type_t* FidlType;

  StrictUnion();
  ~StrictUnion();

  StrictUnion(StrictUnion&&);
  StrictUnion& operator=(StrictUnion&&);

  static StrictUnion WithField(int32_t&&);

  enum __attribute__((enum_extensibility(closed))) Tag : fidl_xunion_tag_t {

    kField = 1,  // 0x1
    Invalid = ::std::numeric_limits<::fidl_union_tag_t>::max(),
  };

  static inline ::std::unique_ptr<StrictUnion> New() { return ::std::make_unique<StrictUnion>(); }

  void Encode(::fidl::Encoder* encoder, size_t offset,
              cpp17::optional<::fidl::HandleInformation> maybe_handle_info = cpp17::nullopt);
  static void Decode(::fidl::Decoder* _decoder, StrictUnion* value, size_t offset);
  zx_status_t Clone(StrictUnion* result) const;

  bool has_invalid_tag() const {
    return tag_ == Invalid;
  }

  bool is_Field() const { return tag_ == ::test::doccomments::StrictUnion::Tag::kField; }

  /// union member comment #1
  ///
  /// union member comment #3
  int32_t& Field() {
    EnsureStorageInitialized(::test::doccomments::StrictUnion::Tag::kField);
    return Field_;
  }

  /// union member comment #1
  ///
  /// union member comment #3
  const int32_t& Field() const {
    ZX_ASSERT(is_Field());
    return Field_;
  }
  StrictUnion& set_Field(int32_t value);

  ::test::doccomments::StrictUnion::Tag Which() const {
    return ::test::doccomments::StrictUnion::Tag(tag_);
  }

  // You probably want to use Which() method instead of Ordinal(). Use Ordinal() only when you need
  // access to the raw integral ordinal value.
  fidl_xunion_tag_t Ordinal() const {
    return tag_;
  }

  friend ::fidl::Equality<::test::doccomments::StrictUnion>;

 private:
  void Destroy();
  void EnsureStorageInitialized(::fidl_xunion_tag_t tag);

  ::fidl_xunion_tag_t tag_ = static_cast<fidl_xunion_tag_t>(::test::doccomments::StrictUnion::Tag::Invalid);
  union {
    int32_t Field_;
  };
};

inline zx_status_t Clone(const ::test::doccomments::StrictUnion& value,
                         ::test::doccomments::StrictUnion* result) {
  return value.Clone(result);
}

using StrictUnionPtr = ::std::unique_ptr<StrictUnion>;

/// flexible union comment #1
///
/// flexible union comment #3
class FlexibleUnion final {
 public:
  static const fidl_type_t* FidlType;

  FlexibleUnion();
  ~FlexibleUnion();

  FlexibleUnion(FlexibleUnion&&);
  FlexibleUnion& operator=(FlexibleUnion&&);

  static FlexibleUnion WithField(int32_t&&);

  enum __attribute__((enum_extensibility(closed))) Tag : fidl_xunion_tag_t {
    kUnknown = 0,

    kField = 1,  // 0x1
    Invalid = ::std::numeric_limits<::fidl_union_tag_t>::max(),
  };

  static inline ::std::unique_ptr<FlexibleUnion> New() { return ::std::make_unique<FlexibleUnion>(); }

  void Encode(::fidl::Encoder* encoder, size_t offset,
              cpp17::optional<::fidl::HandleInformation> maybe_handle_info = cpp17::nullopt);
  static void Decode(::fidl::Decoder* _decoder, FlexibleUnion* value, size_t offset);
  zx_status_t Clone(FlexibleUnion* result) const;

  bool has_invalid_tag() const {
    return tag_ == Invalid;
  }

  bool is_Field() const { return tag_ == ::test::doccomments::FlexibleUnion::Tag::kField; }

  /// union member comment #1
  ///
  /// union member comment #3
  int32_t& Field() {
    EnsureStorageInitialized(::test::doccomments::FlexibleUnion::Tag::kField);
    return Field_;
  }

  /// union member comment #1
  ///
  /// union member comment #3
  const int32_t& Field() const {
    ZX_ASSERT(is_Field());
    return Field_;
  }
  FlexibleUnion& set_Field(int32_t value);
  FlexibleUnion& SetUnknownData(fidl_xunion_tag_t ordinal, std::vector<uint8_t> bytes);

  ::test::doccomments::FlexibleUnion::Tag Which() const {
    switch (tag_) {
      case ::test::doccomments::FlexibleUnion::Tag::Invalid:
      case ::test::doccomments::FlexibleUnion::Tag::kField:
        return ::test::doccomments::FlexibleUnion::Tag(tag_);
      default:
        return ::test::doccomments::FlexibleUnion::Tag::kUnknown;
    }
  }

  // You probably want to use Which() method instead of Ordinal(). Use Ordinal() only when you need
  // access to the raw integral ordinal value.
  fidl_xunion_tag_t Ordinal() const {
    return tag_;
  }
  const std::vector<uint8_t>* UnknownBytes() const {
    if (Which() != ::test::doccomments::FlexibleUnion::Tag::kUnknown) {
      return nullptr;
    }
    return &unknown_data_;
  }

  friend ::fidl::Equality<::test::doccomments::FlexibleUnion>;

 private:
  void Destroy();
  void EnsureStorageInitialized(::fidl_xunion_tag_t tag);

  ::fidl_xunion_tag_t tag_ = static_cast<fidl_xunion_tag_t>(::test::doccomments::FlexibleUnion::Tag::Invalid);
  union {
    int32_t Field_;
    std::vector<uint8_t> unknown_data_;
  };
};

inline zx_status_t Clone(const ::test::doccomments::FlexibleUnion& value,
                         ::test::doccomments::FlexibleUnion* result) {
  return value.Clone(result);
}

using FlexibleUnionPtr = ::std::unique_ptr<FlexibleUnion>;

/// table comment #1
///
/// table comment #3
class Table final {
 public:
  static const fidl_type_t* FidlType;
  /// Returns whether no field is set.
  bool IsEmpty() const;

  /// table field comment #1
  ///
  /// table field comment #3
  const int32_t& Field() const {
    ZX_ASSERT(field_presence_.IsSet<0>());
    return Field_value_.value;
  }
  bool has_Field() const {
    return field_presence_.IsSet<0>();
  }

  /// table field comment #1
  ///
  /// table field comment #3
  int32_t* mutable_Field() {
    if (!field_presence_.IsSet<0>()) {
      field_presence_.Set<0>();
      Construct(&Field_value_.value);
    }
    return &Field_value_.value;
  }
  Table& set_Field(int32_t _value);
  void clear_Field() {
    if (!field_presence_.IsSet<0>()) {
      return;
    }
    field_presence_.Clear<0>();
    Destruct(&Field_value_.value);
  }

  Table();
  Table(Table&& other);
  ~Table();
  Table& operator=(Table&& other);

  static inline ::std::unique_ptr<Table> New() { return ::std::make_unique<Table>(); }

  void Encode(::fidl::Encoder* _encoder, size_t _offset,
              cpp17::optional<::fidl::HandleInformation> maybe_handle_info = cpp17::nullopt);
  static void Decode(::fidl::Decoder* _decoder, Table* _value, size_t _offset);
  zx_status_t Clone(Table* _result) const;

 private:
  template <class T, class... Args>
  void Construct(T* p, Args&&... args) {
    new (p) T(std::forward<Args>(args)...);
  }

  template <class T>
  void Destruct(T* p) {
    p->~T();
  }

  size_t MaxOrdinal() const {
    return static_cast<size_t>(field_presence_.MaxSetIndex()) + std::size_t{1};
  }

  static bool IsOrdinalKnown(uint64_t ordinal) {
    switch (ordinal) {
      case 1:
        return true;
      default:
        return false;
    }
  }

  ::fidl::internal::BitSet<1> field_presence_;
  union ValueUnion_Field {
    ValueUnion_Field() {}
    ~ValueUnion_Field() {}

    int32_t value;
  };
  ValueUnion_Field Field_value_;
};

using TablePtr = ::std::unique_ptr<Table>;

#ifdef __Fuchsia__

class Interface_RequestEncoder {
 public:
  static ::fidl::HLCPPOutgoingMessage Method(::fidl::MessageEncoder* _encoder) {
    return _encoder->GetMessage();
  }
};

class Interface_ResponseEncoder {
 public:
  static ::fidl::HLCPPOutgoingMessage OnEvent(::fidl::MessageEncoder* _encoder) {
    return _encoder->GetMessage();
  }
};

#endif  // __Fuchsia__

}  // namespace doccomments
}  // namespace test
namespace fidl {

template <>
struct CodingTraits<::test::doccomments::MyStrictBits> {
  static constexpr size_t kInlineSize = sizeof(::test::doccomments::MyStrictBits);
  static void Encode(Encoder* encoder, ::test::doccomments::MyStrictBits* value, size_t offset,
                     cpp17::optional<::fidl::HandleInformation> maybe_handle_info) {
    ZX_DEBUG_ASSERT(!maybe_handle_info);
    uint32_t underlying = static_cast<uint32_t>(*value);
    ::fidl::Encode(encoder, &underlying, offset);
  }
  static void Decode(Decoder* decoder, ::test::doccomments::MyStrictBits* value, size_t offset) {
    uint32_t underlying = {};
    ::fidl::Decode(decoder, &underlying, offset);
    *value = static_cast<::test::doccomments::MyStrictBits>(underlying);
  }
};

inline zx_status_t Clone(::test::doccomments::MyStrictBits value,
                         ::test::doccomments::MyStrictBits* result) {
  return ::test::doccomments::Clone(value, result);
}

template <>
struct Equality<::test::doccomments::MyStrictBits> {
  bool operator()(const ::test::doccomments::MyStrictBits& _lhs, const ::test::doccomments::MyStrictBits& _rhs) const {
    uint32_t _lhs_underlying = static_cast<uint32_t>(_lhs);
    uint32_t _rhs_underlying = static_cast<uint32_t>(_rhs);
    return ::fidl::Equals(_lhs_underlying, _rhs_underlying);
  }
};
template <>
struct CodingTraits<::test::doccomments::MyFlexibleBits> {
  static constexpr size_t kInlineSize = sizeof(::test::doccomments::MyFlexibleBits);
  static void Encode(Encoder* encoder, ::test::doccomments::MyFlexibleBits* value, size_t offset,
                     cpp17::optional<::fidl::HandleInformation> maybe_handle_info) {
    ZX_DEBUG_ASSERT(!maybe_handle_info);
    uint32_t underlying = static_cast<uint32_t>(*value);
    ::fidl::Encode(encoder, &underlying, offset);
  }
  static void Decode(Decoder* decoder, ::test::doccomments::MyFlexibleBits* value, size_t offset) {
    uint32_t underlying = {};
    ::fidl::Decode(decoder, &underlying, offset);
    *value = static_cast<::test::doccomments::MyFlexibleBits>(underlying);
  }
};

inline zx_status_t Clone(::test::doccomments::MyFlexibleBits value,
                         ::test::doccomments::MyFlexibleBits* result) {
  return ::test::doccomments::Clone(value, result);
}

template <>
struct Equality<::test::doccomments::MyFlexibleBits> {
  bool operator()(const ::test::doccomments::MyFlexibleBits& _lhs, const ::test::doccomments::MyFlexibleBits& _rhs) const {
    uint32_t _lhs_underlying = static_cast<uint32_t>(_lhs);
    uint32_t _rhs_underlying = static_cast<uint32_t>(_rhs);
    return ::fidl::Equals(_lhs_underlying, _rhs_underlying);
  }
};
template <>
struct CodingTraits<::test::doccomments::MyStrictEnum> {
  static constexpr size_t kInlineSize = sizeof(::test::doccomments::MyStrictEnum);
  static void Encode(Encoder* encoder, ::test::doccomments::MyStrictEnum* value, size_t offset,
                     cpp17::optional<::fidl::HandleInformation> maybe_handle_info) {
    ZX_DEBUG_ASSERT(!maybe_handle_info);
    uint32_t underlying = static_cast<uint32_t>(*value);
    ::fidl::Encode(encoder, &underlying, offset);
  }
  static void Decode(Decoder* decoder, ::test::doccomments::MyStrictEnum* value, size_t offset) {
    uint32_t underlying = {};
    ::fidl::Decode(decoder, &underlying, offset);
    *value = static_cast<::test::doccomments::MyStrictEnum>(underlying);
  }
};

inline zx_status_t Clone(::test::doccomments::MyStrictEnum value,
                         ::test::doccomments::MyStrictEnum* result) {
  return ::test::doccomments::Clone(value, result);
}
template <>
struct Equality<::test::doccomments::MyStrictEnum> {
  bool operator()(const ::test::doccomments::MyStrictEnum& _lhs, const ::test::doccomments::MyStrictEnum& _rhs) const {
    return _lhs == _rhs;
  }
};

template <>
struct CodingTraits<::test::doccomments::MyFlexibleEnum> {
  static constexpr size_t kInlineSize = sizeof(::test::doccomments::MyFlexibleEnum);
  static void Encode(Encoder* encoder, ::test::doccomments::MyFlexibleEnum* value, size_t offset,
                     cpp17::optional<::fidl::HandleInformation> maybe_handle_info) {
    ZX_DEBUG_ASSERT(!maybe_handle_info);
    uint32_t underlying = static_cast<uint32_t>(*value);
    ::fidl::Encode(encoder, &underlying, offset);
  }
  static void Decode(Decoder* decoder, ::test::doccomments::MyFlexibleEnum* value, size_t offset) {
    uint32_t underlying = {};
    ::fidl::Decode(decoder, &underlying, offset);
    *value = static_cast<::test::doccomments::MyFlexibleEnum>(underlying);
  }
};

inline zx_status_t Clone(::test::doccomments::MyFlexibleEnum value,
                         ::test::doccomments::MyFlexibleEnum* result) {
  return ::test::doccomments::Clone(value, result);
}
template <>
struct Equality<::test::doccomments::MyFlexibleEnum> {
  bool operator()(const ::test::doccomments::MyFlexibleEnum& _lhs, const ::test::doccomments::MyFlexibleEnum& _rhs) const {
    return _lhs == _rhs;
  }
};

template <>
struct CodingTraits<::test::doccomments::Struct>
    : public EncodableCodingTraits<::test::doccomments::Struct, 4> {};

template <>
struct IsMemcpyCompatible<::test::doccomments::Struct> : public internal::BoolConstant<
                                                             !HasPadding<::test::doccomments::Struct>::value && IsMemcpyCompatible<int32_t>::value> {};

inline zx_status_t Clone(const ::test::doccomments::Struct& value,
                         ::test::doccomments::Struct* result) {
  return ::test::doccomments::Clone(value, result);
}

template <>
struct Equality<::test::doccomments::Struct> {
  bool operator()(const ::test::doccomments::Struct& _lhs, const ::test::doccomments::Struct& _rhs) const {
    if (!::fidl::Equals(_lhs.Field, _rhs.Field)) {
      return false;
    }
    return true;
  }
};
template <>
struct IsFidlXUnion<::test::doccomments::StrictUnion> : public std::true_type{};

template <>
struct CodingTraits<::test::doccomments::StrictUnion>
    : public EncodableCodingTraits<::test::doccomments::StrictUnion, 16> {};

template <>
struct CodingTraits<std::unique_ptr<::test::doccomments::StrictUnion>> {
  static constexpr size_t kInlineSize = 16;

  static void Encode(Encoder* encoder, std::unique_ptr<::test::doccomments::StrictUnion>* value, size_t offset,
                     cpp17::optional<::fidl::HandleInformation> maybe_handle_info = cpp17::nullopt) {
    auto&& p_xunion = *value;
    if (p_xunion) {
      p_xunion->Encode(encoder, offset);
    }
  }

  static void Decode(Decoder* _decoder, std::unique_ptr<::test::doccomments::StrictUnion>* value, size_t offset) {
    fidl_union_t* encoded = _decoder->GetPtr<fidl_union_t>(offset);
    if (encoded->tag == 0) {
      value->reset(nullptr);
      return;
    }

    value->reset(new ::test::doccomments::StrictUnion);

    ::test::doccomments::StrictUnion::Decode(_decoder, value->get(), offset);
  }
};

inline zx_status_t Clone(const ::test::doccomments::StrictUnion& value,
                         ::test::doccomments::StrictUnion* result) {
  return ::test::doccomments::Clone(value, result);
}

template <>
struct Equality<::test::doccomments::StrictUnion> {
  bool operator()(const ::test::doccomments::StrictUnion& _lhs, const ::test::doccomments::StrictUnion& _rhs) const {
    if (_lhs.Ordinal() != _rhs.Ordinal()) {
      return false;
    }

    switch (_lhs.Ordinal()) {
      case static_cast<fidl_xunion_tag_t>(::test::doccomments::StrictUnion::Tag::Invalid):
        return true;
      case ::test::doccomments::StrictUnion::Tag::kField:
        return ::fidl::Equals(_lhs.Field_, _rhs.Field_);

      default:
        return false;
    }
  }
};
template <>
struct IsFidlXUnion<::test::doccomments::FlexibleUnion> : public std::true_type{};

template <>
struct CodingTraits<::test::doccomments::FlexibleUnion>
    : public EncodableCodingTraits<::test::doccomments::FlexibleUnion, 16> {};

template <>
struct CodingTraits<std::unique_ptr<::test::doccomments::FlexibleUnion>> {
  static constexpr size_t kInlineSize = 16;

  static void Encode(Encoder* encoder, std::unique_ptr<::test::doccomments::FlexibleUnion>* value, size_t offset,
                     cpp17::optional<::fidl::HandleInformation> maybe_handle_info = cpp17::nullopt) {
    auto&& p_xunion = *value;
    if (p_xunion) {
      p_xunion->Encode(encoder, offset);
    }
  }

  static void Decode(Decoder* _decoder, std::unique_ptr<::test::doccomments::FlexibleUnion>* value, size_t offset) {
    fidl_union_t* encoded = _decoder->GetPtr<fidl_union_t>(offset);
    if (encoded->tag == 0) {
      value->reset(nullptr);
      return;
    }

    value->reset(new ::test::doccomments::FlexibleUnion);

    ::test::doccomments::FlexibleUnion::Decode(_decoder, value->get(), offset);
  }
};

inline zx_status_t Clone(const ::test::doccomments::FlexibleUnion& value,
                         ::test::doccomments::FlexibleUnion* result) {
  return ::test::doccomments::Clone(value, result);
}

template <>
struct Equality<::test::doccomments::FlexibleUnion> {
  bool operator()(const ::test::doccomments::FlexibleUnion& _lhs, const ::test::doccomments::FlexibleUnion& _rhs) const {
    if (_lhs.Ordinal() != _rhs.Ordinal()) {
      return false;
    }

    switch (_lhs.Ordinal()) {
      case static_cast<fidl_xunion_tag_t>(::test::doccomments::FlexibleUnion::Tag::Invalid):
        return true;
      case ::test::doccomments::FlexibleUnion::Tag::kField:
        return ::fidl::Equals(_lhs.Field_, _rhs.Field_);
      default:
        return ::fidl::Equals(_lhs.unknown_data_, _rhs.unknown_data_);
    }
  }
};
template <>
struct CodingTraits<::test::doccomments::Table>
    : public EncodableCodingTraits<::test::doccomments::Table, 16> {};

inline zx_status_t Clone(const ::test::doccomments::Table& _value,
                         ::test::doccomments::Table* result) {
  return _value.Clone(result);
}
template <>
struct Equality<::test::doccomments::Table> {
  bool operator()(const ::test::doccomments::Table& _lhs, const ::test::doccomments::Table& _rhs) const {
    if (_lhs.has_Field()) {
      if (!_rhs.has_Field()) {
        return false;
      }
      if (!::fidl::Equals(_lhs.Field(), _rhs.Field())) {
        return false;
      }
    } else if (_rhs.has_Field()) {
      return false;
    }
    return true;
  }
};

//
// Proxies and stubs declarations
//
}  // namespace fidl
namespace test {
namespace doccomments {

#ifdef __Fuchsia__

/// interface comment #1
///
/// interface comment #3
using InterfacePtr = ::fidl::InterfacePtr<Interface>;
class Interface_Proxy;
class Interface_Stub;
class Interface_EventSender;
class Interface_Sync;
using InterfaceSyncPtr = ::fidl::SynchronousInterfacePtr<Interface>;
class Interface_SyncProxy;

namespace internal {

constexpr uint64_t kInterface_Method_Ordinal = 0x45a0257b7cd8f999lu;

constexpr ::fidl::MessageDynamicFlags kInterface_Method_DynamicFlags = ::fidl::MessageDynamicFlags::kStrictMethod;

constexpr uint64_t kInterface_OnEvent_Ordinal = 0x663f6d5971bef0lu;

constexpr ::fidl::MessageDynamicFlags kInterface_OnEvent_DynamicFlags = ::fidl::MessageDynamicFlags::kStrictMethod;
}  // namespace internal

#endif  // __Fuchsia__

#ifdef __Fuchsia__
class Service;

#endif  // __Fuchsia__

#ifdef __Fuchsia__

/// interface comment #1
///
/// interface comment #3
class Interface {
 public:
  using Proxy_ = ::test::doccomments::Interface_Proxy;
  using Stub_ = ::test::doccomments::Interface_Stub;
  using EventSender_ = ::test::doccomments::Interface_EventSender;
  using Sync_ = ::test::doccomments::Interface_Sync;
  virtual ~Interface();

  /// method comment #1
  ///
  /// method comment #3
  virtual void Method() = 0;
  using OnEventCallback =
      fit::function<void()>;
};

class Interface_RequestDecoder {
 public:
  Interface_RequestDecoder() = default;
  virtual ~Interface_RequestDecoder() = default;
  static const fidl_type_t* GetType(uint64_t ordinal, bool* out_needs_response, bool* is_known);
  virtual void Method() = 0;
};

class Interface_ResponseDecoder {
 public:
  Interface_ResponseDecoder() = default;
  virtual ~Interface_ResponseDecoder() = default;
  static const fidl_type_t* GetType(uint64_t ordinal);
  virtual void OnEvent() = 0;
};

class Interface_EventSender {
 public:
  virtual ~Interface_EventSender();
  virtual void OnEvent() = 0;
};

class Interface_Sync {
 public:
  using Proxy_ = ::test::doccomments::Interface_SyncProxy;
  virtual ~Interface_Sync();
  virtual zx_status_t Method() = 0;
};

class Interface_Proxy final : public ::fidl::internal::Proxy, public Interface {
 public:
  explicit Interface_Proxy(::fidl::internal::ProxyController* controller);
  ~Interface_Proxy() override;

  zx_status_t Dispatch_(::fidl::HLCPPIncomingMessage message) override;
  // cts-coverage-fidl-name:test.doccomments/Interface.Method
  void Method() override;
  OnEventCallback OnEvent;

 private:
  Interface_Proxy(const ::test::doccomments::Interface_Proxy&) = delete;
  Interface_Proxy& operator=(const ::test::doccomments::Interface_Proxy&) = delete;

  ::fidl::internal::ProxyController* controller_;
};

class Interface_Stub final : public ::fidl::internal::Stub, public ::test::doccomments::Interface_EventSender {
 public:
  typedef class ::test::doccomments::Interface Interface_clazz;
  explicit Interface_Stub(::test::doccomments::Interface_Stub::Interface_clazz* impl);
  ~Interface_Stub() override;

  zx_status_t Dispatch_(::fidl::HLCPPIncomingMessage message,
                        ::fidl::internal::PendingResponse response) override;
  void OnEvent() override;

 private:
  ::test::doccomments::Interface_Stub::Interface_clazz* impl_;
};

class Interface_SyncProxy : public ::test::doccomments::Interface_Sync {
 public:
  explicit Interface_SyncProxy(::zx::channel channel);
  ~Interface_SyncProxy() override;
  // cts-coverage-fidl-name:test.doccomments/Interface.Method
  zx_status_t Method() override;

 private:
  ::fidl::internal::SynchronousProxy proxy_;
  friend class ::fidl::SynchronousInterfacePtr<Interface>;
};

#endif  // __Fuchsia__

#ifdef __Fuchsia__

/// service comment #1
///
/// service comment #3
class Service final {
 public:
  class Handler;

  static constexpr char Name[] = "test.doccomments.Service";

  explicit Service(std::unique_ptr<::fidl::ServiceConnector> service)
      : service_(std::move(service)) {}

  explicit operator bool() const { return !!service_; }
  /// Returns a |fidl::MemberConnector| which can be used to connect to the member protocol "interface".
  ::fidl::MemberConnector<::test::doccomments::Interface> interface() const {
    return ::fidl::MemberConnector<::test::doccomments::Interface>(service_.get(), "interface");
  }

 private:
  std::unique_ptr<::fidl::ServiceConnector> service_;
};

/// Facilitates member protocol registration for servers.
class Service::Handler final {
 public:
  /// Constructs a new |Handler|. Does not take ownership of |service|.
  explicit Handler(::fidl::ServiceHandlerBase* service)
      : service_(service) {}
  /// Adds member "interface" to the service instance. |handler| is invoked when a connection
  /// is made to the member protocol.
  ///
  /// # Errors
  ///
  /// Returns ZX_ERR_ALREADY_EXISTS if the member was already added.
  zx_status_t add_interface(::fidl::InterfaceRequestHandler<::test::doccomments::Interface> handler) {
    return service_->AddMember("interface", std::move(handler));
  }

 private:
  ::fidl::ServiceHandlerBase* const service_;
};

#endif  // __Fuchsia__

}  // namespace doccomments
}  // namespace test
