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

// fidl_experiment = output_index_json

#pragma once

#include <fidl/test.protocollayouts/cpp/common_types.h>
#include <fidl/test.protocollayouts/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__

#include <fidl/test.protocollayouts.imported/cpp/natural_types.h>
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wshadow"

namespace test_protocollayouts {

class LocalTablePayload;

class MainProtocolOneWayAnonRequest;

class MainProtocolTwoWayAnonResponse;

class MainProtocolTwoWayAnonWithErrorRequest;

class LocalUnionPayload;

class MainProtocolTwoWayImportWithErrorResult;

class MainProtocolTwoWayLocalWithErrorResult;

class MainProtocolTwoWayAnonRequest;

class MainProtocolTwoWayAnonWithErrorResponse;

class MainProtocolTwoWayAnonWithErrorResult;

class MainProtocolOnAnonRequest;

class LocalTablePayload {
 private:
  struct Storage_;

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

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

  const std::optional<uint16_t>& a() const { return storage_.a; }
  ::std::optional<uint16_t>& a() { return storage_.a; }

  // Setter for a.
  //

  LocalTablePayload& a(std::optional<uint16_t> value);

  LocalTablePayload(::fidl::internal::DefaultConstructPossiblyInvalidObjectTag);

 private:
  struct Storage_ final {
    ::std::optional<uint16_t> a;
  };

  // TODO(https://fxbug.dev/42172795): Box the storage.
  Storage_ storage_;
  Storage_ CloneStorage_() const;
  friend struct ::fidl::internal::NaturalTableCodingTraits<::test_protocollayouts::LocalTablePayload>;
  friend struct ::fidl::internal::MemberVisitor<::test_protocollayouts::LocalTablePayload>;
  static constexpr auto kMembers = std::make_tuple(::fidl::internal::NaturalTableMember<Storage_, uint16_t, fidl::internal::NaturalCodingConstraintEmpty>{
      1, &Storage_::a});
};

class LocalUnionPayload {
 private:
  using Storage_ =
      std::variant<
          std::monostate, bool>;

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

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

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

  constexpr ::test_protocollayouts::LocalUnionPayload::Tag Which() const {
    return LocalUnionPayload::IndexToTag(storage_->index()).value();
  }
  static LocalUnionPayload WithB(bool val) {
    return LocalUnionPayload(std::make_shared<Storage_>(
        std::in_place_index_t<1>{},
        std::move(val)));
  }

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

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

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

  LocalUnionPayload& b(bool value) {
    storage_->emplace<1>(std::move(value));
    return *this;
  }

  LocalUnionPayload(::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_protocollayouts::LocalUnionPayload>;
  static constexpr auto kMembers = std::make_tuple(
      ::fidl::internal::NaturalUnionMember<::fidl::internal::NaturalCodingConstraintEmpty>(), ::fidl::internal::NaturalUnionMember<fidl::internal::NaturalCodingConstraintEmpty>());

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

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

  static constexpr std::optional<::test_protocollayouts::LocalUnionPayload::Tag> IndexToTag(size_t index) {
    switch (index) {
      case 1:
        return ::test_protocollayouts::LocalUnionPayload::Tag::kB;
      default:
        return ::test_protocollayouts::LocalUnionPayload::Tag::_do_not_handle_this__write_a_default_case_instead;
    }
  }
};

class MainProtocolTwoWayImportWithErrorResult {
 private:
  using Storage_ =
      std::variant<
          std::monostate, ::test_protocollayouts_imported::ImportUnionPayload, uint32_t>;

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

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

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

  constexpr ::test_protocollayouts::MainProtocolTwoWayImportWithErrorResult::Tag Which() const {
    return MainProtocolTwoWayImportWithErrorResult::IndexToTag(storage_->index()).value();
  }
  static MainProtocolTwoWayImportWithErrorResult WithResponse(::test_protocollayouts_imported::ImportUnionPayload val) {
    return MainProtocolTwoWayImportWithErrorResult(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.
  //

  MainProtocolTwoWayImportWithErrorResult& response(::test_protocollayouts_imported::ImportUnionPayload value) {
    storage_->emplace<1>(std::move(value));
    return *this;
  }
  static MainProtocolTwoWayImportWithErrorResult WithErr(uint32_t val) {
    return MainProtocolTwoWayImportWithErrorResult(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.
  //

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

  MainProtocolTwoWayImportWithErrorResult(::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_protocollayouts::MainProtocolTwoWayImportWithErrorResult>;
  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 MainProtocolTwoWayImportWithErrorResult(std::shared_ptr<Storage_> storage) : storage_(std::move(storage)) {}

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

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

class MainProtocolTwoWayLocalWithErrorResult {
 private:
  using Storage_ =
      std::variant<
          std::monostate, ::test_protocollayouts::LocalUnionPayload, uint32_t>;

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

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

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

  constexpr ::test_protocollayouts::MainProtocolTwoWayLocalWithErrorResult::Tag Which() const {
    return MainProtocolTwoWayLocalWithErrorResult::IndexToTag(storage_->index()).value();
  }
  static MainProtocolTwoWayLocalWithErrorResult WithResponse(::test_protocollayouts::LocalUnionPayload val) {
    return MainProtocolTwoWayLocalWithErrorResult(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.
  //

  MainProtocolTwoWayLocalWithErrorResult& response(::test_protocollayouts::LocalUnionPayload value) {
    storage_->emplace<1>(std::move(value));
    return *this;
  }
  static MainProtocolTwoWayLocalWithErrorResult WithErr(uint32_t val) {
    return MainProtocolTwoWayLocalWithErrorResult(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.
  //

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

  MainProtocolTwoWayLocalWithErrorResult(::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_protocollayouts::MainProtocolTwoWayLocalWithErrorResult>;
  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 MainProtocolTwoWayLocalWithErrorResult(std::shared_ptr<Storage_> storage) : storage_(std::move(storage)) {}

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

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

class MainProtocolOneWayAnonRequest {
 private:
  struct Storage_;

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

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

  const std::optional<uint16_t>& a() const { return storage_.a; }
  ::std::optional<uint16_t>& a() { return storage_.a; }

  // Setter for a.
  //

  MainProtocolOneWayAnonRequest& a(std::optional<uint16_t> value);

  MainProtocolOneWayAnonRequest(::fidl::internal::DefaultConstructPossiblyInvalidObjectTag);

 private:
  struct Storage_ final {
    ::std::optional<uint16_t> a;
  };

  // TODO(https://fxbug.dev/42172795): Box the storage.
  Storage_ storage_;
  Storage_ CloneStorage_() const;
  friend struct ::fidl::internal::NaturalTableCodingTraits<::test_protocollayouts::MainProtocolOneWayAnonRequest>;
  friend struct ::fidl::internal::MemberVisitor<::test_protocollayouts::MainProtocolOneWayAnonRequest>;
  static constexpr auto kMembers = std::make_tuple(::fidl::internal::NaturalTableMember<Storage_, uint16_t, fidl::internal::NaturalCodingConstraintEmpty>{
      1, &Storage_::a});
};

class MainProtocolTwoWayAnonRequest {
 private:
  using Storage_ =
      std::variant<
          std::monostate, bool>;

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

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

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

  constexpr ::test_protocollayouts::MainProtocolTwoWayAnonRequest::Tag Which() const {
    return MainProtocolTwoWayAnonRequest::IndexToTag(storage_->index()).value();
  }
  static MainProtocolTwoWayAnonRequest WithB(bool val) {
    return MainProtocolTwoWayAnonRequest(std::make_shared<Storage_>(
        std::in_place_index_t<1>{},
        std::move(val)));
  }

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

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

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

  MainProtocolTwoWayAnonRequest& b(bool value) {
    storage_->emplace<1>(std::move(value));
    return *this;
  }

  MainProtocolTwoWayAnonRequest(::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_protocollayouts::MainProtocolTwoWayAnonRequest>;
  static constexpr auto kMembers = std::make_tuple(
      ::fidl::internal::NaturalUnionMember<::fidl::internal::NaturalCodingConstraintEmpty>(), ::fidl::internal::NaturalUnionMember<fidl::internal::NaturalCodingConstraintEmpty>());

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

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

  static constexpr std::optional<::test_protocollayouts::MainProtocolTwoWayAnonRequest::Tag> IndexToTag(size_t index) {
    switch (index) {
      case 1:
        return ::test_protocollayouts::MainProtocolTwoWayAnonRequest::Tag::kB;
      default:
        return ::test_protocollayouts::MainProtocolTwoWayAnonRequest::Tag::_do_not_handle_this__write_a_default_case_instead;
    }
  }
};

class MainProtocolTwoWayAnonResponse {
 private:
  struct Storage_;

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

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

  const std::optional<uint16_t>& a() const { return storage_.a; }
  ::std::optional<uint16_t>& a() { return storage_.a; }

  // Setter for a.
  //

  MainProtocolTwoWayAnonResponse& a(std::optional<uint16_t> value);

  MainProtocolTwoWayAnonResponse(::fidl::internal::DefaultConstructPossiblyInvalidObjectTag);

 private:
  struct Storage_ final {
    ::std::optional<uint16_t> a;
  };

  // TODO(https://fxbug.dev/42172795): Box the storage.
  Storage_ storage_;
  Storage_ CloneStorage_() const;
  friend struct ::fidl::internal::NaturalTableCodingTraits<::test_protocollayouts::MainProtocolTwoWayAnonResponse>;
  friend struct ::fidl::internal::MemberVisitor<::test_protocollayouts::MainProtocolTwoWayAnonResponse>;
  static constexpr auto kMembers = std::make_tuple(::fidl::internal::NaturalTableMember<Storage_, uint16_t, fidl::internal::NaturalCodingConstraintEmpty>{
      1, &Storage_::a});
};

class MainProtocolTwoWayAnonWithErrorRequest {
 private:
  struct Storage_;

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

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

  const std::optional<uint16_t>& a() const { return storage_.a; }
  ::std::optional<uint16_t>& a() { return storage_.a; }

  // Setter for a.
  //

  MainProtocolTwoWayAnonWithErrorRequest& a(std::optional<uint16_t> value);

  MainProtocolTwoWayAnonWithErrorRequest(::fidl::internal::DefaultConstructPossiblyInvalidObjectTag);

 private:
  struct Storage_ final {
    ::std::optional<uint16_t> a;
  };

  // TODO(https://fxbug.dev/42172795): Box the storage.
  Storage_ storage_;
  Storage_ CloneStorage_() const;
  friend struct ::fidl::internal::NaturalTableCodingTraits<::test_protocollayouts::MainProtocolTwoWayAnonWithErrorRequest>;
  friend struct ::fidl::internal::MemberVisitor<::test_protocollayouts::MainProtocolTwoWayAnonWithErrorRequest>;
  static constexpr auto kMembers = std::make_tuple(::fidl::internal::NaturalTableMember<Storage_, uint16_t, fidl::internal::NaturalCodingConstraintEmpty>{
      1, &Storage_::a});
};

class MainProtocolTwoWayAnonWithErrorResponse {
 private:
  using Storage_ =
      std::variant<
          std::monostate, bool>;

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

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

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

  constexpr ::test_protocollayouts::MainProtocolTwoWayAnonWithErrorResponse::Tag Which() const {
    return MainProtocolTwoWayAnonWithErrorResponse::IndexToTag(storage_->index()).value();
  }
  static MainProtocolTwoWayAnonWithErrorResponse WithB(bool val) {
    return MainProtocolTwoWayAnonWithErrorResponse(std::make_shared<Storage_>(
        std::in_place_index_t<1>{},
        std::move(val)));
  }

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

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

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

  MainProtocolTwoWayAnonWithErrorResponse& b(bool value) {
    storage_->emplace<1>(std::move(value));
    return *this;
  }

  MainProtocolTwoWayAnonWithErrorResponse(::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_protocollayouts::MainProtocolTwoWayAnonWithErrorResponse>;
  static constexpr auto kMembers = std::make_tuple(
      ::fidl::internal::NaturalUnionMember<::fidl::internal::NaturalCodingConstraintEmpty>(), ::fidl::internal::NaturalUnionMember<fidl::internal::NaturalCodingConstraintEmpty>());

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

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

  static constexpr std::optional<::test_protocollayouts::MainProtocolTwoWayAnonWithErrorResponse::Tag> IndexToTag(size_t index) {
    switch (index) {
      case 1:
        return ::test_protocollayouts::MainProtocolTwoWayAnonWithErrorResponse::Tag::kB;
      default:
        return ::test_protocollayouts::MainProtocolTwoWayAnonWithErrorResponse::Tag::_do_not_handle_this__write_a_default_case_instead;
    }
  }
};

class MainProtocolTwoWayAnonWithErrorResult {
 private:
  using Storage_ =
      std::variant<
          std::monostate, ::test_protocollayouts::MainProtocolTwoWayAnonWithErrorResponse, uint32_t>;

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

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

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

  constexpr ::test_protocollayouts::MainProtocolTwoWayAnonWithErrorResult::Tag Which() const {
    return MainProtocolTwoWayAnonWithErrorResult::IndexToTag(storage_->index()).value();
  }
  static MainProtocolTwoWayAnonWithErrorResult WithResponse(::test_protocollayouts::MainProtocolTwoWayAnonWithErrorResponse val) {
    return MainProtocolTwoWayAnonWithErrorResult(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.
  //

  MainProtocolTwoWayAnonWithErrorResult& response(::test_protocollayouts::MainProtocolTwoWayAnonWithErrorResponse value) {
    storage_->emplace<1>(std::move(value));
    return *this;
  }
  static MainProtocolTwoWayAnonWithErrorResult WithErr(uint32_t val) {
    return MainProtocolTwoWayAnonWithErrorResult(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.
  //

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

  MainProtocolTwoWayAnonWithErrorResult(::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_protocollayouts::MainProtocolTwoWayAnonWithErrorResult>;
  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 MainProtocolTwoWayAnonWithErrorResult(std::shared_ptr<Storage_> storage) : storage_(std::move(storage)) {}

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

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

class MainProtocolOnAnonRequest {
 private:
  using Storage_ =
      std::variant<
          std::monostate, bool>;

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

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

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

  constexpr ::test_protocollayouts::MainProtocolOnAnonRequest::Tag Which() const {
    return MainProtocolOnAnonRequest::IndexToTag(storage_->index()).value();
  }
  static MainProtocolOnAnonRequest WithB(bool val) {
    return MainProtocolOnAnonRequest(std::make_shared<Storage_>(
        std::in_place_index_t<1>{},
        std::move(val)));
  }

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

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

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

  MainProtocolOnAnonRequest& b(bool value) {
    storage_->emplace<1>(std::move(value));
    return *this;
  }

  MainProtocolOnAnonRequest(::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_protocollayouts::MainProtocolOnAnonRequest>;
  static constexpr auto kMembers = std::make_tuple(
      ::fidl::internal::NaturalUnionMember<::fidl::internal::NaturalCodingConstraintEmpty>(), ::fidl::internal::NaturalUnionMember<fidl::internal::NaturalCodingConstraintEmpty>());

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

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

  static constexpr std::optional<::test_protocollayouts::MainProtocolOnAnonRequest::Tag> IndexToTag(size_t index) {
    switch (index) {
      case 1:
        return ::test_protocollayouts::MainProtocolOnAnonRequest::Tag::kB;
      default:
        return ::test_protocollayouts::MainProtocolOnAnonRequest::Tag::_do_not_handle_this__write_a_default_case_instead;
    }
  }
};

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

inline LocalTablePayload::LocalTablePayload(::fidl::internal::DefaultConstructPossiblyInvalidObjectTag) : LocalTablePayload(Storage_{}) {}
inline LocalTablePayload& LocalTablePayload::a(std::optional<uint16_t> value) {
  storage_.a = std::move(value);
  return *this;
}

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

inline MainProtocolOneWayAnonRequest::MainProtocolOneWayAnonRequest(::fidl::internal::DefaultConstructPossiblyInvalidObjectTag) : MainProtocolOneWayAnonRequest(Storage_{}) {}
inline MainProtocolOneWayAnonRequest& MainProtocolOneWayAnonRequest::a(std::optional<uint16_t> value) {
  storage_.a = std::move(value);
  return *this;
}

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

inline MainProtocolTwoWayAnonResponse::MainProtocolTwoWayAnonResponse(::fidl::internal::DefaultConstructPossiblyInvalidObjectTag) : MainProtocolTwoWayAnonResponse(Storage_{}) {}
inline MainProtocolTwoWayAnonResponse& MainProtocolTwoWayAnonResponse::a(std::optional<uint16_t> value) {
  storage_.a = std::move(value);
  return *this;
}

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

inline MainProtocolTwoWayAnonWithErrorRequest::MainProtocolTwoWayAnonWithErrorRequest(::fidl::internal::DefaultConstructPossiblyInvalidObjectTag) : MainProtocolTwoWayAnonWithErrorRequest(Storage_{}) {}
inline MainProtocolTwoWayAnonWithErrorRequest& MainProtocolTwoWayAnonWithErrorRequest::a(std::optional<uint16_t> value) {
  storage_.a = std::move(value);
  return *this;
}

}  // namespace test_protocollayouts
namespace fidl {

template <>
struct IsFidlType<::test_protocollayouts::LocalTablePayload> : public std::true_type {};

template <>
struct TypeTraits<::test_protocollayouts::LocalTablePayload> {
  static constexpr uint32_t kMaxNumHandles = 0;
  static constexpr uint32_t kMaxDepth = 2;
  static constexpr uint32_t kPrimarySize = 16;
  static constexpr uint32_t kMaxOutOfLine = 8;
  static constexpr bool kHasPointer = true;
};

template <>
struct IsTable<::test_protocollayouts::LocalTablePayload> : public std::true_type {};

template <>
struct internal::NaturalCodingTraits<::test_protocollayouts::LocalTablePayload, ::fidl::internal::NaturalCodingConstraintEmpty> : public ::fidl::internal::NaturalTableCodingTraits<::test_protocollayouts::LocalTablePayload> {};

template <>
struct IsFidlType<::test_protocollayouts::MainProtocolOneWayAnonRequest> : public std::true_type {};

template <>
struct TypeTraits<::test_protocollayouts::MainProtocolOneWayAnonRequest> {
  static constexpr uint32_t kMaxNumHandles = 0;
  static constexpr uint32_t kMaxDepth = 2;
  static constexpr uint32_t kPrimarySize = 16;
  static constexpr uint32_t kMaxOutOfLine = 8;
  static constexpr bool kHasPointer = true;
};

template <>
struct IsTable<::test_protocollayouts::MainProtocolOneWayAnonRequest> : public std::true_type {};

template <>
struct internal::NaturalCodingTraits<::test_protocollayouts::MainProtocolOneWayAnonRequest, ::fidl::internal::NaturalCodingConstraintEmpty> : public ::fidl::internal::NaturalTableCodingTraits<::test_protocollayouts::MainProtocolOneWayAnonRequest> {};

template <>
struct IsFidlType<::test_protocollayouts::MainProtocolTwoWayAnonResponse> : public std::true_type {};

template <>
struct TypeTraits<::test_protocollayouts::MainProtocolTwoWayAnonResponse> {
  static constexpr uint32_t kMaxNumHandles = 0;
  static constexpr uint32_t kMaxDepth = 2;
  static constexpr uint32_t kPrimarySize = 16;
  static constexpr uint32_t kMaxOutOfLine = 8;
  static constexpr bool kHasPointer = true;
};

template <>
struct IsTable<::test_protocollayouts::MainProtocolTwoWayAnonResponse> : public std::true_type {};

template <>
struct internal::NaturalCodingTraits<::test_protocollayouts::MainProtocolTwoWayAnonResponse, ::fidl::internal::NaturalCodingConstraintEmpty> : public ::fidl::internal::NaturalTableCodingTraits<::test_protocollayouts::MainProtocolTwoWayAnonResponse> {};

template <>
struct IsFidlType<::test_protocollayouts::MainProtocolTwoWayAnonWithErrorRequest> : public std::true_type {};

template <>
struct TypeTraits<::test_protocollayouts::MainProtocolTwoWayAnonWithErrorRequest> {
  static constexpr uint32_t kMaxNumHandles = 0;
  static constexpr uint32_t kMaxDepth = 2;
  static constexpr uint32_t kPrimarySize = 16;
  static constexpr uint32_t kMaxOutOfLine = 8;
  static constexpr bool kHasPointer = true;
};

template <>
struct IsTable<::test_protocollayouts::MainProtocolTwoWayAnonWithErrorRequest> : public std::true_type {};

template <>
struct internal::NaturalCodingTraits<::test_protocollayouts::MainProtocolTwoWayAnonWithErrorRequest, ::fidl::internal::NaturalCodingConstraintEmpty> : public ::fidl::internal::NaturalTableCodingTraits<::test_protocollayouts::MainProtocolTwoWayAnonWithErrorRequest> {};

template <>
struct IsFidlType<::test_protocollayouts::LocalUnionPayload> : public std::true_type {};

template <>
struct TypeTraits<::test_protocollayouts::LocalUnionPayload> {
  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_protocollayouts::LocalUnionPayload> : public std::true_type {};

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

template <>
struct IsFidlType<::test_protocollayouts::MainProtocolTwoWayImportWithErrorResult> : public std::true_type {};

template <>
struct TypeTraits<::test_protocollayouts::MainProtocolTwoWayImportWithErrorResult> {
  static constexpr uint32_t kMaxNumHandles = 0;
  static constexpr uint32_t kMaxDepth = 2;
  static constexpr uint32_t kPrimarySize = 16;
  static constexpr uint32_t kMaxOutOfLine = 16;
  static constexpr bool kHasPointer = true;
};

template <>
struct IsUnion<::test_protocollayouts::MainProtocolTwoWayImportWithErrorResult> : public std::true_type {};

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

template <>
struct IsFidlType<::test_protocollayouts::MainProtocolTwoWayLocalWithErrorResult> : public std::true_type {};

template <>
struct TypeTraits<::test_protocollayouts::MainProtocolTwoWayLocalWithErrorResult> {
  static constexpr uint32_t kMaxNumHandles = 0;
  static constexpr uint32_t kMaxDepth = 2;
  static constexpr uint32_t kPrimarySize = 16;
  static constexpr uint32_t kMaxOutOfLine = 16;
  static constexpr bool kHasPointer = true;
};

template <>
struct IsUnion<::test_protocollayouts::MainProtocolTwoWayLocalWithErrorResult> : public std::true_type {};

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

template <>
struct IsFidlType<::test_protocollayouts::MainProtocolTwoWayAnonRequest> : public std::true_type {};

template <>
struct TypeTraits<::test_protocollayouts::MainProtocolTwoWayAnonRequest> {
  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_protocollayouts::MainProtocolTwoWayAnonRequest> : public std::true_type {};

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

template <>
struct IsFidlType<::test_protocollayouts::MainProtocolTwoWayAnonWithErrorResponse> : public std::true_type {};

template <>
struct TypeTraits<::test_protocollayouts::MainProtocolTwoWayAnonWithErrorResponse> {
  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_protocollayouts::MainProtocolTwoWayAnonWithErrorResponse> : public std::true_type {};

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

template <>
struct IsFidlType<::test_protocollayouts::MainProtocolTwoWayAnonWithErrorResult> : public std::true_type {};

template <>
struct TypeTraits<::test_protocollayouts::MainProtocolTwoWayAnonWithErrorResult> {
  static constexpr uint32_t kMaxNumHandles = 0;
  static constexpr uint32_t kMaxDepth = 2;
  static constexpr uint32_t kPrimarySize = 16;
  static constexpr uint32_t kMaxOutOfLine = 16;
  static constexpr bool kHasPointer = true;
};

template <>
struct IsUnion<::test_protocollayouts::MainProtocolTwoWayAnonWithErrorResult> : public std::true_type {};

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

template <>
struct IsFidlType<::test_protocollayouts::MainProtocolOnAnonRequest> : public std::true_type {};

template <>
struct TypeTraits<::test_protocollayouts::MainProtocolOnAnonRequest> {
  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_protocollayouts::MainProtocolOnAnonRequest> : public std::true_type {};

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

#pragma clang diagnostic pop

}  // namespace fidl
