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

// fidl_experiment = output_index_json

#pragma once

#include <fidl/test.anonymous/cpp/common_types.h>
#include <fidl/test.anonymous/cpp/markers.h>
#include <lib/fidl/cpp/natural_coding_traits.h>
#include <lib/fidl/cpp/natural_types.h>

#include <cinttypes>
#include <string>

#ifdef __Fuchsia__

#include <lib/zx/channel.h>

#endif  // __Fuchsia__

#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wshadow"

namespace test_anonymous {

class OverrideTest;

class TableData;

class SomeProtocolSomeMethodRequest;

class SomeProtocolSomeMethodResponse;

class FunctionApplication;

class TableMember;

class Expression;

class UnionMember;

class SomeProtocolSomeMethodResult;

class OverrideTest {
 private:
  struct Storage_;

 public:
  OverrideTest(Storage_ storage) noexcept;
  OverrideTest(::test_anonymous::Op op, ::fidl::Box<::test_anonymous::Expression> left, ::fidl::Box<::test_anonymous::Expression> right) noexcept;

#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdefaulted-function-deleted"
  // Default constructs a |OverrideTest| only if all of its members are default constructible.
  OverrideTest() = default;
#pragma clang diagnostic pop

  OverrideTest(OverrideTest&&) noexcept = default;
  OverrideTest& operator=(OverrideTest&&) noexcept = default;
  OverrideTest(const OverrideTest& other) noexcept;
  OverrideTest& operator=(const OverrideTest& other) noexcept;

  bool operator==(const OverrideTest& other) const noexcept {
    return ::fidl::internal::NaturalStructCodingTraits<::test_anonymous::OverrideTest, 40>::Equal(this, &other);
  }
  bool operator!=(const OverrideTest& other) const noexcept {
    return !::fidl::internal::NaturalStructCodingTraits<::test_anonymous::OverrideTest, 40>::Equal(this, &other);
  }

  ::test_anonymous::Op
  op() const {
    return storage_.op;
  }

  ::test_anonymous::Op& op() {
    return storage_.op;
  }

  // Setter for op.
  //

  OverrideTest& op(::test_anonymous::Op value);

  const ::fidl::Box<::test_anonymous::Expression>&
  left() const {
    return storage_.left;
  }

  ::fidl::Box<::test_anonymous::Expression>& left() {
    return storage_.left;
  }

  // Setter for left.
  //

  OverrideTest& left(::fidl::Box<::test_anonymous::Expression> value);

  const ::fidl::Box<::test_anonymous::Expression>&
  right() const {
    return storage_.right;
  }

  ::fidl::Box<::test_anonymous::Expression>& right() {
    return storage_.right;
  }

  // Setter for right.
  //

  OverrideTest& right(::fidl::Box<::test_anonymous::Expression> value);

  OverrideTest(::fidl::internal::DefaultConstructPossiblyInvalidObjectTag);

 private:
  struct Storage_ final {
    ::test_anonymous::Op op = {};
    ::fidl::Box<::test_anonymous::Expression> left;
    ::fidl::Box<::test_anonymous::Expression> right;
  };

  Storage_ storage_;
  Storage_ CloneStorage_() const;

  friend struct ::fidl::internal::NaturalStructCodingTraits<::test_anonymous::OverrideTest, 40>;
  friend struct ::fidl::internal::MemberVisitor<::test_anonymous::OverrideTest>;
  static constexpr auto kMembers = std::make_tuple(::fidl::internal::NaturalStructMember<Storage_, ::test_anonymous::Op, fidl::internal::NaturalCodingConstraintEmpty>{
                                                       &Storage_::op, 0},
                                                   ::fidl::internal::NaturalStructMember<Storage_, ::fidl::Box<::test_anonymous::Expression>, fidl::internal::NaturalCodingConstraintEmpty>{&Storage_::left, 8}, ::fidl::internal::NaturalStructMember<Storage_, ::fidl::Box<::test_anonymous::Expression>, fidl::internal::NaturalCodingConstraintEmpty>{&Storage_::right, 24});
  static constexpr auto kPadding = std::make_tuple(::fidl::internal::NaturalStructPadding<uint64_t>{
      .offset = 0,
      .mask = 0xffffffff00000000,
  });
};

class FunctionApplication {
 private:
  struct Storage_;

 public:
  FunctionApplication(Storage_ storage) noexcept;
  FunctionApplication() noexcept = default;
  FunctionApplication(FunctionApplication&&) noexcept = default;
  FunctionApplication& operator=(FunctionApplication&&) noexcept = default;
  FunctionApplication(const FunctionApplication& other) noexcept;
  FunctionApplication& operator=(const FunctionApplication& other) noexcept;
  bool operator==(const FunctionApplication& other) const noexcept {
    return ::fidl::internal::NaturalTableCodingTraits<::test_anonymous::FunctionApplication>::Equal(this, &other);
  }
  bool operator!=(const FunctionApplication& other) const noexcept {
    return !::fidl::internal::NaturalTableCodingTraits<::test_anonymous::FunctionApplication>::Equal(this, &other);
  }

  bool IsEmpty() const {
    return !(storage_.func.has_value() || storage_.args.has_value() || storage_.flags.has_value());
  }

  const std::optional<::std::string>& func() const { return storage_.func; }
  ::std::optional<::std::string>& func() { return storage_.func; }

  // Setter for func.
  //

  FunctionApplication& func(std::optional<::std::string> value);

  const std::optional<::std::vector<::fidl::Box<::test_anonymous::Expression>>>& args() const { return storage_.args; }
  ::std::optional<::std::vector<::fidl::Box<::test_anonymous::Expression>>>& args() { return storage_.args; }

  // Setter for args.
  //

  FunctionApplication& args(std::optional<::std::vector<::fidl::Box<::test_anonymous::Expression>>> value);

  const std::optional<::test_anonymous::Flags>& flags() const { return storage_.flags; }
  ::std::optional<::test_anonymous::Flags>& flags() { return storage_.flags; }

  // Setter for flags.
  //

  FunctionApplication& flags(std::optional<::test_anonymous::Flags> value);

  FunctionApplication(::fidl::internal::DefaultConstructPossiblyInvalidObjectTag);

 private:
  struct Storage_ final {
    ::std::optional<::std::string> func;
    ::std::optional<::std::vector<::fidl::Box<::test_anonymous::Expression>>> args;
    ::std::optional<::test_anonymous::Flags> flags;
  };

  // TODO(https://fxbug.dev/42172795): Box the storage.
  Storage_ storage_;
  Storage_ CloneStorage_() const;
  friend struct ::fidl::internal::NaturalTableCodingTraits<::test_anonymous::FunctionApplication>;
  friend struct ::fidl::internal::MemberVisitor<::test_anonymous::FunctionApplication>;
  static constexpr auto kMembers = std::make_tuple(::fidl::internal::NaturalTableMember<Storage_, ::std::string, fidl::internal::NaturalCodingConstraintString<100>>{
                                                       1, &Storage_::func},
                                                   ::fidl::internal::NaturalTableMember<Storage_, ::std::vector<::fidl::Box<::test_anonymous::Expression>>, fidl::internal::NaturalCodingConstraintVector<fidl::internal::NaturalCodingConstraintEmpty, 5>>{3, &Storage_::args}, ::fidl::internal::NaturalTableMember<Storage_, ::test_anonymous::Flags, fidl::internal::NaturalCodingConstraintEmpty>{4, &Storage_::flags});
};

class Expression {
 private:
  using Storage_ =
      std::variant<
          std::monostate, uint64_t, ::test_anonymous::OverrideTest, ::test_anonymous::FunctionApplication>;

 public:
  // TODO: share union tag types between wire & natural.
  enum class Tag : fidl_xunion_tag_t {
    kValue = 1,                // 0x1
    kBinOp = 2,                // 0x2
    kFunctionApplication = 3,  // 0x3
    _do_not_handle_this__write_a_default_case_instead = ::std::numeric_limits<::fidl_union_tag_t>::max(),
  };

  Expression(Expression&& other) noexcept
      : Expression(::fidl::internal::DefaultConstructPossiblyInvalidObjectTag{}) {
    *storage_ = std::move(*other.storage_);
  }
  Expression& operator=(Expression&& other) noexcept {
    if (this != &other) {
      *storage_ = std::move(*other.storage_);
    }
    return *this;
  }
  Expression(const Expression& other) noexcept : Expression(other.CloneStorage_()) {}
  Expression& operator=(const Expression& other) noexcept {
    if (this != &other) {
      storage_ = other.CloneStorage_();
    }
    return *this;
  }

  bool operator==(const Expression& other) const noexcept {
    return *storage_ == *other.storage_;
  }
  bool operator!=(const Expression& other) const noexcept {
    return *storage_ != *other.storage_;
  }
  constexpr bool IsUnknown() const {
    return Which() == ::test_anonymous::Expression::Tag::_do_not_handle_this__write_a_default_case_instead;
  }

  constexpr ::test_anonymous::Expression::Tag Which() const {
    return Expression::IndexToTag(storage_->index()).value();
  }
  static Expression WithValue(uint64_t val) {
    return Expression(std::make_shared<Storage_>(
        std::in_place_index_t<1>{},
        std::move(val)));
  }

  const ::fidl::internal::UnionMemberView<1, Storage_> value() const {
    return ::fidl::internal::UnionMemberView<1, Storage_>(storage_);
  }

  ::fidl::internal::UnionMemberView<1, Storage_> value() {
    return ::fidl::internal::UnionMemberView<1, Storage_>(storage_);
  }

  // Sets the union to hold the value member.
  //

  Expression& value(uint64_t value) {
    storage_->emplace<1>(std::move(value));
    return *this;
  }
  static Expression WithBinOp(::test_anonymous::OverrideTest val) {
    return Expression(std::make_shared<Storage_>(
        std::in_place_index_t<2>{},
        std::move(val)));
  }

  const ::fidl::internal::UnionMemberView<2, Storage_> bin_op() const {
    return ::fidl::internal::UnionMemberView<2, Storage_>(storage_);
  }

  ::fidl::internal::UnionMemberView<2, Storage_> bin_op() {
    return ::fidl::internal::UnionMemberView<2, Storage_>(storage_);
  }

  // Sets the union to hold the bin_op member.
  //

  Expression& bin_op(::test_anonymous::OverrideTest value) {
    storage_->emplace<2>(std::move(value));
    return *this;
  }
  static Expression WithFunctionApplication(::test_anonymous::FunctionApplication val) {
    return Expression(std::make_shared<Storage_>(
        std::in_place_index_t<3>{},
        std::move(val)));
  }

  const ::fidl::internal::UnionMemberView<3, Storage_> function_application() const {
    return ::fidl::internal::UnionMemberView<3, Storage_>(storage_);
  }

  ::fidl::internal::UnionMemberView<3, Storage_> function_application() {
    return ::fidl::internal::UnionMemberView<3, Storage_>(storage_);
  }

  // Sets the union to hold the function_application member.
  //

  Expression& function_application(::test_anonymous::FunctionApplication value) {
    storage_->emplace<3>(std::move(value));
    return *this;
  }

  Expression(::fidl::internal::DefaultConstructPossiblyInvalidObjectTag)
      : storage_(std::make_shared<Storage_>()) {}

 private:
  std::shared_ptr<Storage_> storage_;
  std::shared_ptr<Storage_> CloneStorage_() const;
  friend struct ::fidl::internal::NaturalUnionCodingTraits<::test_anonymous::Expression>;
  static constexpr auto kMembers = std::make_tuple(
      ::fidl::internal::NaturalUnionMember<::fidl::internal::NaturalCodingConstraintEmpty>(), ::fidl::internal::NaturalUnionMember<fidl::internal::NaturalCodingConstraintEmpty>(), ::fidl::internal::NaturalUnionMember<fidl::internal::NaturalCodingConstraintEmpty>(), ::fidl::internal::NaturalUnionMember<fidl::internal::NaturalCodingConstraintEmpty>());

  explicit Expression(std::shared_ptr<Storage_> storage) : storage_(std::move(storage)) {}

  static constexpr size_t TagToIndex(::fidl::internal::NaturalDecoder* decoder, ::test_anonymous::Expression::Tag tag) {
    switch (tag) {
      case ::test_anonymous::Expression::Tag::kValue:
        return 1;
      case ::test_anonymous::Expression::Tag::kBinOp:
        return 2;
      case ::test_anonymous::Expression::Tag::kFunctionApplication:
        return 3;
      default: {
        return 0;
      }
    }
  }

  static constexpr std::optional<::test_anonymous::Expression::Tag> IndexToTag(size_t index) {
    switch (index) {
      case 1:
        return ::test_anonymous::Expression::Tag::kValue;
      case 2:
        return ::test_anonymous::Expression::Tag::kBinOp;
      case 3:
        return ::test_anonymous::Expression::Tag::kFunctionApplication;
      default:
        return ::test_anonymous::Expression::Tag::_do_not_handle_this__write_a_default_case_instead;
    }
  }
};

class UnionMember {
 private:
  using Storage_ =
      std::variant<
          std::monostate, uint8_t>;

 public:
  // TODO: share union tag types between wire & natural.
  enum class Tag : fidl_xunion_tag_t {
    kUnionData = 2,  // 0x2
    _do_not_handle_this__write_a_default_case_instead = ::std::numeric_limits<::fidl_union_tag_t>::max(),
  };

  UnionMember(UnionMember&& other) noexcept
      : UnionMember(::fidl::internal::DefaultConstructPossiblyInvalidObjectTag{}) {
    *storage_ = std::move(*other.storage_);
  }
  UnionMember& operator=(UnionMember&& other) noexcept {
    if (this != &other) {
      *storage_ = std::move(*other.storage_);
    }
    return *this;
  }
  UnionMember(const UnionMember& other) noexcept : UnionMember(other.CloneStorage_()) {}
  UnionMember& operator=(const UnionMember& other) noexcept {
    if (this != &other) {
      storage_ = other.CloneStorage_();
    }
    return *this;
  }

  bool operator==(const UnionMember& other) const noexcept {
    return *storage_ == *other.storage_;
  }
  bool operator!=(const UnionMember& other) const noexcept {
    return *storage_ != *other.storage_;
  }
  constexpr bool IsUnknown() const {
    return Which() == ::test_anonymous::UnionMember::Tag::_do_not_handle_this__write_a_default_case_instead;
  }

  constexpr ::test_anonymous::UnionMember::Tag Which() const {
    return UnionMember::IndexToTag(storage_->index()).value();
  }
  static UnionMember WithUnionData(uint8_t val) {
    return UnionMember(std::make_shared<Storage_>(
        std::in_place_index_t<1>{},
        std::move(val)));
  }

  const ::fidl::internal::UnionMemberView<1, Storage_> union_data() const {
    return ::fidl::internal::UnionMemberView<1, Storage_>(storage_);
  }

  ::fidl::internal::UnionMemberView<1, Storage_> union_data() {
    return ::fidl::internal::UnionMemberView<1, Storage_>(storage_);
  }

  // Sets the union to hold the union_data member.
  //

  UnionMember& union_data(uint8_t value) {
    storage_->emplace<1>(std::move(value));
    return *this;
  }

  UnionMember(::fidl::internal::DefaultConstructPossiblyInvalidObjectTag)
      : storage_(std::make_shared<Storage_>()) {}

 private:
  std::shared_ptr<Storage_> storage_;
  std::shared_ptr<Storage_> CloneStorage_() const;
  friend struct ::fidl::internal::NaturalUnionCodingTraits<::test_anonymous::UnionMember>;
  static constexpr auto kMembers = std::make_tuple(
      ::fidl::internal::NaturalUnionMember<::fidl::internal::NaturalCodingConstraintEmpty>(), ::fidl::internal::NaturalUnionMember<fidl::internal::NaturalCodingConstraintEmpty>());

  explicit UnionMember(std::shared_ptr<Storage_> storage) : storage_(std::move(storage)) {}

  static constexpr size_t TagToIndex(::fidl::internal::NaturalDecoder* decoder, ::test_anonymous::UnionMember::Tag tag) {
    switch (tag) {
      case ::test_anonymous::UnionMember::Tag::kUnionData:
        return 1;
      default: {
        return 0;
      }
    }
  }

  static constexpr std::optional<::test_anonymous::UnionMember::Tag> IndexToTag(size_t index) {
    switch (index) {
      case 1:
        return ::test_anonymous::UnionMember::Tag::kUnionData;
      default:
        return ::test_anonymous::UnionMember::Tag::_do_not_handle_this__write_a_default_case_instead;
    }
  }
};

class TableData {
 private:
  struct Storage_;

 public:
  TableData(Storage_ storage) noexcept;
  TableData(uint8_t data) noexcept;

#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdefaulted-function-deleted"
  // Default constructs a |TableData| only if all of its members are default constructible.
  TableData() = default;
#pragma clang diagnostic pop

  TableData(TableData&&) noexcept = default;
  TableData& operator=(TableData&&) noexcept = default;
  TableData(const TableData& other) noexcept;
  TableData& operator=(const TableData& other) noexcept;

  bool operator==(const TableData& other) const noexcept {
    return ::fidl::internal::NaturalStructCodingTraits<::test_anonymous::TableData, 1>::Equal(this, &other);
  }
  bool operator!=(const TableData& other) const noexcept {
    return !::fidl::internal::NaturalStructCodingTraits<::test_anonymous::TableData, 1>::Equal(this, &other);
  }

  uint8_t
  data() const {
    return storage_.data;
  }

  uint8_t& data() {
    return storage_.data;
  }

  // Setter for data.
  //

  TableData& data(uint8_t value);

  TableData(::fidl::internal::DefaultConstructPossiblyInvalidObjectTag);

 private:
  struct Storage_ final {
    uint8_t data = {};
  };

  Storage_ storage_;
  Storage_ CloneStorage_() const;

  friend struct ::fidl::internal::NaturalStructCodingTraits<::test_anonymous::TableData, 1>;
  friend struct ::fidl::internal::MemberVisitor<::test_anonymous::TableData>;
  static constexpr auto kMembers = std::make_tuple(::fidl::internal::NaturalStructMember<Storage_, uint8_t, fidl::internal::NaturalCodingConstraintEmpty>{
      &Storage_::data, 0});
  static constexpr auto kPadding = std::make_tuple();
};

class TableMember {
 private:
  struct Storage_;

 public:
  TableMember(Storage_ storage) noexcept;
  TableMember() noexcept = default;
  TableMember(TableMember&&) noexcept = default;
  TableMember& operator=(TableMember&&) noexcept = default;
  TableMember(const TableMember& other) noexcept;
  TableMember& operator=(const TableMember& other) noexcept;
  bool operator==(const TableMember& other) const noexcept {
    return ::fidl::internal::NaturalTableCodingTraits<::test_anonymous::TableMember>::Equal(this, &other);
  }
  bool operator!=(const TableMember& other) const noexcept {
    return !::fidl::internal::NaturalTableCodingTraits<::test_anonymous::TableMember>::Equal(this, &other);
  }

  bool IsEmpty() const {
    return !(storage_.table_data.has_value());
  }

  const std::optional<::std::vector<::test_anonymous::TableData>>& table_data() const { return storage_.table_data; }
  ::std::optional<::std::vector<::test_anonymous::TableData>>& table_data() { return storage_.table_data; }

  // Setter for table_data.
  //

  TableMember& table_data(std::optional<::std::vector<::test_anonymous::TableData>> value);

  TableMember(::fidl::internal::DefaultConstructPossiblyInvalidObjectTag);

 private:
  struct Storage_ final {
    ::std::optional<::std::vector<::test_anonymous::TableData>> table_data;
  };

  // TODO(https://fxbug.dev/42172795): Box the storage.
  Storage_ storage_;
  Storage_ CloneStorage_() const;
  friend struct ::fidl::internal::NaturalTableCodingTraits<::test_anonymous::TableMember>;
  friend struct ::fidl::internal::MemberVisitor<::test_anonymous::TableMember>;
  static constexpr auto kMembers = std::make_tuple(::fidl::internal::NaturalTableMember<Storage_, ::std::vector<::test_anonymous::TableData>, fidl::internal::NaturalCodingConstraintVector<fidl::internal::NaturalCodingConstraintEmpty, 10>>{
      2, &Storage_::table_data});
};

class SomeProtocolSomeMethodRequest {
 private:
  struct Storage_;

 public:
  SomeProtocolSomeMethodRequest(Storage_ storage) noexcept;
  SomeProtocolSomeMethodRequest(::test_anonymous::UnionMember union_member, ::test_anonymous::TableMember table_member) noexcept;

#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdefaulted-function-deleted"
  // Default constructs a |SomeProtocolSomeMethodRequest| only if all of its members are default constructible.
  SomeProtocolSomeMethodRequest() = default;
#pragma clang diagnostic pop

  SomeProtocolSomeMethodRequest(SomeProtocolSomeMethodRequest&&) noexcept = default;
  SomeProtocolSomeMethodRequest& operator=(SomeProtocolSomeMethodRequest&&) noexcept = default;
  SomeProtocolSomeMethodRequest(const SomeProtocolSomeMethodRequest& other) noexcept;
  SomeProtocolSomeMethodRequest& operator=(const SomeProtocolSomeMethodRequest& other) noexcept;

  bool operator==(const SomeProtocolSomeMethodRequest& other) const noexcept {
    return ::fidl::internal::NaturalStructCodingTraits<::test_anonymous::SomeProtocolSomeMethodRequest, 32>::Equal(this, &other);
  }
  bool operator!=(const SomeProtocolSomeMethodRequest& other) const noexcept {
    return !::fidl::internal::NaturalStructCodingTraits<::test_anonymous::SomeProtocolSomeMethodRequest, 32>::Equal(this, &other);
  }

  const ::test_anonymous::UnionMember&
  union_member() const {
    return storage_.union_member;
  }

  ::test_anonymous::UnionMember& union_member() {
    return storage_.union_member;
  }

  // Setter for union_member.
  //

  SomeProtocolSomeMethodRequest& union_member(::test_anonymous::UnionMember value);

  const ::test_anonymous::TableMember&
  table_member() const {
    return storage_.table_member;
  }

  ::test_anonymous::TableMember& table_member() {
    return storage_.table_member;
  }

  // Setter for table_member.
  //

  SomeProtocolSomeMethodRequest& table_member(::test_anonymous::TableMember value);

  SomeProtocolSomeMethodRequest(::fidl::internal::DefaultConstructPossiblyInvalidObjectTag);

 private:
  struct Storage_ final {
    ::test_anonymous::UnionMember union_member;
    ::test_anonymous::TableMember table_member;
  };

  Storage_ storage_;
  Storage_ CloneStorage_() const;

  friend struct ::fidl::internal::NaturalStructCodingTraits<::test_anonymous::SomeProtocolSomeMethodRequest, 32>;
  friend struct ::fidl::internal::MemberVisitor<::test_anonymous::SomeProtocolSomeMethodRequest>;
  static constexpr auto kMembers = std::make_tuple(::fidl::internal::NaturalStructMember<Storage_, ::test_anonymous::UnionMember, fidl::internal::NaturalCodingConstraintEmpty>{
                                                       &Storage_::union_member, 0},
                                                   ::fidl::internal::NaturalStructMember<Storage_, ::test_anonymous::TableMember, fidl::internal::NaturalCodingConstraintEmpty>{&Storage_::table_member, 16});
  static constexpr auto kPadding = std::make_tuple();
};

class SomeProtocolSomeMethodResponse {
 private:
  struct Storage_;

 public:
  SomeProtocolSomeMethodResponse(Storage_ storage) noexcept;
  SomeProtocolSomeMethodResponse(::test_anonymous::BitsMember bits_member) noexcept;

#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdefaulted-function-deleted"
  // Default constructs a |SomeProtocolSomeMethodResponse| only if all of its members are default constructible.
  SomeProtocolSomeMethodResponse() = default;
#pragma clang diagnostic pop

  SomeProtocolSomeMethodResponse(SomeProtocolSomeMethodResponse&&) noexcept = default;
  SomeProtocolSomeMethodResponse& operator=(SomeProtocolSomeMethodResponse&&) noexcept = default;
  SomeProtocolSomeMethodResponse(const SomeProtocolSomeMethodResponse& other) noexcept;
  SomeProtocolSomeMethodResponse& operator=(const SomeProtocolSomeMethodResponse& other) noexcept;

  bool operator==(const SomeProtocolSomeMethodResponse& other) const noexcept {
    return ::fidl::internal::NaturalStructCodingTraits<::test_anonymous::SomeProtocolSomeMethodResponse, 4>::Equal(this, &other);
  }
  bool operator!=(const SomeProtocolSomeMethodResponse& other) const noexcept {
    return !::fidl::internal::NaturalStructCodingTraits<::test_anonymous::SomeProtocolSomeMethodResponse, 4>::Equal(this, &other);
  }

  ::test_anonymous::BitsMember
  bits_member() const {
    return storage_.bits_member;
  }

  ::test_anonymous::BitsMember& bits_member() {
    return storage_.bits_member;
  }

  // Setter for bits_member.
  //

  SomeProtocolSomeMethodResponse& bits_member(::test_anonymous::BitsMember value);

  SomeProtocolSomeMethodResponse(::fidl::internal::DefaultConstructPossiblyInvalidObjectTag);

 private:
  struct Storage_ final {
    ::test_anonymous::BitsMember bits_member = {};
  };

  Storage_ storage_;
  Storage_ CloneStorage_() const;

  friend struct ::fidl::internal::NaturalStructCodingTraits<::test_anonymous::SomeProtocolSomeMethodResponse, 4>;
  friend struct ::fidl::internal::MemberVisitor<::test_anonymous::SomeProtocolSomeMethodResponse>;
  static constexpr auto kMembers = std::make_tuple(::fidl::internal::NaturalStructMember<Storage_, ::test_anonymous::BitsMember, fidl::internal::NaturalCodingConstraintEmpty>{
      &Storage_::bits_member, 0});
  static constexpr auto kPadding = std::make_tuple();
};

class SomeProtocolSomeMethodResult {
 private:
  using Storage_ =
      std::variant<
          std::monostate, ::test_anonymous::SomeProtocolSomeMethodResponse, ::test_anonymous::SomeProtocolSomeMethodError>;

 public:
  // TODO: share union tag types between wire & natural.
  enum class Tag : fidl_xunion_tag_t {
    kResponse = 1,  // 0x1
    kErr = 2,       // 0x2
  };

  SomeProtocolSomeMethodResult(SomeProtocolSomeMethodResult&& other) noexcept
      : SomeProtocolSomeMethodResult(::fidl::internal::DefaultConstructPossiblyInvalidObjectTag{}) {
    *storage_ = std::move(*other.storage_);
  }
  SomeProtocolSomeMethodResult& operator=(SomeProtocolSomeMethodResult&& other) noexcept {
    if (this != &other) {
      *storage_ = std::move(*other.storage_);
    }
    return *this;
  }
  SomeProtocolSomeMethodResult(const SomeProtocolSomeMethodResult& other) noexcept : SomeProtocolSomeMethodResult(other.CloneStorage_()) {}
  SomeProtocolSomeMethodResult& operator=(const SomeProtocolSomeMethodResult& other) noexcept {
    if (this != &other) {
      storage_ = other.CloneStorage_();
    }
    return *this;
  }

  bool operator==(const SomeProtocolSomeMethodResult& other) const noexcept {
    return *storage_ == *other.storage_;
  }
  bool operator!=(const SomeProtocolSomeMethodResult& other) const noexcept {
    return *storage_ != *other.storage_;
  }

  constexpr ::test_anonymous::SomeProtocolSomeMethodResult::Tag Which() const {
    return SomeProtocolSomeMethodResult::IndexToTag(storage_->index()).value();
  }
  static SomeProtocolSomeMethodResult WithResponse(::test_anonymous::SomeProtocolSomeMethodResponse val) {
    return SomeProtocolSomeMethodResult(std::make_shared<Storage_>(
        std::in_place_index_t<1>{},
        std::move(val)));
  }

  const ::fidl::internal::UnionMemberView<1, Storage_> response() const {
    return ::fidl::internal::UnionMemberView<1, Storage_>(storage_);
  }

  ::fidl::internal::UnionMemberView<1, Storage_> response() {
    return ::fidl::internal::UnionMemberView<1, Storage_>(storage_);
  }

  // Sets the union to hold the response member.
  //

  SomeProtocolSomeMethodResult& response(::test_anonymous::SomeProtocolSomeMethodResponse value) {
    storage_->emplace<1>(std::move(value));
    return *this;
  }
  static SomeProtocolSomeMethodResult WithErr(::test_anonymous::SomeProtocolSomeMethodError val) {
    return SomeProtocolSomeMethodResult(std::make_shared<Storage_>(
        std::in_place_index_t<2>{},
        std::move(val)));
  }

  const ::fidl::internal::UnionMemberView<2, Storage_> err() const {
    return ::fidl::internal::UnionMemberView<2, Storage_>(storage_);
  }

  ::fidl::internal::UnionMemberView<2, Storage_> err() {
    return ::fidl::internal::UnionMemberView<2, Storage_>(storage_);
  }

  // Sets the union to hold the err member.
  //

  SomeProtocolSomeMethodResult& err(::test_anonymous::SomeProtocolSomeMethodError value) {
    storage_->emplace<2>(std::move(value));
    return *this;
  }

  SomeProtocolSomeMethodResult(::fidl::internal::DefaultConstructPossiblyInvalidObjectTag)
      : storage_(std::make_shared<Storage_>()) {}

 private:
  std::shared_ptr<Storage_> storage_;
  std::shared_ptr<Storage_> CloneStorage_() const;
  friend struct ::fidl::internal::NaturalUnionCodingTraits<::test_anonymous::SomeProtocolSomeMethodResult>;
  static constexpr auto kMembers = std::make_tuple(
      ::fidl::internal::NaturalUnionMember<::fidl::internal::NaturalCodingConstraintEmpty>(), ::fidl::internal::NaturalUnionMember<fidl::internal::NaturalCodingConstraintEmpty>(), ::fidl::internal::NaturalUnionMember<fidl::internal::NaturalCodingConstraintEmpty>());

  explicit SomeProtocolSomeMethodResult(std::shared_ptr<Storage_> storage) : storage_(std::move(storage)) {}

  static constexpr size_t TagToIndex(::fidl::internal::NaturalDecoder* decoder, ::test_anonymous::SomeProtocolSomeMethodResult::Tag tag) {
    switch (tag) {
      case ::test_anonymous::SomeProtocolSomeMethodResult::Tag::kResponse:
        return 1;
      case ::test_anonymous::SomeProtocolSomeMethodResult::Tag::kErr:
        return 2;
      default: {
        decoder->SetError(::fidl::internal::kCodingErrorUnknownUnionTag);
        return 0;
      }
    }
  }

  static constexpr std::optional<::test_anonymous::SomeProtocolSomeMethodResult::Tag> IndexToTag(size_t index) {
    switch (index) {
      case 1:
        return ::test_anonymous::SomeProtocolSomeMethodResult::Tag::kResponse;
      case 2:
        return ::test_anonymous::SomeProtocolSomeMethodResult::Tag::kErr;
      default:
        return std::nullopt;
    }
  }
};

inline OverrideTest::OverrideTest(Storage_ storage) noexcept : storage_(std::move(storage)) {}
inline OverrideTest::OverrideTest(::test_anonymous::Op op, ::fidl::Box<::test_anonymous::Expression> left, ::fidl::Box<::test_anonymous::Expression> right) noexcept
    : storage_({.op = std::move(op),
                .left = std::move(left),
                .right = std::move(right)}) {}
inline OverrideTest::OverrideTest(const ::test_anonymous::OverrideTest& other) noexcept : ::test_anonymous::OverrideTest(other.CloneStorage_()) {}
inline OverrideTest& ::test_anonymous::OverrideTest::operator=(const ::test_anonymous::OverrideTest & other) noexcept {
  storage_ = other.CloneStorage_();
  return *this;
}

inline OverrideTest::OverrideTest(::fidl::internal::DefaultConstructPossiblyInvalidObjectTag) : OverrideTest(Storage_{
                                                                                                    .op = {},
                                                                                                    .left = {},
                                                                                                    .right = {},
                                                                                                }) {}
inline OverrideTest& OverrideTest::op(::test_anonymous::Op value) {
  storage_.op = std::move(value);
  return *this;
}
inline OverrideTest& OverrideTest::left(::fidl::Box<::test_anonymous::Expression> value) {
  storage_.left = std::move(value);
  return *this;
}
inline OverrideTest& OverrideTest::right(::fidl::Box<::test_anonymous::Expression> value) {
  storage_.right = std::move(value);
  return *this;
}

inline FunctionApplication::FunctionApplication(Storage_ storage) noexcept : storage_(std::move(storage)) {}
inline FunctionApplication::FunctionApplication(const ::test_anonymous::FunctionApplication& other) noexcept : FunctionApplication(other.CloneStorage_()) {}
inline FunctionApplication& ::test_anonymous::FunctionApplication::operator=(const FunctionApplication & other) noexcept {
  storage_ = other.CloneStorage_();
  return *this;
}

inline FunctionApplication::FunctionApplication(::fidl::internal::DefaultConstructPossiblyInvalidObjectTag) : FunctionApplication(Storage_{}) {}
inline FunctionApplication& FunctionApplication::func(std::optional<::std::string> value) {
  storage_.func = std::move(value);
  return *this;
}
inline FunctionApplication& FunctionApplication::args(std::optional<::std::vector<::fidl::Box<::test_anonymous::Expression>>> value) {
  storage_.args = std::move(value);
  return *this;
}
inline FunctionApplication& FunctionApplication::flags(std::optional<::test_anonymous::Flags> value) {
  storage_.flags = std::move(value);
  return *this;
}

inline TableData::TableData(Storage_ storage) noexcept : storage_(std::move(storage)) {}
inline TableData::TableData(uint8_t data) noexcept
    : storage_({.data = std::move(data)}) {}
inline TableData::TableData(const ::test_anonymous::TableData& other) noexcept : ::test_anonymous::TableData(other.CloneStorage_()) {}
inline TableData& ::test_anonymous::TableData::operator=(const ::test_anonymous::TableData & other) noexcept {
  storage_ = other.CloneStorage_();
  return *this;
}

inline TableData::TableData(::fidl::internal::DefaultConstructPossiblyInvalidObjectTag) : TableData(Storage_{
                                                                                              .data = {},
                                                                                          }) {}
inline TableData& TableData::data(uint8_t value) {
  storage_.data = std::move(value);
  return *this;
}

inline TableMember::TableMember(Storage_ storage) noexcept : storage_(std::move(storage)) {}
inline TableMember::TableMember(const ::test_anonymous::TableMember& other) noexcept : TableMember(other.CloneStorage_()) {}
inline TableMember& ::test_anonymous::TableMember::operator=(const TableMember & other) noexcept {
  storage_ = other.CloneStorage_();
  return *this;
}

inline TableMember::TableMember(::fidl::internal::DefaultConstructPossiblyInvalidObjectTag) : TableMember(Storage_{}) {}
inline TableMember& TableMember::table_data(std::optional<::std::vector<::test_anonymous::TableData>> value) {
  storage_.table_data = std::move(value);
  return *this;
}

inline SomeProtocolSomeMethodRequest::SomeProtocolSomeMethodRequest(Storage_ storage) noexcept : storage_(std::move(storage)) {}
inline SomeProtocolSomeMethodRequest::SomeProtocolSomeMethodRequest(::test_anonymous::UnionMember union_member, ::test_anonymous::TableMember table_member) noexcept
    : storage_({.union_member = std::move(union_member),
                .table_member = std::move(table_member)}) {}
inline SomeProtocolSomeMethodRequest::SomeProtocolSomeMethodRequest(const ::test_anonymous::SomeProtocolSomeMethodRequest& other) noexcept : ::test_anonymous::SomeProtocolSomeMethodRequest(other.CloneStorage_()) {}
inline SomeProtocolSomeMethodRequest& ::test_anonymous::SomeProtocolSomeMethodRequest::operator=(const ::test_anonymous::SomeProtocolSomeMethodRequest & other) noexcept {
  storage_ = other.CloneStorage_();
  return *this;
}

inline SomeProtocolSomeMethodRequest::SomeProtocolSomeMethodRequest(::fidl::internal::DefaultConstructPossiblyInvalidObjectTag) : SomeProtocolSomeMethodRequest(Storage_{
                                                                                                                                      .union_member = ::fidl::internal::DefaultConstructPossiblyInvalidObjectTag{},
                                                                                                                                      .table_member = ::fidl::internal::DefaultConstructPossiblyInvalidObjectTag{},
                                                                                                                                  }) {}
inline SomeProtocolSomeMethodRequest& SomeProtocolSomeMethodRequest::union_member(::test_anonymous::UnionMember value) {
  storage_.union_member = std::move(value);
  return *this;
}
inline SomeProtocolSomeMethodRequest& SomeProtocolSomeMethodRequest::table_member(::test_anonymous::TableMember value) {
  storage_.table_member = std::move(value);
  return *this;
}

inline SomeProtocolSomeMethodResponse::SomeProtocolSomeMethodResponse(Storage_ storage) noexcept : storage_(std::move(storage)) {}
inline SomeProtocolSomeMethodResponse::SomeProtocolSomeMethodResponse(::test_anonymous::BitsMember bits_member) noexcept
    : storage_({.bits_member = std::move(bits_member)}) {}
inline SomeProtocolSomeMethodResponse::SomeProtocolSomeMethodResponse(const ::test_anonymous::SomeProtocolSomeMethodResponse& other) noexcept : ::test_anonymous::SomeProtocolSomeMethodResponse(other.CloneStorage_()) {}
inline SomeProtocolSomeMethodResponse& ::test_anonymous::SomeProtocolSomeMethodResponse::operator=(const ::test_anonymous::SomeProtocolSomeMethodResponse & other) noexcept {
  storage_ = other.CloneStorage_();
  return *this;
}

inline SomeProtocolSomeMethodResponse::SomeProtocolSomeMethodResponse(::fidl::internal::DefaultConstructPossiblyInvalidObjectTag) : SomeProtocolSomeMethodResponse(Storage_{
                                                                                                                                        .bits_member = {},
                                                                                                                                    }) {}
inline SomeProtocolSomeMethodResponse& SomeProtocolSomeMethodResponse::bits_member(::test_anonymous::BitsMember value) {
  storage_.bits_member = std::move(value);
  return *this;
}

}  // namespace test_anonymous
namespace fidl {

template <>
struct IsFidlType<::test_anonymous::OverrideTest> : public std::true_type {};

template <>
struct TypeTraits<::test_anonymous::OverrideTest> {
  static constexpr uint32_t kMaxNumHandles = 0;
  static constexpr uint32_t kMaxDepth = 4294967295;
  static constexpr uint32_t kPrimarySize = 40;
  static constexpr uint32_t kMaxOutOfLine = 4294967295;
  static constexpr bool kHasPointer = true;
};

template <>
struct IsStruct<::test_anonymous::OverrideTest> : public std::true_type {};

template <>
struct internal::NaturalCodingTraits<::test_anonymous::OverrideTest, ::fidl::internal::NaturalCodingConstraintEmpty> final
    : public ::fidl::internal::NaturalStructCodingTraits<::test_anonymous::OverrideTest, 40> {};

template <>
struct IsFidlType<::test_anonymous::TableData> : public std::true_type {};

template <>
struct TypeTraits<::test_anonymous::TableData> {
  static constexpr uint32_t kMaxNumHandles = 0;
  static constexpr uint32_t kMaxDepth = 0;
  static constexpr uint32_t kPrimarySize = 1;
  static constexpr uint32_t kMaxOutOfLine = 0;
  static constexpr bool kHasPointer = false;
};

template <>
struct IsStruct<::test_anonymous::TableData> : public std::true_type {};

template <>
struct internal::NaturalCodingTraits<::test_anonymous::TableData, ::fidl::internal::NaturalCodingConstraintEmpty> final
    : public ::fidl::internal::NaturalStructCodingTraits<::test_anonymous::TableData, 1> {};

template <>
struct IsFidlType<::test_anonymous::SomeProtocolSomeMethodRequest> : public std::true_type {};

template <>
struct TypeTraits<::test_anonymous::SomeProtocolSomeMethodRequest> {
  static constexpr uint32_t kMaxNumHandles = 0;
  static constexpr uint32_t kMaxDepth = 3;
  static constexpr uint32_t kPrimarySize = 32;
  static constexpr uint32_t kMaxOutOfLine = 48;
  static constexpr bool kHasPointer = true;
};

template <>
struct IsStruct<::test_anonymous::SomeProtocolSomeMethodRequest> : public std::true_type {};

template <>
struct internal::NaturalCodingTraits<::test_anonymous::SomeProtocolSomeMethodRequest, ::fidl::internal::NaturalCodingConstraintEmpty> final
    : public ::fidl::internal::NaturalStructCodingTraits<::test_anonymous::SomeProtocolSomeMethodRequest, 32> {};

template <>
struct IsFidlType<::test_anonymous::SomeProtocolSomeMethodResponse> : public std::true_type {};

template <>
struct TypeTraits<::test_anonymous::SomeProtocolSomeMethodResponse> {
  static constexpr uint32_t kMaxNumHandles = 0;
  static constexpr uint32_t kMaxDepth = 0;
  static constexpr uint32_t kPrimarySize = 4;
  static constexpr uint32_t kMaxOutOfLine = 0;
  static constexpr bool kHasPointer = false;
};

template <>
struct IsStruct<::test_anonymous::SomeProtocolSomeMethodResponse> : public std::true_type {};

template <>
struct internal::NaturalCodingTraits<::test_anonymous::SomeProtocolSomeMethodResponse, ::fidl::internal::NaturalCodingConstraintEmpty> final
    : public ::fidl::internal::NaturalStructCodingTraits<::test_anonymous::SomeProtocolSomeMethodResponse, 4> {};

template <>
struct IsFidlType<::test_anonymous::FunctionApplication> : public std::true_type {};

template <>
struct TypeTraits<::test_anonymous::FunctionApplication> {
  static constexpr uint32_t kMaxNumHandles = 0;
  static constexpr uint32_t kMaxDepth = 4294967295;
  static constexpr uint32_t kPrimarySize = 16;
  static constexpr uint32_t kMaxOutOfLine = 4294967295;
  static constexpr bool kHasPointer = true;
};

template <>
struct IsTable<::test_anonymous::FunctionApplication> : public std::true_type {};

template <>
struct internal::NaturalCodingTraits<::test_anonymous::FunctionApplication, ::fidl::internal::NaturalCodingConstraintEmpty> : public ::fidl::internal::NaturalTableCodingTraits<::test_anonymous::FunctionApplication> {};

template <>
struct IsFidlType<::test_anonymous::TableMember> : public std::true_type {};

template <>
struct TypeTraits<::test_anonymous::TableMember> {
  static constexpr uint32_t kMaxNumHandles = 0;
  static constexpr uint32_t kMaxDepth = 3;
  static constexpr uint32_t kPrimarySize = 16;
  static constexpr uint32_t kMaxOutOfLine = 48;
  static constexpr bool kHasPointer = true;
};

template <>
struct IsTable<::test_anonymous::TableMember> : public std::true_type {};

template <>
struct internal::NaturalCodingTraits<::test_anonymous::TableMember, ::fidl::internal::NaturalCodingConstraintEmpty> : public ::fidl::internal::NaturalTableCodingTraits<::test_anonymous::TableMember> {};

template <>
struct IsFidlType<::test_anonymous::Expression> : public std::true_type {};

template <>
struct TypeTraits<::test_anonymous::Expression> {
  static constexpr uint32_t kMaxNumHandles = 0;
  static constexpr uint32_t kMaxDepth = 4294967295;
  static constexpr uint32_t kPrimarySize = 16;
  static constexpr uint32_t kMaxOutOfLine = 4294967295;
  static constexpr bool kHasPointer = true;
};

template <>
struct IsUnion<::test_anonymous::Expression> : public std::true_type {};

template <>
struct internal::NaturalCodingTraits<::test_anonymous::Expression, ::fidl::internal::NaturalCodingConstraintEmpty> final
    : public ::fidl::internal::NaturalUnionCodingTraits<::test_anonymous::Expression> {};

template <>
struct IsFidlType<::test_anonymous::UnionMember> : public std::true_type {};

template <>
struct TypeTraits<::test_anonymous::UnionMember> {
  static constexpr uint32_t kMaxNumHandles = 0;
  static constexpr uint32_t kMaxDepth = 1;
  static constexpr uint32_t kPrimarySize = 16;
  static constexpr uint32_t kMaxOutOfLine = 0;
  static constexpr bool kHasPointer = true;
};

template <>
struct IsUnion<::test_anonymous::UnionMember> : public std::true_type {};

template <>
struct internal::NaturalCodingTraits<::test_anonymous::UnionMember, ::fidl::internal::NaturalCodingConstraintEmpty> final
    : public ::fidl::internal::NaturalUnionCodingTraits<::test_anonymous::UnionMember> {};

template <>
struct IsFidlType<::test_anonymous::SomeProtocolSomeMethodResult> : public std::true_type {};

template <>
struct TypeTraits<::test_anonymous::SomeProtocolSomeMethodResult> {
  static constexpr uint32_t kMaxNumHandles = 0;
  static constexpr uint32_t kMaxDepth = 1;
  static constexpr uint32_t kPrimarySize = 16;
  static constexpr uint32_t kMaxOutOfLine = 0;
  static constexpr bool kHasPointer = true;
};

template <>
struct IsUnion<::test_anonymous::SomeProtocolSomeMethodResult> : public std::true_type {};

template <>
struct internal::NaturalCodingTraits<::test_anonymous::SomeProtocolSomeMethodResult, ::fidl::internal::NaturalCodingConstraintEmpty> final
    : public ::fidl::internal::NaturalUnionCodingTraits<::test_anonymous::SomeProtocolSomeMethodResult> {};

template <>
struct internal::NaturalCodingTraits<::test_anonymous::Flags, ::fidl::internal::NaturalCodingConstraintEmpty> {
  static constexpr size_t kInlineSize = sizeof(uint16_t);
  static constexpr bool kIsMemcpyCompatible = true;

  static void Encode(internal::NaturalEncoder* encoder, ::test_anonymous::Flags* value, size_t offset, size_t recursion_depth) {
    *encoder->template GetPtr<::test_anonymous::Flags>(offset) = *value;
  }
  static void Decode(internal::NaturalDecoder* decoder, ::test_anonymous::Flags* value, size_t offset, size_t recursion_depth) {
    *value = *decoder->template GetPtr<::test_anonymous::Flags>(offset);
  }
};
template <>
struct internal::NaturalCodingTraits<::test_anonymous::BitsMember, ::fidl::internal::NaturalCodingConstraintEmpty> {
  static constexpr size_t kInlineSize = sizeof(uint32_t);
  static constexpr bool kIsMemcpyCompatible = true;

  static void Encode(internal::NaturalEncoder* encoder, ::test_anonymous::BitsMember* value, size_t offset, size_t recursion_depth) {
    *encoder->template GetPtr<::test_anonymous::BitsMember>(offset) = *value;
  }
  static void Decode(internal::NaturalDecoder* decoder, ::test_anonymous::BitsMember* value, size_t offset, size_t recursion_depth) {
    *value = *decoder->template GetPtr<::test_anonymous::BitsMember>(offset);
  }
};

template <>
struct internal::NaturalCodingTraits<::test_anonymous::Op, ::fidl::internal::NaturalCodingConstraintEmpty> {
  static constexpr size_t kInlineSize = sizeof(uint32_t);
  static constexpr bool kIsMemcpyCompatible = true;

  static void Encode(internal::NaturalEncoder* encoder, ::test_anonymous::Op* value, size_t offset, size_t recursion_depth) {
    *encoder->template GetPtr<::test_anonymous::Op>(offset) = *value;
  }
  static void Decode(internal::NaturalDecoder* decoder, ::test_anonymous::Op* value, size_t offset, size_t recursion_depth) {
    *value = *decoder->template GetPtr<::test_anonymous::Op>(offset);
  }
};
template <>
struct internal::NaturalCodingTraits<::test_anonymous::SomeProtocolSomeMethodError, ::fidl::internal::NaturalCodingConstraintEmpty> {
  static constexpr size_t kInlineSize = sizeof(uint32_t);
  static constexpr bool kIsMemcpyCompatible = true;

  static void Encode(internal::NaturalEncoder* encoder, ::test_anonymous::SomeProtocolSomeMethodError* value, size_t offset, size_t recursion_depth) {
    *encoder->template GetPtr<::test_anonymous::SomeProtocolSomeMethodError>(offset) = *value;
  }
  static void Decode(internal::NaturalDecoder* decoder, ::test_anonymous::SomeProtocolSomeMethodError* value, size_t offset, size_t recursion_depth) {
    *value = *decoder->template GetPtr<::test_anonymous::SomeProtocolSomeMethodError>(offset);
  }
};

#pragma clang diagnostic pop

}  // namespace fidl
