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

// fidl_experiment = output_index_json

#pragma once

#include <fidl/test.protocolpayloads/cpp/common_types.h>
#include <fidl/test.protocolpayloads/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.protocolpayloads.imported/cpp/natural_types.h>
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wshadow"

namespace test_protocolpayloads {

class LocalStructPayload;

class MainProtocolOneWayAnonRequest;

class MainProtocolTwoWayAnonRequest;

class MainProtocolTwoWayAnonResponse;

class MainProtocolTwoWayAnonWithErrorRequest;

class MainProtocolTwoWayAnonWithErrorResponse;

class MainProtocolOnAnonRequest;

class MainProtocolTwoWayLocalWithErrorResult;

class MainProtocolTwoWayAnonWithErrorResult;

class MainProtocolTwoWayImportWithErrorResult;

class LocalStructPayload {
 private:
  struct Storage_;

 public:
  LocalStructPayload(Storage_ storage) noexcept;
  LocalStructPayload(uint32_t a, uint32_t b) noexcept;

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

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

  bool operator==(const LocalStructPayload& other) const noexcept {
    return ::fidl::internal::NaturalStructCodingTraits<::test_protocolpayloads::LocalStructPayload, 8>::Equal(this, &other);
  }
  bool operator!=(const LocalStructPayload& other) const noexcept {
    return !::fidl::internal::NaturalStructCodingTraits<::test_protocolpayloads::LocalStructPayload, 8>::Equal(this, &other);
  }

  uint32_t
  a() const {
    return storage_.a;
  }

  uint32_t& a() {
    return storage_.a;
  }

  // Setter for a.
  //

  LocalStructPayload& a(uint32_t value);

  uint32_t
  b() const {
    return storage_.b;
  }

  uint32_t& b() {
    return storage_.b;
  }

  // Setter for b.
  //

  LocalStructPayload& b(uint32_t value);

  LocalStructPayload(::fidl::internal::DefaultConstructPossiblyInvalidObjectTag);

 private:
  struct Storage_ final {
    uint32_t a = {};
    uint32_t b = {};
  };

  Storage_ storage_;
  Storage_ CloneStorage_() const;

  friend struct ::fidl::internal::NaturalStructCodingTraits<::test_protocolpayloads::LocalStructPayload, 8>;
  friend struct ::fidl::internal::MemberVisitor<::test_protocolpayloads::LocalStructPayload>;
  static constexpr auto kMembers = std::make_tuple(::fidl::internal::NaturalStructMember<Storage_, uint32_t, fidl::internal::NaturalCodingConstraintEmpty>{
                                                       &Storage_::a, 0},
                                                   ::fidl::internal::NaturalStructMember<Storage_, uint32_t, fidl::internal::NaturalCodingConstraintEmpty>{&Storage_::b, 4});
  static constexpr auto kPadding = std::make_tuple();
};

class MainProtocolTwoWayLocalWithErrorResult {
 private:
  using Storage_ =
      std::variant<
          std::monostate, ::test_protocolpayloads::LocalStructPayload, 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_protocolpayloads::MainProtocolTwoWayLocalWithErrorResult::Tag Which() const {
    return MainProtocolTwoWayLocalWithErrorResult::IndexToTag(storage_->index()).value();
  }
  static MainProtocolTwoWayLocalWithErrorResult WithResponse(::test_protocolpayloads::LocalStructPayload 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_protocolpayloads::LocalStructPayload 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_protocolpayloads::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_protocolpayloads::MainProtocolTwoWayLocalWithErrorResult::Tag tag) {
    switch (tag) {
      case ::test_protocolpayloads::MainProtocolTwoWayLocalWithErrorResult::Tag::kResponse:
        return 1;
      case ::test_protocolpayloads::MainProtocolTwoWayLocalWithErrorResult::Tag::kErr:
        return 2;
      default: {
        decoder->SetError(::fidl::internal::kCodingErrorUnknownUnionTag);
        return 0;
      }
    }
  }

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

class MainProtocolOneWayAnonRequest {
 private:
  struct Storage_;

 public:
  MainProtocolOneWayAnonRequest(Storage_ storage) noexcept;
  MainProtocolOneWayAnonRequest(uint32_t a, uint32_t b) noexcept;

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

  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::NaturalStructCodingTraits<::test_protocolpayloads::MainProtocolOneWayAnonRequest, 8>::Equal(this, &other);
  }
  bool operator!=(const MainProtocolOneWayAnonRequest& other) const noexcept {
    return !::fidl::internal::NaturalStructCodingTraits<::test_protocolpayloads::MainProtocolOneWayAnonRequest, 8>::Equal(this, &other);
  }

  uint32_t
  a() const {
    return storage_.a;
  }

  uint32_t& a() {
    return storage_.a;
  }

  // Setter for a.
  //

  MainProtocolOneWayAnonRequest& a(uint32_t value);

  uint32_t
  b() const {
    return storage_.b;
  }

  uint32_t& b() {
    return storage_.b;
  }

  // Setter for b.
  //

  MainProtocolOneWayAnonRequest& b(uint32_t value);

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

 private:
  struct Storage_ final {
    uint32_t a = {};
    uint32_t b = {};
  };

  Storage_ storage_;
  Storage_ CloneStorage_() const;

  friend struct ::fidl::internal::NaturalStructCodingTraits<::test_protocolpayloads::MainProtocolOneWayAnonRequest, 8>;
  friend struct ::fidl::internal::MemberVisitor<::test_protocolpayloads::MainProtocolOneWayAnonRequest>;
  static constexpr auto kMembers = std::make_tuple(::fidl::internal::NaturalStructMember<Storage_, uint32_t, fidl::internal::NaturalCodingConstraintEmpty>{
                                                       &Storage_::a, 0},
                                                   ::fidl::internal::NaturalStructMember<Storage_, uint32_t, fidl::internal::NaturalCodingConstraintEmpty>{&Storage_::b, 4});
  static constexpr auto kPadding = std::make_tuple();
};

class MainProtocolTwoWayAnonRequest {
 private:
  struct Storage_;

 public:
  MainProtocolTwoWayAnonRequest(Storage_ storage) noexcept;
  MainProtocolTwoWayAnonRequest(uint32_t a, uint32_t b) noexcept;

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

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

  bool operator==(const MainProtocolTwoWayAnonRequest& other) const noexcept {
    return ::fidl::internal::NaturalStructCodingTraits<::test_protocolpayloads::MainProtocolTwoWayAnonRequest, 8>::Equal(this, &other);
  }
  bool operator!=(const MainProtocolTwoWayAnonRequest& other) const noexcept {
    return !::fidl::internal::NaturalStructCodingTraits<::test_protocolpayloads::MainProtocolTwoWayAnonRequest, 8>::Equal(this, &other);
  }

  uint32_t
  a() const {
    return storage_.a;
  }

  uint32_t& a() {
    return storage_.a;
  }

  // Setter for a.
  //

  MainProtocolTwoWayAnonRequest& a(uint32_t value);

  uint32_t
  b() const {
    return storage_.b;
  }

  uint32_t& b() {
    return storage_.b;
  }

  // Setter for b.
  //

  MainProtocolTwoWayAnonRequest& b(uint32_t value);

  MainProtocolTwoWayAnonRequest(::fidl::internal::DefaultConstructPossiblyInvalidObjectTag);

 private:
  struct Storage_ final {
    uint32_t a = {};
    uint32_t b = {};
  };

  Storage_ storage_;
  Storage_ CloneStorage_() const;

  friend struct ::fidl::internal::NaturalStructCodingTraits<::test_protocolpayloads::MainProtocolTwoWayAnonRequest, 8>;
  friend struct ::fidl::internal::MemberVisitor<::test_protocolpayloads::MainProtocolTwoWayAnonRequest>;
  static constexpr auto kMembers = std::make_tuple(::fidl::internal::NaturalStructMember<Storage_, uint32_t, fidl::internal::NaturalCodingConstraintEmpty>{
                                                       &Storage_::a, 0},
                                                   ::fidl::internal::NaturalStructMember<Storage_, uint32_t, fidl::internal::NaturalCodingConstraintEmpty>{&Storage_::b, 4});
  static constexpr auto kPadding = std::make_tuple();
};

class MainProtocolTwoWayAnonResponse {
 private:
  struct Storage_;

 public:
  MainProtocolTwoWayAnonResponse(Storage_ storage) noexcept;
  MainProtocolTwoWayAnonResponse(uint32_t a, uint32_t b) noexcept;

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

  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::NaturalStructCodingTraits<::test_protocolpayloads::MainProtocolTwoWayAnonResponse, 8>::Equal(this, &other);
  }
  bool operator!=(const MainProtocolTwoWayAnonResponse& other) const noexcept {
    return !::fidl::internal::NaturalStructCodingTraits<::test_protocolpayloads::MainProtocolTwoWayAnonResponse, 8>::Equal(this, &other);
  }

  uint32_t
  a() const {
    return storage_.a;
  }

  uint32_t& a() {
    return storage_.a;
  }

  // Setter for a.
  //

  MainProtocolTwoWayAnonResponse& a(uint32_t value);

  uint32_t
  b() const {
    return storage_.b;
  }

  uint32_t& b() {
    return storage_.b;
  }

  // Setter for b.
  //

  MainProtocolTwoWayAnonResponse& b(uint32_t value);

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

 private:
  struct Storage_ final {
    uint32_t a = {};
    uint32_t b = {};
  };

  Storage_ storage_;
  Storage_ CloneStorage_() const;

  friend struct ::fidl::internal::NaturalStructCodingTraits<::test_protocolpayloads::MainProtocolTwoWayAnonResponse, 8>;
  friend struct ::fidl::internal::MemberVisitor<::test_protocolpayloads::MainProtocolTwoWayAnonResponse>;
  static constexpr auto kMembers = std::make_tuple(::fidl::internal::NaturalStructMember<Storage_, uint32_t, fidl::internal::NaturalCodingConstraintEmpty>{
                                                       &Storage_::a, 0},
                                                   ::fidl::internal::NaturalStructMember<Storage_, uint32_t, fidl::internal::NaturalCodingConstraintEmpty>{&Storage_::b, 4});
  static constexpr auto kPadding = std::make_tuple();
};

class MainProtocolTwoWayAnonWithErrorRequest {
 private:
  struct Storage_;

 public:
  MainProtocolTwoWayAnonWithErrorRequest(Storage_ storage) noexcept;
  MainProtocolTwoWayAnonWithErrorRequest(uint32_t a, uint32_t b) noexcept;

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

  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::NaturalStructCodingTraits<::test_protocolpayloads::MainProtocolTwoWayAnonWithErrorRequest, 8>::Equal(this, &other);
  }
  bool operator!=(const MainProtocolTwoWayAnonWithErrorRequest& other) const noexcept {
    return !::fidl::internal::NaturalStructCodingTraits<::test_protocolpayloads::MainProtocolTwoWayAnonWithErrorRequest, 8>::Equal(this, &other);
  }

  uint32_t
  a() const {
    return storage_.a;
  }

  uint32_t& a() {
    return storage_.a;
  }

  // Setter for a.
  //

  MainProtocolTwoWayAnonWithErrorRequest& a(uint32_t value);

  uint32_t
  b() const {
    return storage_.b;
  }

  uint32_t& b() {
    return storage_.b;
  }

  // Setter for b.
  //

  MainProtocolTwoWayAnonWithErrorRequest& b(uint32_t value);

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

 private:
  struct Storage_ final {
    uint32_t a = {};
    uint32_t b = {};
  };

  Storage_ storage_;
  Storage_ CloneStorage_() const;

  friend struct ::fidl::internal::NaturalStructCodingTraits<::test_protocolpayloads::MainProtocolTwoWayAnonWithErrorRequest, 8>;
  friend struct ::fidl::internal::MemberVisitor<::test_protocolpayloads::MainProtocolTwoWayAnonWithErrorRequest>;
  static constexpr auto kMembers = std::make_tuple(::fidl::internal::NaturalStructMember<Storage_, uint32_t, fidl::internal::NaturalCodingConstraintEmpty>{
                                                       &Storage_::a, 0},
                                                   ::fidl::internal::NaturalStructMember<Storage_, uint32_t, fidl::internal::NaturalCodingConstraintEmpty>{&Storage_::b, 4});
  static constexpr auto kPadding = std::make_tuple();
};

class MainProtocolTwoWayAnonWithErrorResponse {
 private:
  struct Storage_;

 public:
  MainProtocolTwoWayAnonWithErrorResponse(Storage_ storage) noexcept;
  MainProtocolTwoWayAnonWithErrorResponse(uint32_t a, uint32_t b) noexcept;

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

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

  bool operator==(const MainProtocolTwoWayAnonWithErrorResponse& other) const noexcept {
    return ::fidl::internal::NaturalStructCodingTraits<::test_protocolpayloads::MainProtocolTwoWayAnonWithErrorResponse, 8>::Equal(this, &other);
  }
  bool operator!=(const MainProtocolTwoWayAnonWithErrorResponse& other) const noexcept {
    return !::fidl::internal::NaturalStructCodingTraits<::test_protocolpayloads::MainProtocolTwoWayAnonWithErrorResponse, 8>::Equal(this, &other);
  }

  uint32_t
  a() const {
    return storage_.a;
  }

  uint32_t& a() {
    return storage_.a;
  }

  // Setter for a.
  //

  MainProtocolTwoWayAnonWithErrorResponse& a(uint32_t value);

  uint32_t
  b() const {
    return storage_.b;
  }

  uint32_t& b() {
    return storage_.b;
  }

  // Setter for b.
  //

  MainProtocolTwoWayAnonWithErrorResponse& b(uint32_t value);

  MainProtocolTwoWayAnonWithErrorResponse(::fidl::internal::DefaultConstructPossiblyInvalidObjectTag);

 private:
  struct Storage_ final {
    uint32_t a = {};
    uint32_t b = {};
  };

  Storage_ storage_;
  Storage_ CloneStorage_() const;

  friend struct ::fidl::internal::NaturalStructCodingTraits<::test_protocolpayloads::MainProtocolTwoWayAnonWithErrorResponse, 8>;
  friend struct ::fidl::internal::MemberVisitor<::test_protocolpayloads::MainProtocolTwoWayAnonWithErrorResponse>;
  static constexpr auto kMembers = std::make_tuple(::fidl::internal::NaturalStructMember<Storage_, uint32_t, fidl::internal::NaturalCodingConstraintEmpty>{
                                                       &Storage_::a, 0},
                                                   ::fidl::internal::NaturalStructMember<Storage_, uint32_t, fidl::internal::NaturalCodingConstraintEmpty>{&Storage_::b, 4});
  static constexpr auto kPadding = std::make_tuple();
};

class MainProtocolTwoWayAnonWithErrorResult {
 private:
  using Storage_ =
      std::variant<
          std::monostate, ::test_protocolpayloads::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_protocolpayloads::MainProtocolTwoWayAnonWithErrorResult::Tag Which() const {
    return MainProtocolTwoWayAnonWithErrorResult::IndexToTag(storage_->index()).value();
  }
  static MainProtocolTwoWayAnonWithErrorResult WithResponse(::test_protocolpayloads::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_protocolpayloads::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_protocolpayloads::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_protocolpayloads::MainProtocolTwoWayAnonWithErrorResult::Tag tag) {
    switch (tag) {
      case ::test_protocolpayloads::MainProtocolTwoWayAnonWithErrorResult::Tag::kResponse:
        return 1;
      case ::test_protocolpayloads::MainProtocolTwoWayAnonWithErrorResult::Tag::kErr:
        return 2;
      default: {
        decoder->SetError(::fidl::internal::kCodingErrorUnknownUnionTag);
        return 0;
      }
    }
  }

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

class MainProtocolOnAnonRequest {
 private:
  struct Storage_;

 public:
  MainProtocolOnAnonRequest(Storage_ storage) noexcept;
  MainProtocolOnAnonRequest(uint32_t a, uint32_t b) noexcept;

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

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

  bool operator==(const MainProtocolOnAnonRequest& other) const noexcept {
    return ::fidl::internal::NaturalStructCodingTraits<::test_protocolpayloads::MainProtocolOnAnonRequest, 8>::Equal(this, &other);
  }
  bool operator!=(const MainProtocolOnAnonRequest& other) const noexcept {
    return !::fidl::internal::NaturalStructCodingTraits<::test_protocolpayloads::MainProtocolOnAnonRequest, 8>::Equal(this, &other);
  }

  uint32_t
  a() const {
    return storage_.a;
  }

  uint32_t& a() {
    return storage_.a;
  }

  // Setter for a.
  //

  MainProtocolOnAnonRequest& a(uint32_t value);

  uint32_t
  b() const {
    return storage_.b;
  }

  uint32_t& b() {
    return storage_.b;
  }

  // Setter for b.
  //

  MainProtocolOnAnonRequest& b(uint32_t value);

  MainProtocolOnAnonRequest(::fidl::internal::DefaultConstructPossiblyInvalidObjectTag);

 private:
  struct Storage_ final {
    uint32_t a = {};
    uint32_t b = {};
  };

  Storage_ storage_;
  Storage_ CloneStorage_() const;

  friend struct ::fidl::internal::NaturalStructCodingTraits<::test_protocolpayloads::MainProtocolOnAnonRequest, 8>;
  friend struct ::fidl::internal::MemberVisitor<::test_protocolpayloads::MainProtocolOnAnonRequest>;
  static constexpr auto kMembers = std::make_tuple(::fidl::internal::NaturalStructMember<Storage_, uint32_t, fidl::internal::NaturalCodingConstraintEmpty>{
                                                       &Storage_::a, 0},
                                                   ::fidl::internal::NaturalStructMember<Storage_, uint32_t, fidl::internal::NaturalCodingConstraintEmpty>{&Storage_::b, 4});
  static constexpr auto kPadding = std::make_tuple();
};

class MainProtocolTwoWayImportWithErrorResult {
 private:
  using Storage_ =
      std::variant<
          std::monostate, ::test_protocolpayloads_imported::ImportStructPayload, 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_protocolpayloads::MainProtocolTwoWayImportWithErrorResult::Tag Which() const {
    return MainProtocolTwoWayImportWithErrorResult::IndexToTag(storage_->index()).value();
  }
  static MainProtocolTwoWayImportWithErrorResult WithResponse(::test_protocolpayloads_imported::ImportStructPayload 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_protocolpayloads_imported::ImportStructPayload 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_protocolpayloads::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_protocolpayloads::MainProtocolTwoWayImportWithErrorResult::Tag tag) {
    switch (tag) {
      case ::test_protocolpayloads::MainProtocolTwoWayImportWithErrorResult::Tag::kResponse:
        return 1;
      case ::test_protocolpayloads::MainProtocolTwoWayImportWithErrorResult::Tag::kErr:
        return 2;
      default: {
        decoder->SetError(::fidl::internal::kCodingErrorUnknownUnionTag);
        return 0;
      }
    }
  }

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

inline LocalStructPayload::LocalStructPayload(Storage_ storage) noexcept : storage_(std::move(storage)) {}
inline LocalStructPayload::LocalStructPayload(uint32_t a, uint32_t b) noexcept
    : storage_({.a = std::move(a),
                .b = std::move(b)}) {}
inline LocalStructPayload::LocalStructPayload(const ::test_protocolpayloads::LocalStructPayload& other) noexcept : ::test_protocolpayloads::LocalStructPayload(other.CloneStorage_()) {}
inline LocalStructPayload& ::test_protocolpayloads::LocalStructPayload::operator=(const ::test_protocolpayloads::LocalStructPayload & other) noexcept {
  storage_ = other.CloneStorage_();
  return *this;
}

inline LocalStructPayload::LocalStructPayload(::fidl::internal::DefaultConstructPossiblyInvalidObjectTag) : LocalStructPayload(Storage_{
                                                                                                                .a = {},
                                                                                                                .b = {},
                                                                                                            }) {}
inline LocalStructPayload& LocalStructPayload::a(uint32_t value) {
  storage_.a = std::move(value);
  return *this;
}
inline LocalStructPayload& LocalStructPayload::b(uint32_t value) {
  storage_.b = std::move(value);
  return *this;
}

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

inline MainProtocolOneWayAnonRequest::MainProtocolOneWayAnonRequest(::fidl::internal::DefaultConstructPossiblyInvalidObjectTag) : MainProtocolOneWayAnonRequest(Storage_{
                                                                                                                                      .a = {},
                                                                                                                                      .b = {},
                                                                                                                                  }) {}
inline MainProtocolOneWayAnonRequest& MainProtocolOneWayAnonRequest::a(uint32_t value) {
  storage_.a = std::move(value);
  return *this;
}
inline MainProtocolOneWayAnonRequest& MainProtocolOneWayAnonRequest::b(uint32_t value) {
  storage_.b = std::move(value);
  return *this;
}

inline MainProtocolTwoWayAnonRequest::MainProtocolTwoWayAnonRequest(Storage_ storage) noexcept : storage_(std::move(storage)) {}
inline MainProtocolTwoWayAnonRequest::MainProtocolTwoWayAnonRequest(uint32_t a, uint32_t b) noexcept
    : storage_({.a = std::move(a),
                .b = std::move(b)}) {}
inline MainProtocolTwoWayAnonRequest::MainProtocolTwoWayAnonRequest(const ::test_protocolpayloads::MainProtocolTwoWayAnonRequest& other) noexcept : ::test_protocolpayloads::MainProtocolTwoWayAnonRequest(other.CloneStorage_()) {}
inline MainProtocolTwoWayAnonRequest& ::test_protocolpayloads::MainProtocolTwoWayAnonRequest::operator=(const ::test_protocolpayloads::MainProtocolTwoWayAnonRequest & other) noexcept {
  storage_ = other.CloneStorage_();
  return *this;
}

inline MainProtocolTwoWayAnonRequest::MainProtocolTwoWayAnonRequest(::fidl::internal::DefaultConstructPossiblyInvalidObjectTag) : MainProtocolTwoWayAnonRequest(Storage_{
                                                                                                                                      .a = {},
                                                                                                                                      .b = {},
                                                                                                                                  }) {}
inline MainProtocolTwoWayAnonRequest& MainProtocolTwoWayAnonRequest::a(uint32_t value) {
  storage_.a = std::move(value);
  return *this;
}
inline MainProtocolTwoWayAnonRequest& MainProtocolTwoWayAnonRequest::b(uint32_t value) {
  storage_.b = std::move(value);
  return *this;
}

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

inline MainProtocolTwoWayAnonResponse::MainProtocolTwoWayAnonResponse(::fidl::internal::DefaultConstructPossiblyInvalidObjectTag) : MainProtocolTwoWayAnonResponse(Storage_{
                                                                                                                                        .a = {},
                                                                                                                                        .b = {},
                                                                                                                                    }) {}
inline MainProtocolTwoWayAnonResponse& MainProtocolTwoWayAnonResponse::a(uint32_t value) {
  storage_.a = std::move(value);
  return *this;
}
inline MainProtocolTwoWayAnonResponse& MainProtocolTwoWayAnonResponse::b(uint32_t value) {
  storage_.b = std::move(value);
  return *this;
}

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

inline MainProtocolTwoWayAnonWithErrorRequest::MainProtocolTwoWayAnonWithErrorRequest(::fidl::internal::DefaultConstructPossiblyInvalidObjectTag) : MainProtocolTwoWayAnonWithErrorRequest(Storage_{
                                                                                                                                                        .a = {},
                                                                                                                                                        .b = {},
                                                                                                                                                    }) {}
inline MainProtocolTwoWayAnonWithErrorRequest& MainProtocolTwoWayAnonWithErrorRequest::a(uint32_t value) {
  storage_.a = std::move(value);
  return *this;
}
inline MainProtocolTwoWayAnonWithErrorRequest& MainProtocolTwoWayAnonWithErrorRequest::b(uint32_t value) {
  storage_.b = std::move(value);
  return *this;
}

inline MainProtocolTwoWayAnonWithErrorResponse::MainProtocolTwoWayAnonWithErrorResponse(Storage_ storage) noexcept : storage_(std::move(storage)) {}
inline MainProtocolTwoWayAnonWithErrorResponse::MainProtocolTwoWayAnonWithErrorResponse(uint32_t a, uint32_t b) noexcept
    : storage_({.a = std::move(a),
                .b = std::move(b)}) {}
inline MainProtocolTwoWayAnonWithErrorResponse::MainProtocolTwoWayAnonWithErrorResponse(const ::test_protocolpayloads::MainProtocolTwoWayAnonWithErrorResponse& other) noexcept : ::test_protocolpayloads::MainProtocolTwoWayAnonWithErrorResponse(other.CloneStorage_()) {}
inline MainProtocolTwoWayAnonWithErrorResponse& ::test_protocolpayloads::MainProtocolTwoWayAnonWithErrorResponse::operator=(const ::test_protocolpayloads::MainProtocolTwoWayAnonWithErrorResponse & other) noexcept {
  storage_ = other.CloneStorage_();
  return *this;
}

inline MainProtocolTwoWayAnonWithErrorResponse::MainProtocolTwoWayAnonWithErrorResponse(::fidl::internal::DefaultConstructPossiblyInvalidObjectTag) : MainProtocolTwoWayAnonWithErrorResponse(Storage_{
                                                                                                                                                          .a = {},
                                                                                                                                                          .b = {},
                                                                                                                                                      }) {}
inline MainProtocolTwoWayAnonWithErrorResponse& MainProtocolTwoWayAnonWithErrorResponse::a(uint32_t value) {
  storage_.a = std::move(value);
  return *this;
}
inline MainProtocolTwoWayAnonWithErrorResponse& MainProtocolTwoWayAnonWithErrorResponse::b(uint32_t value) {
  storage_.b = std::move(value);
  return *this;
}

inline MainProtocolOnAnonRequest::MainProtocolOnAnonRequest(Storage_ storage) noexcept : storage_(std::move(storage)) {}
inline MainProtocolOnAnonRequest::MainProtocolOnAnonRequest(uint32_t a, uint32_t b) noexcept
    : storage_({.a = std::move(a),
                .b = std::move(b)}) {}
inline MainProtocolOnAnonRequest::MainProtocolOnAnonRequest(const ::test_protocolpayloads::MainProtocolOnAnonRequest& other) noexcept : ::test_protocolpayloads::MainProtocolOnAnonRequest(other.CloneStorage_()) {}
inline MainProtocolOnAnonRequest& ::test_protocolpayloads::MainProtocolOnAnonRequest::operator=(const ::test_protocolpayloads::MainProtocolOnAnonRequest & other) noexcept {
  storage_ = other.CloneStorage_();
  return *this;
}

inline MainProtocolOnAnonRequest::MainProtocolOnAnonRequest(::fidl::internal::DefaultConstructPossiblyInvalidObjectTag) : MainProtocolOnAnonRequest(Storage_{
                                                                                                                              .a = {},
                                                                                                                              .b = {},
                                                                                                                          }) {}
inline MainProtocolOnAnonRequest& MainProtocolOnAnonRequest::a(uint32_t value) {
  storage_.a = std::move(value);
  return *this;
}
inline MainProtocolOnAnonRequest& MainProtocolOnAnonRequest::b(uint32_t value) {
  storage_.b = std::move(value);
  return *this;
}

}  // namespace test_protocolpayloads
namespace fidl {

template <>
struct IsFidlType<::test_protocolpayloads::LocalStructPayload> : public std::true_type {};

template <>
struct TypeTraits<::test_protocolpayloads::LocalStructPayload> {
  static constexpr uint32_t kMaxNumHandles = 0;
  static constexpr uint32_t kMaxDepth = 0;
  static constexpr uint32_t kPrimarySize = 8;
  static constexpr uint32_t kMaxOutOfLine = 0;
  static constexpr bool kHasPointer = false;
};

template <>
struct IsStruct<::test_protocolpayloads::LocalStructPayload> : public std::true_type {};

template <>
struct internal::NaturalCodingTraits<::test_protocolpayloads::LocalStructPayload, ::fidl::internal::NaturalCodingConstraintEmpty> final
    : public ::fidl::internal::NaturalStructCodingTraits<::test_protocolpayloads::LocalStructPayload, 8> {};

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

template <>
struct TypeTraits<::test_protocolpayloads::MainProtocolOneWayAnonRequest> {
  static constexpr uint32_t kMaxNumHandles = 0;
  static constexpr uint32_t kMaxDepth = 0;
  static constexpr uint32_t kPrimarySize = 8;
  static constexpr uint32_t kMaxOutOfLine = 0;
  static constexpr bool kHasPointer = false;
};

template <>
struct IsStruct<::test_protocolpayloads::MainProtocolOneWayAnonRequest> : public std::true_type {};

template <>
struct internal::NaturalCodingTraits<::test_protocolpayloads::MainProtocolOneWayAnonRequest, ::fidl::internal::NaturalCodingConstraintEmpty> final
    : public ::fidl::internal::NaturalStructCodingTraits<::test_protocolpayloads::MainProtocolOneWayAnonRequest, 8> {};

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

template <>
struct TypeTraits<::test_protocolpayloads::MainProtocolTwoWayAnonRequest> {
  static constexpr uint32_t kMaxNumHandles = 0;
  static constexpr uint32_t kMaxDepth = 0;
  static constexpr uint32_t kPrimarySize = 8;
  static constexpr uint32_t kMaxOutOfLine = 0;
  static constexpr bool kHasPointer = false;
};

template <>
struct IsStruct<::test_protocolpayloads::MainProtocolTwoWayAnonRequest> : public std::true_type {};

template <>
struct internal::NaturalCodingTraits<::test_protocolpayloads::MainProtocolTwoWayAnonRequest, ::fidl::internal::NaturalCodingConstraintEmpty> final
    : public ::fidl::internal::NaturalStructCodingTraits<::test_protocolpayloads::MainProtocolTwoWayAnonRequest, 8> {};

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

template <>
struct TypeTraits<::test_protocolpayloads::MainProtocolTwoWayAnonResponse> {
  static constexpr uint32_t kMaxNumHandles = 0;
  static constexpr uint32_t kMaxDepth = 0;
  static constexpr uint32_t kPrimarySize = 8;
  static constexpr uint32_t kMaxOutOfLine = 0;
  static constexpr bool kHasPointer = false;
};

template <>
struct IsStruct<::test_protocolpayloads::MainProtocolTwoWayAnonResponse> : public std::true_type {};

template <>
struct internal::NaturalCodingTraits<::test_protocolpayloads::MainProtocolTwoWayAnonResponse, ::fidl::internal::NaturalCodingConstraintEmpty> final
    : public ::fidl::internal::NaturalStructCodingTraits<::test_protocolpayloads::MainProtocolTwoWayAnonResponse, 8> {};

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

template <>
struct TypeTraits<::test_protocolpayloads::MainProtocolTwoWayAnonWithErrorRequest> {
  static constexpr uint32_t kMaxNumHandles = 0;
  static constexpr uint32_t kMaxDepth = 0;
  static constexpr uint32_t kPrimarySize = 8;
  static constexpr uint32_t kMaxOutOfLine = 0;
  static constexpr bool kHasPointer = false;
};

template <>
struct IsStruct<::test_protocolpayloads::MainProtocolTwoWayAnonWithErrorRequest> : public std::true_type {};

template <>
struct internal::NaturalCodingTraits<::test_protocolpayloads::MainProtocolTwoWayAnonWithErrorRequest, ::fidl::internal::NaturalCodingConstraintEmpty> final
    : public ::fidl::internal::NaturalStructCodingTraits<::test_protocolpayloads::MainProtocolTwoWayAnonWithErrorRequest, 8> {};

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

template <>
struct TypeTraits<::test_protocolpayloads::MainProtocolTwoWayAnonWithErrorResponse> {
  static constexpr uint32_t kMaxNumHandles = 0;
  static constexpr uint32_t kMaxDepth = 0;
  static constexpr uint32_t kPrimarySize = 8;
  static constexpr uint32_t kMaxOutOfLine = 0;
  static constexpr bool kHasPointer = false;
};

template <>
struct IsStruct<::test_protocolpayloads::MainProtocolTwoWayAnonWithErrorResponse> : public std::true_type {};

template <>
struct internal::NaturalCodingTraits<::test_protocolpayloads::MainProtocolTwoWayAnonWithErrorResponse, ::fidl::internal::NaturalCodingConstraintEmpty> final
    : public ::fidl::internal::NaturalStructCodingTraits<::test_protocolpayloads::MainProtocolTwoWayAnonWithErrorResponse, 8> {};

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

template <>
struct TypeTraits<::test_protocolpayloads::MainProtocolOnAnonRequest> {
  static constexpr uint32_t kMaxNumHandles = 0;
  static constexpr uint32_t kMaxDepth = 0;
  static constexpr uint32_t kPrimarySize = 8;
  static constexpr uint32_t kMaxOutOfLine = 0;
  static constexpr bool kHasPointer = false;
};

template <>
struct IsStruct<::test_protocolpayloads::MainProtocolOnAnonRequest> : public std::true_type {};

template <>
struct internal::NaturalCodingTraits<::test_protocolpayloads::MainProtocolOnAnonRequest, ::fidl::internal::NaturalCodingConstraintEmpty> final
    : public ::fidl::internal::NaturalStructCodingTraits<::test_protocolpayloads::MainProtocolOnAnonRequest, 8> {};

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

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

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

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

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

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

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

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

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

template <>
struct TypeTraits<::test_protocolpayloads::MainProtocolTwoWayImportWithErrorResult> {
  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_protocolpayloads::MainProtocolTwoWayImportWithErrorResult> : public std::true_type {};

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

#pragma clang diagnostic pop

}  // namespace fidl
