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

#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__

namespace test_anonymous {
class TableData;

class SomeProtocolSomeMethodRequest;

class OverrideTest;

class SomeProtocolSomeMethodResponse;

class SomeProtocolSomeMethodTopResponse;

class TableMember;

class FunctionApplication;

class UnionMember;

class Expression;

class SomeProtocolSomeMethodResult;

extern "C" const fidl_type_t test_anonymous_UnionMemberTable;

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

 public:
  // TODO: share union tag types between wire & natural.
  enum class Tag : fidl_union_tag_t {
    kUnionData = 2,  // 0x2
    kUnknown = ::std::numeric_limits<::fidl_union_tag_t>::max(),
  };
  // Create an unknown value of this union.
  UnionMember() : storage_(std::make_shared<Storage_>()) {}

  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 ::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_);
  }

  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;
      case ::test_anonymous::UnionMember::Tag::kUnknown:
        return 0;
      default: {
        decoder->SetError(::fidl::internal::kCodingErrorUnknownUnionTag);
        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::kUnknown;
    }
  }
};

extern "C" const fidl_type_t test_anonymous_TableDataTable;

class TableData {
 private:
  struct Storage_;

 public:
  TableData(Storage_ storage) noexcept : storage_(std::move(storage)) {}
  TableData(uint8_t data) noexcept : storage_({.data = std::move(data)}) {}

#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(other.CloneStorage_()) {}
  TableData& operator=(const TableData& other) noexcept {
    storage_ = other.CloneStorage_();
    return *this;
  }

  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; }

  TableData(::fidl::internal::DefaultConstructPossiblyInvalidObjectTag)
      : TableData(Storage_{
            .data = {},
        }) {}

 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();
};

extern "C" const fidl_type_t test_anonymous_TableMemberTable;

class TableMember {
 private:
  struct Storage_;

 public:
  TableMember(Storage_ storage) noexcept : storage_(std::move(storage)) {}
  TableMember() noexcept = default;
  TableMember(TableMember&&) noexcept = default;
  TableMember& operator=(TableMember&&) noexcept = default;
  TableMember(const TableMember& other) noexcept
      : TableMember(other.CloneStorage_()) {}
  TableMember& operator=(const TableMember& other) noexcept {
    storage_ = other.CloneStorage_();
    return *this;
  }
  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;
  }

  TableMember(::fidl::internal::DefaultConstructPossiblyInvalidObjectTag)
      : TableMember(Storage_{}) {}

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

  // TODO(https://fxbug.dev/91252): 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});
};

extern "C" const fidl_type_t test_anonymous_SomeProtocolSomeMethodRequestTable;

class SomeProtocolSomeMethodRequest {
 private:
  struct Storage_;

 public:
  SomeProtocolSomeMethodRequest(Storage_ storage) noexcept
      : storage_(std::move(storage)) {}
  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)}) {}

#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(other.CloneStorage_()) {}
  SomeProtocolSomeMethodRequest& operator=(
      const SomeProtocolSomeMethodRequest& other) noexcept {
    storage_ = other.CloneStorage_();
    return *this;
  }

  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;
  }

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

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

  SomeProtocolSomeMethodRequest(
      ::fidl::internal::DefaultConstructPossiblyInvalidObjectTag)
      : SomeProtocolSomeMethodRequest(Storage_{
            .union_member =
                ::fidl::internal::DefaultConstructPossiblyInvalidObjectTag{},
            .table_member =
                ::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();
};

extern "C" const fidl_type_t test_anonymous_OverrideTestTable;

class OverrideTest {
 private:
  struct Storage_;

 public:
  OverrideTest(Storage_ storage) noexcept : storage_(std::move(storage)) {}
  OverrideTest(::test_anonymous::Op op,
               ::std::unique_ptr<::test_anonymous::Expression> left,
               ::std::unique_ptr<::test_anonymous::Expression> right) noexcept
      : storage_({.op = std::move(op),
                  .left = std::move(left),
                  .right = std::move(right)}) {}

#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(other.CloneStorage_()) {}
  OverrideTest& operator=(const OverrideTest& other) noexcept {
    storage_ = other.CloneStorage_();
    return *this;
  }

  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; }

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

  ::std::unique_ptr<::test_anonymous::Expression>& left() {
    return storage_.left;
  }

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

  ::std::unique_ptr<::test_anonymous::Expression>& right() {
    return storage_.right;
  }

  OverrideTest(::fidl::internal::DefaultConstructPossiblyInvalidObjectTag)
      : OverrideTest(Storage_{
            .op = {},
            .left = {},
            .right = {},
        }) {}

 private:
  struct Storage_ final {
    ::test_anonymous::Op op = {};
    ::std::unique_ptr<::test_anonymous::Expression> left;
    ::std::unique_ptr<::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_, ::std::unique_ptr<::test_anonymous::Expression>,
          fidl::internal::NaturalCodingConstraintEmpty>{&Storage_::left, 8},
      ::fidl::internal::NaturalStructMember<
          Storage_, ::std::unique_ptr<::test_anonymous::Expression>,
          fidl::internal::NaturalCodingConstraintEmpty>{&Storage_::right, 24});
  static constexpr auto kPadding =
      std::make_tuple(::fidl::internal::NaturalStructPadding<uint64_t>{
          .offset = 0,
          .mask = 0xffffffff00000000ull,
      });
};

extern "C" const fidl_type_t test_anonymous_FunctionApplicationTable;

class FunctionApplication {
 private:
  struct Storage_;

 public:
  FunctionApplication(Storage_ storage) noexcept
      : storage_(std::move(storage)) {}
  FunctionApplication() noexcept = default;
  FunctionApplication(FunctionApplication&&) noexcept = default;
  FunctionApplication& operator=(FunctionApplication&&) noexcept = default;
  FunctionApplication(const FunctionApplication& other) noexcept
      : FunctionApplication(other.CloneStorage_()) {}
  FunctionApplication& operator=(const FunctionApplication& other) noexcept {
    storage_ = other.CloneStorage_();
    return *this;
  }
  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; }

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

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

  FunctionApplication(
      ::fidl::internal::DefaultConstructPossiblyInvalidObjectTag)
      : FunctionApplication(Storage_{}) {}

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

  // TODO(https://fxbug.dev/91252): 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<::std::unique_ptr<::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});
};

extern "C" const fidl_type_t test_anonymous_ExpressionTable;

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_union_tag_t {
    kValue = 1,                // 0x1
    kBinOp = 2,                // 0x2
    kFunctionApplication = 3,  // 0x3
    kUnknown = ::std::numeric_limits<::fidl_union_tag_t>::max(),
  };
  // Create an unknown value of this union.
  Expression() : storage_(std::make_shared<Storage_>()) {}

  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 ::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_);
  }
  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_);
  }
  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_);
  }

  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;
      case ::test_anonymous::Expression::Tag::kUnknown:
        return 0;
      default: {
        decoder->SetError(::fidl::internal::kCodingErrorUnknownUnionTag);
        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::kUnknown;
    }
  }
};

extern "C" const fidl_type_t
    test_anonymous_SomeProtocol_SomeMethod_ResponseTable;

class SomeProtocolSomeMethodResponse {
 private:
  struct Storage_;

 public:
  SomeProtocolSomeMethodResponse(Storage_ storage) noexcept
      : storage_(std::move(storage)) {}
  SomeProtocolSomeMethodResponse(
      ::test_anonymous::BitsMember bits_member) noexcept
      : storage_({.bits_member = std::move(bits_member)}) {}

#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(other.CloneStorage_()) {}
  SomeProtocolSomeMethodResponse& operator=(
      const SomeProtocolSomeMethodResponse& other) noexcept {
    storage_ = other.CloneStorage_();
    return *this;
  }

  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; }

  SomeProtocolSomeMethodResponse(
      ::fidl::internal::DefaultConstructPossiblyInvalidObjectTag)
      : SomeProtocolSomeMethodResponse(Storage_{
            .bits_member = {},
        }) {}

 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();
};

extern "C" const fidl_type_t test_anonymous_SomeProtocol_SomeMethod_ResultTable;

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_union_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_);
  }
  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_);
  }

  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;
    }
  }
};

extern "C" const fidl_type_t
    test_anonymous_SomeProtocolSomeMethodTopResponseTable;

class SomeProtocolSomeMethodTopResponse {
 private:
  struct Storage_;

 public:
  SomeProtocolSomeMethodTopResponse(Storage_ storage) noexcept
      : storage_(std::move(storage)) {}
  SomeProtocolSomeMethodTopResponse(
      ::test_anonymous::SomeProtocolSomeMethodResult result) noexcept
      : storage_({.result = std::move(result)}) {}

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

  SomeProtocolSomeMethodTopResponse(
      SomeProtocolSomeMethodTopResponse&&) noexcept = default;
  SomeProtocolSomeMethodTopResponse& operator=(
      SomeProtocolSomeMethodTopResponse&&) noexcept = default;
  SomeProtocolSomeMethodTopResponse(
      const SomeProtocolSomeMethodTopResponse& other) noexcept
      : SomeProtocolSomeMethodTopResponse(other.CloneStorage_()) {}
  SomeProtocolSomeMethodTopResponse& operator=(
      const SomeProtocolSomeMethodTopResponse& other) noexcept {
    storage_ = other.CloneStorage_();
    return *this;
  }

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

  const ::test_anonymous::SomeProtocolSomeMethodResult& result() const {
    return storage_.result;
  }

  ::test_anonymous::SomeProtocolSomeMethodResult& result() {
    return storage_.result;
  }

  SomeProtocolSomeMethodTopResponse(
      ::fidl::internal::DefaultConstructPossiblyInvalidObjectTag)
      : SomeProtocolSomeMethodTopResponse(Storage_{
            .result =
                ::fidl::internal::DefaultConstructPossiblyInvalidObjectTag{},
        }) {}

 private:
  struct Storage_ final {
    ::test_anonymous::SomeProtocolSomeMethodResult result;
  };

  Storage_ storage_;
  Storage_ CloneStorage_() const;

  friend struct ::fidl::internal::NaturalStructCodingTraits<
      ::test_anonymous::SomeProtocolSomeMethodTopResponse, 16>;
  friend struct ::fidl::internal::MemberVisitor<
      ::test_anonymous::SomeProtocolSomeMethodTopResponse>;
  static constexpr auto kMembers = std::make_tuple(
      ::fidl::internal::NaturalStructMember<
          Storage_, ::test_anonymous::SomeProtocolSomeMethodResult,
          fidl::internal::NaturalCodingConstraintEmpty>{&Storage_::result, 0});
  static constexpr auto kPadding = std::make_tuple();
};

}  // namespace test_anonymous
namespace fidl {

extern "C" const fidl_type_t test_anonymous_TableDataTable;

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

template <>
struct ::fidl::internal::TypeTraits<::test_anonymous::TableData> final {
 public:
  static constexpr const fidl_type_t* kCodingTable =
      &test_anonymous_TableDataTable;
};

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

extern "C" const fidl_type_t test_anonymous_SomeProtocolSomeMethodRequestTable;

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

template <>
struct ::fidl::internal::TypeTraits<
    ::test_anonymous::SomeProtocolSomeMethodRequest>
    final {
 public:
  static constexpr const fidl_type_t* kCodingTable =
      &test_anonymous_SomeProtocolSomeMethodRequestTable;
};

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

extern "C" const fidl_type_t test_anonymous_OverrideTestTable;

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

template <>
struct ::fidl::internal::TypeTraits<::test_anonymous::OverrideTest> final {
 public:
  static constexpr const fidl_type_t* kCodingTable =
      &test_anonymous_OverrideTestTable;
};

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

extern "C" const fidl_type_t
    test_anonymous_SomeProtocol_SomeMethod_ResponseTable;

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

template <>
struct ::fidl::internal::TypeTraits<
    ::test_anonymous::SomeProtocolSomeMethodResponse>
    final {
 public:
  static constexpr const fidl_type_t* kCodingTable =
      &test_anonymous_SomeProtocol_SomeMethod_ResponseTable;
};

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

extern "C" const fidl_type_t
    test_anonymous_SomeProtocolSomeMethodTopResponseTable;

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

template <>
struct ::fidl::internal::TypeTraits<
    ::test_anonymous::SomeProtocolSomeMethodTopResponse>
    final {
 public:
  static constexpr const fidl_type_t* kCodingTable =
      &test_anonymous_SomeProtocolSomeMethodTopResponseTable;
};

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

extern "C" const fidl_type_t test_anonymous_TableMemberTable;

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

template <>
struct ::fidl::internal::TypeTraits<::test_anonymous::TableMember> final {
 public:
  static constexpr const fidl_type_t* kCodingTable =
      &test_anonymous_TableMemberTable;
};

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

extern "C" const fidl_type_t test_anonymous_FunctionApplicationTable;

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

template <>
struct ::fidl::internal::TypeTraits<::test_anonymous::FunctionApplication>
    final {
 public:
  static constexpr const fidl_type_t* kCodingTable =
      &test_anonymous_FunctionApplicationTable;
};

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

extern "C" const fidl_type_t test_anonymous_UnionMemberTable;

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

template <>
struct ::fidl::internal::TypeTraits<::test_anonymous::UnionMember> final {
 public:
  static constexpr const fidl_type_t* kCodingTable =
      &test_anonymous_UnionMemberTable;
};

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

extern "C" const fidl_type_t test_anonymous_ExpressionTable;

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

template <>
struct ::fidl::internal::TypeTraits<::test_anonymous::Expression> final {
 public:
  static constexpr const fidl_type_t* kCodingTable =
      &test_anonymous_ExpressionTable;
};

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

extern "C" const fidl_type_t test_anonymous_SomeProtocol_SomeMethod_ResultTable;

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

template <>
struct ::fidl::internal::TypeTraits<
    ::test_anonymous::SomeProtocolSomeMethodResult>
    final {
 public:
  static constexpr const fidl_type_t* kCodingTable =
      &test_anonymous_SomeProtocol_SomeMethod_ResultTable;
};

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 inline_size_v2 = sizeof(uint16_t);
  static constexpr bool is_memcpy_compatible = 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 inline_size_v2 = sizeof(uint32_t);
  static constexpr bool is_memcpy_compatible = 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::SomeProtocolSomeMethodError,
    ::fidl::internal::NaturalCodingConstraintEmpty> {
  static constexpr size_t inline_size_v2 = sizeof(uint32_t);
  static constexpr bool is_memcpy_compatible = 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);
  }
};
template <>
struct internal::NaturalCodingTraits<
    ::test_anonymous::Op, ::fidl::internal::NaturalCodingConstraintEmpty> {
  static constexpr size_t inline_size_v2 = sizeof(uint32_t);
  static constexpr bool is_memcpy_compatible = 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);
  }
};

}  // namespace fidl
