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

#pragma once

#include <lib/fidl/llcpp/array.h>
#include <lib/fidl/llcpp/coding.h>
#include <lib/fidl/llcpp/envelope.h>
#include <lib/fidl/llcpp/message.h>
#include <lib/fidl/llcpp/message_storage.h>
#include <lib/fidl/llcpp/object_view.h>
#include <lib/fidl/llcpp/string_view.h>
#include <lib/fidl/llcpp/traits.h>
#include <lib/fidl/llcpp/wire_types.h>
#include <lib/stdcompat/optional.h>

#include <cinttypes>
#ifdef __Fuchsia__
#include <lib/zx/channel.h>

#endif  // __Fuchsia__

#include <fidl/test.protocollayouts.imported/cpp/wire_types.h>
#include <fidl/test.protocollayouts/cpp/common_types.h>
#include <fidl/test.protocollayouts/cpp/markers.h>

namespace test_protocollayouts {
namespace wire {
struct MainProtocolTwoWayImportWithErrorTopResponse;

struct MainProtocolTwoWayAnonWithErrorTopResponse;

struct MainProtocolOnImportWithErrorRequest;

struct MainProtocolOnAnonWithErrorRequest;

struct MainProtocolTwoWayLocalWithErrorTopResponse;

struct MainProtocolOnLocalWithErrorRequest;

class MainProtocolOnAnonWithErrorResponse;

class MainProtocolTwoWayAnonWithErrorRequest;

class MainProtocolTwoWayAnonResponse;

class MainProtocolOneWayAnonRequest;

class LocalTablePayload;

class MainProtocolTwoWayImportWithErrorResult;

class MainProtocolTwoWayAnonWithErrorResponse;

class MainProtocolTwoWayAnonWithErrorResult;

class MainProtocolOnImportWithErrorResult;

class MainProtocolOnAnonWithErrorResult;

class MainProtocolTwoWayAnonRequest;

class MainProtocolOnAnonRequest;

class LocalUnionPayload;

class MainProtocolTwoWayLocalWithErrorResult;

class MainProtocolOnLocalWithErrorResult;

}  // namespace wire
}  // namespace test_protocollayouts
template <>
class ::fidl::WireTableBuilder<
    ::test_protocollayouts::wire::MainProtocolOnAnonWithErrorResponse>;
template <>
class ::fidl::WireTableExternalBuilder<
    ::test_protocollayouts::wire::MainProtocolOnAnonWithErrorResponse>;

template <>
struct ::fidl::WireTableFrame<
    ::test_protocollayouts::wire::MainProtocolOnAnonWithErrorResponse>
    final {
 public:
  WireTableFrame() = default;
  // In its intended usage, WireTableFrame will be referenced by an ObjectView.
  // If the ObjectView is assigned before a move or copy, then it will reference
  // the old invalid object. Because this is unsafe, copies are disallowed and
  // moves are only allowed by friend classes that operate safely.
  WireTableFrame(const WireTableFrame&) = delete;
  WireTableFrame& operator=(const WireTableFrame&) = delete;

 private:
  WireTableFrame(WireTableFrame&&) noexcept = default;
  WireTableFrame& operator=(WireTableFrame&&) noexcept = default;

  bool HasUnknownData() const;
  ::fidl::Envelope<uint16_t> a_;

  friend class ::test_protocollayouts::wire::
      MainProtocolOnAnonWithErrorResponse;
  friend ::fidl::internal::WireTableBaseBuilder<
      ::test_protocollayouts::wire::MainProtocolOnAnonWithErrorResponse,
      ::fidl::WireTableBuilder<
          ::test_protocollayouts::wire::MainProtocolOnAnonWithErrorResponse>>;
  friend ::fidl::internal::WireTableBaseBuilder<
      ::test_protocollayouts::wire::MainProtocolOnAnonWithErrorResponse,
      ::fidl::WireTableExternalBuilder<
          ::test_protocollayouts::wire::MainProtocolOnAnonWithErrorResponse>>;
};

namespace test_protocollayouts {
namespace wire {
extern "C" const fidl_type_t
    test_protocollayouts_MainProtocol_OnAnonWithError_ResponseTable;

class MainProtocolOnAnonWithErrorResponse {
 public:
  MainProtocolOnAnonWithErrorResponse() = default;
  MainProtocolOnAnonWithErrorResponse(
      const MainProtocolOnAnonWithErrorResponse& other) noexcept = default;
  MainProtocolOnAnonWithErrorResponse& operator=(
      const MainProtocolOnAnonWithErrorResponse& other) noexcept = default;
  MainProtocolOnAnonWithErrorResponse(
      MainProtocolOnAnonWithErrorResponse&& other) noexcept = default;
  MainProtocolOnAnonWithErrorResponse& operator=(
      MainProtocolOnAnonWithErrorResponse&& other) noexcept = default;

  ~MainProtocolOnAnonWithErrorResponse() = default;

  // Returns whether no field is set.
  bool IsEmpty() const { return max_ordinal_ == 0; }

  // Returns whether the table references unknown fields.
  bool HasUnknownData() const;

  // Return a builder that by defaults allocates of an arena.
  static ::fidl::WireTableBuilder<
      ::test_protocollayouts::wire::MainProtocolOnAnonWithErrorResponse>
  Builder(::fidl::AnyArena& arena);

  // Return a builder that relies on explicitly allocating |fidl::ObjectView|s.
  static ::fidl::WireTableExternalBuilder<
      ::test_protocollayouts::wire::MainProtocolOnAnonWithErrorResponse>
  ExternalBuilder(
      ::fidl::ObjectView<::fidl::WireTableFrame<
          ::test_protocollayouts::wire::MainProtocolOnAnonWithErrorResponse>>
          frame);

  const uint16_t& a() const {
    ZX_ASSERT(has_a());
    return frame_ptr_->a_.get_data();
  }
  uint16_t& a() {
    ZX_ASSERT(has_a());
    return frame_ptr_->a_.get_data();
  }
  bool has_a() const { return max_ordinal_ >= 1 && frame_ptr_->a_.has_data(); }
#if defined(FIDL_WIRE_ALLOW_DEPRECATED_MUTABLE_TABLES) || false
 public:
#else   // !defined(FIDL_WIRE_ALLOW_DEPRECATED_MUTABLE_TABLES)
 private:
#endif  // FIDL_WIRE_ALLOW_DEPRECATED_MUTABLE_TABLES

  MainProtocolOnAnonWithErrorResponse& set_a(uint16_t elem) {
    ZX_DEBUG_ASSERT(frame_ptr_ != nullptr);
    frame_ptr_->a_.set_data(std::move(elem));
    max_ordinal_ = std::max(max_ordinal_, static_cast<uint64_t>(1));
    return *this;
  }

  MainProtocolOnAnonWithErrorResponse& clear_a() {
    ZX_DEBUG_ASSERT(frame_ptr_ != nullptr);
    frame_ptr_->a_.clear_data();
    return *this;
  }

  explicit MainProtocolOnAnonWithErrorResponse(::fidl::AnyArena& allocator)
      : frame_ptr_(::fidl::ObjectView<::fidl::WireTableFrame<
                       ::test_protocollayouts::wire::
                           MainProtocolOnAnonWithErrorResponse>>(allocator)) {}
  // This constructor allows a user controlled allocation (not using a Arena).
  // It should only be used when performance is key.
  // As soon as the frame is given to the table, it must not be used directly or
  // for another table.
  explicit MainProtocolOnAnonWithErrorResponse(
      ::fidl::ObjectView<::fidl::WireTableFrame<
          ::test_protocollayouts::wire::MainProtocolOnAnonWithErrorResponse>>&&
          frame)
      : frame_ptr_(std::move(frame)) {}

  void Allocate(::fidl::AnyArena& allocator) {
    max_ordinal_ = 0;
    frame_ptr_ = ::fidl::ObjectView<::fidl::WireTableFrame<
        ::test_protocollayouts::wire::MainProtocolOnAnonWithErrorResponse>>(
        allocator);
  }
  void Init(
      ::fidl::ObjectView<::fidl::WireTableFrame<
          ::test_protocollayouts::wire::MainProtocolOnAnonWithErrorResponse>>&&
          frame_ptr) {
    max_ordinal_ = 0;
    frame_ptr_ = std::move(frame_ptr);
  }

 private:
  friend ::fidl::internal::WireTableBaseBuilder<
      ::test_protocollayouts::wire::MainProtocolOnAnonWithErrorResponse,
      ::fidl::WireTableBuilder<
          ::test_protocollayouts::wire::MainProtocolOnAnonWithErrorResponse>>;
  friend ::fidl::internal::WireTableBaseBuilder<
      ::test_protocollayouts::wire::MainProtocolOnAnonWithErrorResponse,
      ::fidl::WireTableExternalBuilder<
          ::test_protocollayouts::wire::MainProtocolOnAnonWithErrorResponse>>;

  uint64_t max_ordinal_ = 0;
  ::fidl::ObjectView<::fidl::WireTableFrame<
      ::test_protocollayouts::wire::MainProtocolOnAnonWithErrorResponse>>
      frame_ptr_;
};
}  // namespace wire
}  // namespace test_protocollayouts
template <typename BuilderImpl>
class ::fidl::internal::WireTableBaseBuilder<
    ::test_protocollayouts::wire::MainProtocolOnAnonWithErrorResponse,
    BuilderImpl> {
 public:
  // Build and return the table. The builder should not be used after this.
  ::test_protocollayouts::wire::MainProtocolOnAnonWithErrorResponse Build() {
    ZX_DEBUG_ASSERT(table_.frame_ptr_ != nullptr);
    ::test_protocollayouts::wire::MainProtocolOnAnonWithErrorResponse t =
        std::move(table_);
    // Poison this builder to prevent accidental reuse.
    table_.frame_ptr_ = nullptr;
    return t;
  }

  BuilderImpl& a(uint16_t elem) {
    ZX_DEBUG_ASSERT(table_.frame_ptr_ != nullptr);
    table_.frame_ptr_->a_.set_data(std::move(elem));
    table_.max_ordinal_ =
        std::max(table_.max_ordinal_, static_cast<uint64_t>(1));
    return *static_cast<BuilderImpl*>(this);
  }

 protected:
  WireTableBaseBuilder(
      ::fidl::ObjectView<::fidl::WireTableFrame<
          ::test_protocollayouts::wire::MainProtocolOnAnonWithErrorResponse>>&&
          frame)
      : table_(std::move(frame)) {}

 private:
  ::test_protocollayouts::wire::MainProtocolOnAnonWithErrorResponse table_;
};

template <>
class ::fidl::WireTableBuilder<
    ::test_protocollayouts::wire::MainProtocolOnAnonWithErrorResponse>
    final
    : public ::fidl::internal::WireTableBaseBuilder<
          ::test_protocollayouts::wire::MainProtocolOnAnonWithErrorResponse,
          ::fidl::WireTableBuilder<::test_protocollayouts::wire::
                                       MainProtocolOnAnonWithErrorResponse>> {
  using Base = ::fidl::internal::WireTableBaseBuilder<
      ::test_protocollayouts::wire::MainProtocolOnAnonWithErrorResponse,
      ::fidl::WireTableBuilder<
          ::test_protocollayouts::wire::MainProtocolOnAnonWithErrorResponse>>;

 public:
 private:
  friend class ::test_protocollayouts::wire::
      MainProtocolOnAnonWithErrorResponse;
  WireTableBuilder(::fidl::AnyArena& arena)
      : Base(::fidl::ObjectView<
             ::fidl::WireTableFrame<::test_protocollayouts::wire::
                                        MainProtocolOnAnonWithErrorResponse>>(
            arena)),
        arena_(arena) {}

  [[maybe_unused]] std::reference_wrapper<::fidl::AnyArena> arena_;
};

template <>
class ::fidl::WireTableExternalBuilder<
    ::test_protocollayouts::wire::MainProtocolOnAnonWithErrorResponse>
    final
    : public ::fidl::internal::WireTableBaseBuilder<
          ::test_protocollayouts::wire::MainProtocolOnAnonWithErrorResponse,
          ::fidl::WireTableExternalBuilder<
              ::test_protocollayouts::wire::
                  MainProtocolOnAnonWithErrorResponse>> {
  using Base = ::fidl::internal::WireTableBaseBuilder<
      ::test_protocollayouts::wire::MainProtocolOnAnonWithErrorResponse,
      ::fidl::WireTableExternalBuilder<
          ::test_protocollayouts::wire::MainProtocolOnAnonWithErrorResponse>>;

 private:
  friend class ::test_protocollayouts::wire::
      MainProtocolOnAnonWithErrorResponse;
  using Base::Base;
  WireTableExternalBuilder(
      ::fidl::WireTableFrame<
          ::test_protocollayouts::wire::MainProtocolOnAnonWithErrorResponse>*
          frame)
      : Base(::fidl::ObjectView<
             ::fidl::WireTableFrame<::test_protocollayouts::wire::
                                        MainProtocolOnAnonWithErrorResponse>>::
                 FromExternal(frame)) {}
};
namespace test_protocollayouts {
namespace wire {
inline ::fidl::WireTableBuilder<
    ::test_protocollayouts::wire::MainProtocolOnAnonWithErrorResponse>
MainProtocolOnAnonWithErrorResponse::Builder(::fidl::AnyArena& arena) {
  return ::fidl::WireTableBuilder<
      ::test_protocollayouts::wire::MainProtocolOnAnonWithErrorResponse>(arena);
}
inline ::fidl::WireTableExternalBuilder<
    ::test_protocollayouts::wire::MainProtocolOnAnonWithErrorResponse>
MainProtocolOnAnonWithErrorResponse::ExternalBuilder(
    ::fidl::ObjectView<::fidl::WireTableFrame<
        ::test_protocollayouts::wire::MainProtocolOnAnonWithErrorResponse>>
        frame) {
  return ::fidl::WireTableExternalBuilder<
      ::test_protocollayouts::wire::MainProtocolOnAnonWithErrorResponse>(
      std::move(frame));
}

}  // namespace wire
}  // namespace test_protocollayouts
template <>
class ::fidl::WireTableBuilder<
    ::test_protocollayouts::wire::MainProtocolTwoWayAnonWithErrorRequest>;
template <>
class ::fidl::WireTableExternalBuilder<
    ::test_protocollayouts::wire::MainProtocolTwoWayAnonWithErrorRequest>;

template <>
struct ::fidl::WireTableFrame<
    ::test_protocollayouts::wire::MainProtocolTwoWayAnonWithErrorRequest>
    final {
 public:
  WireTableFrame() = default;
  // In its intended usage, WireTableFrame will be referenced by an ObjectView.
  // If the ObjectView is assigned before a move or copy, then it will reference
  // the old invalid object. Because this is unsafe, copies are disallowed and
  // moves are only allowed by friend classes that operate safely.
  WireTableFrame(const WireTableFrame&) = delete;
  WireTableFrame& operator=(const WireTableFrame&) = delete;

 private:
  WireTableFrame(WireTableFrame&&) noexcept = default;
  WireTableFrame& operator=(WireTableFrame&&) noexcept = default;

  bool HasUnknownData() const;
  ::fidl::Envelope<uint16_t> a_;

  friend class ::test_protocollayouts::wire::
      MainProtocolTwoWayAnonWithErrorRequest;
  friend ::fidl::internal::WireTableBaseBuilder<
      ::test_protocollayouts::wire::MainProtocolTwoWayAnonWithErrorRequest,
      ::fidl::WireTableBuilder<::test_protocollayouts::wire::
                                   MainProtocolTwoWayAnonWithErrorRequest>>;
  friend ::fidl::internal::WireTableBaseBuilder<
      ::test_protocollayouts::wire::MainProtocolTwoWayAnonWithErrorRequest,
      ::fidl::WireTableExternalBuilder<
          ::test_protocollayouts::wire::
              MainProtocolTwoWayAnonWithErrorRequest>>;
};

namespace test_protocollayouts {
namespace wire {
extern "C" const fidl_type_t
    test_protocollayouts_MainProtocolTwoWayAnonWithErrorRequestTable;

class MainProtocolTwoWayAnonWithErrorRequest {
 public:
  MainProtocolTwoWayAnonWithErrorRequest() = default;
  MainProtocolTwoWayAnonWithErrorRequest(
      const MainProtocolTwoWayAnonWithErrorRequest& other) noexcept = default;
  MainProtocolTwoWayAnonWithErrorRequest& operator=(
      const MainProtocolTwoWayAnonWithErrorRequest& other) noexcept = default;
  MainProtocolTwoWayAnonWithErrorRequest(
      MainProtocolTwoWayAnonWithErrorRequest&& other) noexcept = default;
  MainProtocolTwoWayAnonWithErrorRequest& operator=(
      MainProtocolTwoWayAnonWithErrorRequest&& other) noexcept = default;

  ~MainProtocolTwoWayAnonWithErrorRequest() = default;

  // Returns whether no field is set.
  bool IsEmpty() const { return max_ordinal_ == 0; }

  // Returns whether the table references unknown fields.
  bool HasUnknownData() const;

  // Return a builder that by defaults allocates of an arena.
  static ::fidl::WireTableBuilder<
      ::test_protocollayouts::wire::MainProtocolTwoWayAnonWithErrorRequest>
  Builder(::fidl::AnyArena& arena);

  // Return a builder that relies on explicitly allocating |fidl::ObjectView|s.
  static ::fidl::WireTableExternalBuilder<
      ::test_protocollayouts::wire::MainProtocolTwoWayAnonWithErrorRequest>
  ExternalBuilder(
      ::fidl::ObjectView<::fidl::WireTableFrame<
          ::test_protocollayouts::wire::MainProtocolTwoWayAnonWithErrorRequest>>
          frame);

  const uint16_t& a() const {
    ZX_ASSERT(has_a());
    return frame_ptr_->a_.get_data();
  }
  uint16_t& a() {
    ZX_ASSERT(has_a());
    return frame_ptr_->a_.get_data();
  }
  bool has_a() const { return max_ordinal_ >= 1 && frame_ptr_->a_.has_data(); }
#if defined(FIDL_WIRE_ALLOW_DEPRECATED_MUTABLE_TABLES) || false
 public:
#else   // !defined(FIDL_WIRE_ALLOW_DEPRECATED_MUTABLE_TABLES)
 private:
#endif  // FIDL_WIRE_ALLOW_DEPRECATED_MUTABLE_TABLES

  MainProtocolTwoWayAnonWithErrorRequest& set_a(uint16_t elem) {
    ZX_DEBUG_ASSERT(frame_ptr_ != nullptr);
    frame_ptr_->a_.set_data(std::move(elem));
    max_ordinal_ = std::max(max_ordinal_, static_cast<uint64_t>(1));
    return *this;
  }

  MainProtocolTwoWayAnonWithErrorRequest& clear_a() {
    ZX_DEBUG_ASSERT(frame_ptr_ != nullptr);
    frame_ptr_->a_.clear_data();
    return *this;
  }

  explicit MainProtocolTwoWayAnonWithErrorRequest(::fidl::AnyArena& allocator)
      : frame_ptr_(
            ::fidl::ObjectView<::fidl::WireTableFrame<
                ::test_protocollayouts::wire::
                    MainProtocolTwoWayAnonWithErrorRequest>>(allocator)) {}
  // This constructor allows a user controlled allocation (not using a Arena).
  // It should only be used when performance is key.
  // As soon as the frame is given to the table, it must not be used directly or
  // for another table.
  explicit MainProtocolTwoWayAnonWithErrorRequest(
      ::fidl::ObjectView<::fidl::WireTableFrame<
          ::test_protocollayouts::wire::
              MainProtocolTwoWayAnonWithErrorRequest>>&& frame)
      : frame_ptr_(std::move(frame)) {}

  void Allocate(::fidl::AnyArena& allocator) {
    max_ordinal_ = 0;
    frame_ptr_ = ::fidl::ObjectView<::fidl::WireTableFrame<
        ::test_protocollayouts::wire::MainProtocolTwoWayAnonWithErrorRequest>>(
        allocator);
  }
  void Init(::fidl::ObjectView<::fidl::WireTableFrame<
                ::test_protocollayouts::wire::
                    MainProtocolTwoWayAnonWithErrorRequest>>&& frame_ptr) {
    max_ordinal_ = 0;
    frame_ptr_ = std::move(frame_ptr);
  }

 private:
  friend ::fidl::internal::WireTableBaseBuilder<
      ::test_protocollayouts::wire::MainProtocolTwoWayAnonWithErrorRequest,
      ::fidl::WireTableBuilder<::test_protocollayouts::wire::
                                   MainProtocolTwoWayAnonWithErrorRequest>>;
  friend ::fidl::internal::WireTableBaseBuilder<
      ::test_protocollayouts::wire::MainProtocolTwoWayAnonWithErrorRequest,
      ::fidl::WireTableExternalBuilder<
          ::test_protocollayouts::wire::
              MainProtocolTwoWayAnonWithErrorRequest>>;

  uint64_t max_ordinal_ = 0;
  ::fidl::ObjectView<::fidl::WireTableFrame<
      ::test_protocollayouts::wire::MainProtocolTwoWayAnonWithErrorRequest>>
      frame_ptr_;
};
}  // namespace wire
}  // namespace test_protocollayouts
template <typename BuilderImpl>
class ::fidl::internal::WireTableBaseBuilder<
    ::test_protocollayouts::wire::MainProtocolTwoWayAnonWithErrorRequest,
    BuilderImpl> {
 public:
  // Build and return the table. The builder should not be used after this.
  ::test_protocollayouts::wire::MainProtocolTwoWayAnonWithErrorRequest Build() {
    ZX_DEBUG_ASSERT(table_.frame_ptr_ != nullptr);
    ::test_protocollayouts::wire::MainProtocolTwoWayAnonWithErrorRequest t =
        std::move(table_);
    // Poison this builder to prevent accidental reuse.
    table_.frame_ptr_ = nullptr;
    return t;
  }

  BuilderImpl& a(uint16_t elem) {
    ZX_DEBUG_ASSERT(table_.frame_ptr_ != nullptr);
    table_.frame_ptr_->a_.set_data(std::move(elem));
    table_.max_ordinal_ =
        std::max(table_.max_ordinal_, static_cast<uint64_t>(1));
    return *static_cast<BuilderImpl*>(this);
  }

 protected:
  WireTableBaseBuilder(::fidl::ObjectView<::fidl::WireTableFrame<
                           ::test_protocollayouts::wire::
                               MainProtocolTwoWayAnonWithErrorRequest>>&& frame)
      : table_(std::move(frame)) {}

 private:
  ::test_protocollayouts::wire::MainProtocolTwoWayAnonWithErrorRequest table_;
};

template <>
class ::fidl::WireTableBuilder<
    ::test_protocollayouts::wire::MainProtocolTwoWayAnonWithErrorRequest>
    final
    : public ::fidl::internal::WireTableBaseBuilder<
          ::test_protocollayouts::wire::MainProtocolTwoWayAnonWithErrorRequest,
          ::fidl::WireTableBuilder<
              ::test_protocollayouts::wire::
                  MainProtocolTwoWayAnonWithErrorRequest>> {
  using Base = ::fidl::internal::WireTableBaseBuilder<
      ::test_protocollayouts::wire::MainProtocolTwoWayAnonWithErrorRequest,
      ::fidl::WireTableBuilder<::test_protocollayouts::wire::
                                   MainProtocolTwoWayAnonWithErrorRequest>>;

 public:
 private:
  friend class ::test_protocollayouts::wire::
      MainProtocolTwoWayAnonWithErrorRequest;
  WireTableBuilder(::fidl::AnyArena& arena)
      : Base(::fidl::ObjectView<::fidl::WireTableFrame<
                 ::test_protocollayouts::wire::
                     MainProtocolTwoWayAnonWithErrorRequest>>(arena)),
        arena_(arena) {}

  [[maybe_unused]] std::reference_wrapper<::fidl::AnyArena> arena_;
};

template <>
class ::fidl::WireTableExternalBuilder<
    ::test_protocollayouts::wire::MainProtocolTwoWayAnonWithErrorRequest>
    final
    : public ::fidl::internal::WireTableBaseBuilder<
          ::test_protocollayouts::wire::MainProtocolTwoWayAnonWithErrorRequest,
          ::fidl::WireTableExternalBuilder<
              ::test_protocollayouts::wire::
                  MainProtocolTwoWayAnonWithErrorRequest>> {
  using Base = ::fidl::internal::WireTableBaseBuilder<
      ::test_protocollayouts::wire::MainProtocolTwoWayAnonWithErrorRequest,
      ::fidl::WireTableExternalBuilder<
          ::test_protocollayouts::wire::
              MainProtocolTwoWayAnonWithErrorRequest>>;

 private:
  friend class ::test_protocollayouts::wire::
      MainProtocolTwoWayAnonWithErrorRequest;
  using Base::Base;
  WireTableExternalBuilder(
      ::fidl::WireTableFrame<
          ::test_protocollayouts::wire::MainProtocolTwoWayAnonWithErrorRequest>*
          frame)
      : Base(::fidl::ObjectView<::fidl::WireTableFrame<
                 ::test_protocollayouts::wire::
                     MainProtocolTwoWayAnonWithErrorRequest>>::
                 FromExternal(frame)) {}
};
namespace test_protocollayouts {
namespace wire {
inline ::fidl::WireTableBuilder<
    ::test_protocollayouts::wire::MainProtocolTwoWayAnonWithErrorRequest>
MainProtocolTwoWayAnonWithErrorRequest::Builder(::fidl::AnyArena& arena) {
  return ::fidl::WireTableBuilder<
      ::test_protocollayouts::wire::MainProtocolTwoWayAnonWithErrorRequest>(
      arena);
}
inline ::fidl::WireTableExternalBuilder<
    ::test_protocollayouts::wire::MainProtocolTwoWayAnonWithErrorRequest>
MainProtocolTwoWayAnonWithErrorRequest::ExternalBuilder(
    ::fidl::ObjectView<::fidl::WireTableFrame<
        ::test_protocollayouts::wire::MainProtocolTwoWayAnonWithErrorRequest>>
        frame) {
  return ::fidl::WireTableExternalBuilder<
      ::test_protocollayouts::wire::MainProtocolTwoWayAnonWithErrorRequest>(
      std::move(frame));
}

}  // namespace wire
}  // namespace test_protocollayouts
template <>
class ::fidl::WireTableBuilder<
    ::test_protocollayouts::wire::MainProtocolTwoWayAnonResponse>;
template <>
class ::fidl::WireTableExternalBuilder<
    ::test_protocollayouts::wire::MainProtocolTwoWayAnonResponse>;

template <>
struct ::fidl::WireTableFrame<
    ::test_protocollayouts::wire::MainProtocolTwoWayAnonResponse>
    final {
 public:
  WireTableFrame() = default;
  // In its intended usage, WireTableFrame will be referenced by an ObjectView.
  // If the ObjectView is assigned before a move or copy, then it will reference
  // the old invalid object. Because this is unsafe, copies are disallowed and
  // moves are only allowed by friend classes that operate safely.
  WireTableFrame(const WireTableFrame&) = delete;
  WireTableFrame& operator=(const WireTableFrame&) = delete;

 private:
  WireTableFrame(WireTableFrame&&) noexcept = default;
  WireTableFrame& operator=(WireTableFrame&&) noexcept = default;

  bool HasUnknownData() const;
  ::fidl::Envelope<uint16_t> a_;

  friend class ::test_protocollayouts::wire::MainProtocolTwoWayAnonResponse;
  friend ::fidl::internal::WireTableBaseBuilder<
      ::test_protocollayouts::wire::MainProtocolTwoWayAnonResponse,
      ::fidl::WireTableBuilder<
          ::test_protocollayouts::wire::MainProtocolTwoWayAnonResponse>>;
  friend ::fidl::internal::WireTableBaseBuilder<
      ::test_protocollayouts::wire::MainProtocolTwoWayAnonResponse,
      ::fidl::WireTableExternalBuilder<
          ::test_protocollayouts::wire::MainProtocolTwoWayAnonResponse>>;
};

namespace test_protocollayouts {
namespace wire {
extern "C" const fidl_type_t
    test_protocollayouts_MainProtocolTwoWayAnonResponseTable;

class MainProtocolTwoWayAnonResponse {
 public:
  MainProtocolTwoWayAnonResponse() = default;
  MainProtocolTwoWayAnonResponse(
      const MainProtocolTwoWayAnonResponse& other) noexcept = default;
  MainProtocolTwoWayAnonResponse& operator=(
      const MainProtocolTwoWayAnonResponse& other) noexcept = default;
  MainProtocolTwoWayAnonResponse(
      MainProtocolTwoWayAnonResponse&& other) noexcept = default;
  MainProtocolTwoWayAnonResponse& operator=(
      MainProtocolTwoWayAnonResponse&& other) noexcept = default;

  ~MainProtocolTwoWayAnonResponse() = default;

  // Returns whether no field is set.
  bool IsEmpty() const { return max_ordinal_ == 0; }

  // Returns whether the table references unknown fields.
  bool HasUnknownData() const;

  // Return a builder that by defaults allocates of an arena.
  static ::fidl::WireTableBuilder<
      ::test_protocollayouts::wire::MainProtocolTwoWayAnonResponse>
  Builder(::fidl::AnyArena& arena);

  // Return a builder that relies on explicitly allocating |fidl::ObjectView|s.
  static ::fidl::WireTableExternalBuilder<
      ::test_protocollayouts::wire::MainProtocolTwoWayAnonResponse>
  ExternalBuilder(
      ::fidl::ObjectView<::fidl::WireTableFrame<
          ::test_protocollayouts::wire::MainProtocolTwoWayAnonResponse>>
          frame);

  const uint16_t& a() const {
    ZX_ASSERT(has_a());
    return frame_ptr_->a_.get_data();
  }
  uint16_t& a() {
    ZX_ASSERT(has_a());
    return frame_ptr_->a_.get_data();
  }
  bool has_a() const { return max_ordinal_ >= 1 && frame_ptr_->a_.has_data(); }
#if defined(FIDL_WIRE_ALLOW_DEPRECATED_MUTABLE_TABLES) || false
 public:
#else   // !defined(FIDL_WIRE_ALLOW_DEPRECATED_MUTABLE_TABLES)
 private:
#endif  // FIDL_WIRE_ALLOW_DEPRECATED_MUTABLE_TABLES

  MainProtocolTwoWayAnonResponse& set_a(uint16_t elem) {
    ZX_DEBUG_ASSERT(frame_ptr_ != nullptr);
    frame_ptr_->a_.set_data(std::move(elem));
    max_ordinal_ = std::max(max_ordinal_, static_cast<uint64_t>(1));
    return *this;
  }

  MainProtocolTwoWayAnonResponse& clear_a() {
    ZX_DEBUG_ASSERT(frame_ptr_ != nullptr);
    frame_ptr_->a_.clear_data();
    return *this;
  }

  explicit MainProtocolTwoWayAnonResponse(::fidl::AnyArena& allocator)
      : frame_ptr_(
            ::fidl::ObjectView<::fidl::WireTableFrame<
                ::test_protocollayouts::wire::MainProtocolTwoWayAnonResponse>>(
                allocator)) {}
  // This constructor allows a user controlled allocation (not using a Arena).
  // It should only be used when performance is key.
  // As soon as the frame is given to the table, it must not be used directly or
  // for another table.
  explicit MainProtocolTwoWayAnonResponse(
      ::fidl::ObjectView<::fidl::WireTableFrame<
          ::test_protocollayouts::wire::MainProtocolTwoWayAnonResponse>>&&
          frame)
      : frame_ptr_(std::move(frame)) {}

  void Allocate(::fidl::AnyArena& allocator) {
    max_ordinal_ = 0;
    frame_ptr_ = ::fidl::ObjectView<::fidl::WireTableFrame<
        ::test_protocollayouts::wire::MainProtocolTwoWayAnonResponse>>(
        allocator);
  }
  void Init(::fidl::ObjectView<::fidl::WireTableFrame<
                ::test_protocollayouts::wire::MainProtocolTwoWayAnonResponse>>&&
                frame_ptr) {
    max_ordinal_ = 0;
    frame_ptr_ = std::move(frame_ptr);
  }

 private:
  friend ::fidl::internal::WireTableBaseBuilder<
      ::test_protocollayouts::wire::MainProtocolTwoWayAnonResponse,
      ::fidl::WireTableBuilder<
          ::test_protocollayouts::wire::MainProtocolTwoWayAnonResponse>>;
  friend ::fidl::internal::WireTableBaseBuilder<
      ::test_protocollayouts::wire::MainProtocolTwoWayAnonResponse,
      ::fidl::WireTableExternalBuilder<
          ::test_protocollayouts::wire::MainProtocolTwoWayAnonResponse>>;

  uint64_t max_ordinal_ = 0;
  ::fidl::ObjectView<::fidl::WireTableFrame<
      ::test_protocollayouts::wire::MainProtocolTwoWayAnonResponse>>
      frame_ptr_;
};
}  // namespace wire
}  // namespace test_protocollayouts
template <typename BuilderImpl>
class ::fidl::internal::WireTableBaseBuilder<
    ::test_protocollayouts::wire::MainProtocolTwoWayAnonResponse, BuilderImpl> {
 public:
  // Build and return the table. The builder should not be used after this.
  ::test_protocollayouts::wire::MainProtocolTwoWayAnonResponse Build() {
    ZX_DEBUG_ASSERT(table_.frame_ptr_ != nullptr);
    ::test_protocollayouts::wire::MainProtocolTwoWayAnonResponse t =
        std::move(table_);
    // Poison this builder to prevent accidental reuse.
    table_.frame_ptr_ = nullptr;
    return t;
  }

  BuilderImpl& a(uint16_t elem) {
    ZX_DEBUG_ASSERT(table_.frame_ptr_ != nullptr);
    table_.frame_ptr_->a_.set_data(std::move(elem));
    table_.max_ordinal_ =
        std::max(table_.max_ordinal_, static_cast<uint64_t>(1));
    return *static_cast<BuilderImpl*>(this);
  }

 protected:
  WireTableBaseBuilder(
      ::fidl::ObjectView<::fidl::WireTableFrame<
          ::test_protocollayouts::wire::MainProtocolTwoWayAnonResponse>>&&
          frame)
      : table_(std::move(frame)) {}

 private:
  ::test_protocollayouts::wire::MainProtocolTwoWayAnonResponse table_;
};

template <>
class ::fidl::WireTableBuilder<
    ::test_protocollayouts::wire::MainProtocolTwoWayAnonResponse>
    final
    : public ::fidl::internal::WireTableBaseBuilder<
          ::test_protocollayouts::wire::MainProtocolTwoWayAnonResponse,
          ::fidl::WireTableBuilder<
              ::test_protocollayouts::wire::MainProtocolTwoWayAnonResponse>> {
  using Base = ::fidl::internal::WireTableBaseBuilder<
      ::test_protocollayouts::wire::MainProtocolTwoWayAnonResponse,
      ::fidl::WireTableBuilder<
          ::test_protocollayouts::wire::MainProtocolTwoWayAnonResponse>>;

 public:
 private:
  friend class ::test_protocollayouts::wire::MainProtocolTwoWayAnonResponse;
  WireTableBuilder(::fidl::AnyArena& arena)
      : Base(::fidl::ObjectView<::fidl::WireTableFrame<
                 ::test_protocollayouts::wire::MainProtocolTwoWayAnonResponse>>(
            arena)),
        arena_(arena) {}

  [[maybe_unused]] std::reference_wrapper<::fidl::AnyArena> arena_;
};

template <>
class ::fidl::WireTableExternalBuilder<
    ::test_protocollayouts::wire::MainProtocolTwoWayAnonResponse>
    final
    : public ::fidl::internal::WireTableBaseBuilder<
          ::test_protocollayouts::wire::MainProtocolTwoWayAnonResponse,
          ::fidl::WireTableExternalBuilder<
              ::test_protocollayouts::wire::MainProtocolTwoWayAnonResponse>> {
  using Base = ::fidl::internal::WireTableBaseBuilder<
      ::test_protocollayouts::wire::MainProtocolTwoWayAnonResponse,
      ::fidl::WireTableExternalBuilder<
          ::test_protocollayouts::wire::MainProtocolTwoWayAnonResponse>>;

 private:
  friend class ::test_protocollayouts::wire::MainProtocolTwoWayAnonResponse;
  using Base::Base;
  WireTableExternalBuilder(
      ::fidl::WireTableFrame<
          ::test_protocollayouts::wire::MainProtocolTwoWayAnonResponse>* frame)
      : Base(
            ::fidl::ObjectView<::fidl::WireTableFrame<
                ::test_protocollayouts::wire::MainProtocolTwoWayAnonResponse>>::
                FromExternal(frame)) {}
};
namespace test_protocollayouts {
namespace wire {
inline ::fidl::WireTableBuilder<
    ::test_protocollayouts::wire::MainProtocolTwoWayAnonResponse>
MainProtocolTwoWayAnonResponse::Builder(::fidl::AnyArena& arena) {
  return ::fidl::WireTableBuilder<
      ::test_protocollayouts::wire::MainProtocolTwoWayAnonResponse>(arena);
}
inline ::fidl::WireTableExternalBuilder<
    ::test_protocollayouts::wire::MainProtocolTwoWayAnonResponse>
MainProtocolTwoWayAnonResponse::ExternalBuilder(
    ::fidl::ObjectView<::fidl::WireTableFrame<
        ::test_protocollayouts::wire::MainProtocolTwoWayAnonResponse>>
        frame) {
  return ::fidl::WireTableExternalBuilder<
      ::test_protocollayouts::wire::MainProtocolTwoWayAnonResponse>(
      std::move(frame));
}

}  // namespace wire
}  // namespace test_protocollayouts
template <>
class ::fidl::WireTableBuilder<
    ::test_protocollayouts::wire::MainProtocolOneWayAnonRequest>;
template <>
class ::fidl::WireTableExternalBuilder<
    ::test_protocollayouts::wire::MainProtocolOneWayAnonRequest>;

template <>
struct ::fidl::WireTableFrame<
    ::test_protocollayouts::wire::MainProtocolOneWayAnonRequest>
    final {
 public:
  WireTableFrame() = default;
  // In its intended usage, WireTableFrame will be referenced by an ObjectView.
  // If the ObjectView is assigned before a move or copy, then it will reference
  // the old invalid object. Because this is unsafe, copies are disallowed and
  // moves are only allowed by friend classes that operate safely.
  WireTableFrame(const WireTableFrame&) = delete;
  WireTableFrame& operator=(const WireTableFrame&) = delete;

 private:
  WireTableFrame(WireTableFrame&&) noexcept = default;
  WireTableFrame& operator=(WireTableFrame&&) noexcept = default;

  bool HasUnknownData() const;
  ::fidl::Envelope<uint16_t> a_;

  friend class ::test_protocollayouts::wire::MainProtocolOneWayAnonRequest;
  friend ::fidl::internal::WireTableBaseBuilder<
      ::test_protocollayouts::wire::MainProtocolOneWayAnonRequest,
      ::fidl::WireTableBuilder<
          ::test_protocollayouts::wire::MainProtocolOneWayAnonRequest>>;
  friend ::fidl::internal::WireTableBaseBuilder<
      ::test_protocollayouts::wire::MainProtocolOneWayAnonRequest,
      ::fidl::WireTableExternalBuilder<
          ::test_protocollayouts::wire::MainProtocolOneWayAnonRequest>>;
};

namespace test_protocollayouts {
namespace wire {
extern "C" const fidl_type_t
    test_protocollayouts_MainProtocolOneWayAnonRequestTable;

class MainProtocolOneWayAnonRequest {
 public:
  MainProtocolOneWayAnonRequest() = default;
  MainProtocolOneWayAnonRequest(
      const MainProtocolOneWayAnonRequest& other) noexcept = default;
  MainProtocolOneWayAnonRequest& operator=(
      const MainProtocolOneWayAnonRequest& other) noexcept = default;
  MainProtocolOneWayAnonRequest(
      MainProtocolOneWayAnonRequest&& other) noexcept = default;
  MainProtocolOneWayAnonRequest& operator=(
      MainProtocolOneWayAnonRequest&& other) noexcept = default;

  ~MainProtocolOneWayAnonRequest() = default;

  // Returns whether no field is set.
  bool IsEmpty() const { return max_ordinal_ == 0; }

  // Returns whether the table references unknown fields.
  bool HasUnknownData() const;

  // Return a builder that by defaults allocates of an arena.
  static ::fidl::WireTableBuilder<
      ::test_protocollayouts::wire::MainProtocolOneWayAnonRequest>
  Builder(::fidl::AnyArena& arena);

  // Return a builder that relies on explicitly allocating |fidl::ObjectView|s.
  static ::fidl::WireTableExternalBuilder<
      ::test_protocollayouts::wire::MainProtocolOneWayAnonRequest>
  ExternalBuilder(
      ::fidl::ObjectView<::fidl::WireTableFrame<
          ::test_protocollayouts::wire::MainProtocolOneWayAnonRequest>>
          frame);

  const uint16_t& a() const {
    ZX_ASSERT(has_a());
    return frame_ptr_->a_.get_data();
  }
  uint16_t& a() {
    ZX_ASSERT(has_a());
    return frame_ptr_->a_.get_data();
  }
  bool has_a() const { return max_ordinal_ >= 1 && frame_ptr_->a_.has_data(); }
#if defined(FIDL_WIRE_ALLOW_DEPRECATED_MUTABLE_TABLES) || false
 public:
#else   // !defined(FIDL_WIRE_ALLOW_DEPRECATED_MUTABLE_TABLES)
 private:
#endif  // FIDL_WIRE_ALLOW_DEPRECATED_MUTABLE_TABLES

  MainProtocolOneWayAnonRequest& set_a(uint16_t elem) {
    ZX_DEBUG_ASSERT(frame_ptr_ != nullptr);
    frame_ptr_->a_.set_data(std::move(elem));
    max_ordinal_ = std::max(max_ordinal_, static_cast<uint64_t>(1));
    return *this;
  }

  MainProtocolOneWayAnonRequest& clear_a() {
    ZX_DEBUG_ASSERT(frame_ptr_ != nullptr);
    frame_ptr_->a_.clear_data();
    return *this;
  }

  explicit MainProtocolOneWayAnonRequest(::fidl::AnyArena& allocator)
      : frame_ptr_(
            ::fidl::ObjectView<::fidl::WireTableFrame<
                ::test_protocollayouts::wire::MainProtocolOneWayAnonRequest>>(
                allocator)) {}
  // This constructor allows a user controlled allocation (not using a Arena).
  // It should only be used when performance is key.
  // As soon as the frame is given to the table, it must not be used directly or
  // for another table.
  explicit MainProtocolOneWayAnonRequest(
      ::fidl::ObjectView<::fidl::WireTableFrame<
          ::test_protocollayouts::wire::MainProtocolOneWayAnonRequest>>&& frame)
      : frame_ptr_(std::move(frame)) {}

  void Allocate(::fidl::AnyArena& allocator) {
    max_ordinal_ = 0;
    frame_ptr_ = ::fidl::ObjectView<::fidl::WireTableFrame<
        ::test_protocollayouts::wire::MainProtocolOneWayAnonRequest>>(
        allocator);
  }
  void Init(::fidl::ObjectView<::fidl::WireTableFrame<
                ::test_protocollayouts::wire::MainProtocolOneWayAnonRequest>>&&
                frame_ptr) {
    max_ordinal_ = 0;
    frame_ptr_ = std::move(frame_ptr);
  }

 private:
  friend ::fidl::internal::WireTableBaseBuilder<
      ::test_protocollayouts::wire::MainProtocolOneWayAnonRequest,
      ::fidl::WireTableBuilder<
          ::test_protocollayouts::wire::MainProtocolOneWayAnonRequest>>;
  friend ::fidl::internal::WireTableBaseBuilder<
      ::test_protocollayouts::wire::MainProtocolOneWayAnonRequest,
      ::fidl::WireTableExternalBuilder<
          ::test_protocollayouts::wire::MainProtocolOneWayAnonRequest>>;

  uint64_t max_ordinal_ = 0;
  ::fidl::ObjectView<::fidl::WireTableFrame<
      ::test_protocollayouts::wire::MainProtocolOneWayAnonRequest>>
      frame_ptr_;
};
}  // namespace wire
}  // namespace test_protocollayouts
template <typename BuilderImpl>
class ::fidl::internal::WireTableBaseBuilder<
    ::test_protocollayouts::wire::MainProtocolOneWayAnonRequest, BuilderImpl> {
 public:
  // Build and return the table. The builder should not be used after this.
  ::test_protocollayouts::wire::MainProtocolOneWayAnonRequest Build() {
    ZX_DEBUG_ASSERT(table_.frame_ptr_ != nullptr);
    ::test_protocollayouts::wire::MainProtocolOneWayAnonRequest t =
        std::move(table_);
    // Poison this builder to prevent accidental reuse.
    table_.frame_ptr_ = nullptr;
    return t;
  }

  BuilderImpl& a(uint16_t elem) {
    ZX_DEBUG_ASSERT(table_.frame_ptr_ != nullptr);
    table_.frame_ptr_->a_.set_data(std::move(elem));
    table_.max_ordinal_ =
        std::max(table_.max_ordinal_, static_cast<uint64_t>(1));
    return *static_cast<BuilderImpl*>(this);
  }

 protected:
  WireTableBaseBuilder(
      ::fidl::ObjectView<::fidl::WireTableFrame<
          ::test_protocollayouts::wire::MainProtocolOneWayAnonRequest>>&& frame)
      : table_(std::move(frame)) {}

 private:
  ::test_protocollayouts::wire::MainProtocolOneWayAnonRequest table_;
};

template <>
class ::fidl::WireTableBuilder<
    ::test_protocollayouts::wire::MainProtocolOneWayAnonRequest>
    final
    : public ::fidl::internal::WireTableBaseBuilder<
          ::test_protocollayouts::wire::MainProtocolOneWayAnonRequest,
          ::fidl::WireTableBuilder<
              ::test_protocollayouts::wire::MainProtocolOneWayAnonRequest>> {
  using Base = ::fidl::internal::WireTableBaseBuilder<
      ::test_protocollayouts::wire::MainProtocolOneWayAnonRequest,
      ::fidl::WireTableBuilder<
          ::test_protocollayouts::wire::MainProtocolOneWayAnonRequest>>;

 public:
 private:
  friend class ::test_protocollayouts::wire::MainProtocolOneWayAnonRequest;
  WireTableBuilder(::fidl::AnyArena& arena)
      : Base(::fidl::ObjectView<::fidl::WireTableFrame<
                 ::test_protocollayouts::wire::MainProtocolOneWayAnonRequest>>(
            arena)),
        arena_(arena) {}

  [[maybe_unused]] std::reference_wrapper<::fidl::AnyArena> arena_;
};

template <>
class ::fidl::WireTableExternalBuilder<
    ::test_protocollayouts::wire::MainProtocolOneWayAnonRequest>
    final
    : public ::fidl::internal::WireTableBaseBuilder<
          ::test_protocollayouts::wire::MainProtocolOneWayAnonRequest,
          ::fidl::WireTableExternalBuilder<
              ::test_protocollayouts::wire::MainProtocolOneWayAnonRequest>> {
  using Base = ::fidl::internal::WireTableBaseBuilder<
      ::test_protocollayouts::wire::MainProtocolOneWayAnonRequest,
      ::fidl::WireTableExternalBuilder<
          ::test_protocollayouts::wire::MainProtocolOneWayAnonRequest>>;

 private:
  friend class ::test_protocollayouts::wire::MainProtocolOneWayAnonRequest;
  using Base::Base;
  WireTableExternalBuilder(
      ::fidl::WireTableFrame<
          ::test_protocollayouts::wire::MainProtocolOneWayAnonRequest>* frame)
      : Base(::fidl::ObjectView<::fidl::WireTableFrame<
                 ::test_protocollayouts::wire::MainProtocolOneWayAnonRequest>>::
                 FromExternal(frame)) {}
};
namespace test_protocollayouts {
namespace wire {
inline ::fidl::WireTableBuilder<
    ::test_protocollayouts::wire::MainProtocolOneWayAnonRequest>
MainProtocolOneWayAnonRequest::Builder(::fidl::AnyArena& arena) {
  return ::fidl::WireTableBuilder<
      ::test_protocollayouts::wire::MainProtocolOneWayAnonRequest>(arena);
}
inline ::fidl::WireTableExternalBuilder<
    ::test_protocollayouts::wire::MainProtocolOneWayAnonRequest>
MainProtocolOneWayAnonRequest::ExternalBuilder(
    ::fidl::ObjectView<::fidl::WireTableFrame<
        ::test_protocollayouts::wire::MainProtocolOneWayAnonRequest>>
        frame) {
  return ::fidl::WireTableExternalBuilder<
      ::test_protocollayouts::wire::MainProtocolOneWayAnonRequest>(
      std::move(frame));
}

}  // namespace wire
}  // namespace test_protocollayouts
template <>
class ::fidl::WireTableBuilder<::test_protocollayouts::wire::LocalTablePayload>;
template <>
class ::fidl::WireTableExternalBuilder<
    ::test_protocollayouts::wire::LocalTablePayload>;

template <>
struct ::fidl::WireTableFrame<::test_protocollayouts::wire::LocalTablePayload>
    final {
 public:
  WireTableFrame() = default;
  // In its intended usage, WireTableFrame will be referenced by an ObjectView.
  // If the ObjectView is assigned before a move or copy, then it will reference
  // the old invalid object. Because this is unsafe, copies are disallowed and
  // moves are only allowed by friend classes that operate safely.
  WireTableFrame(const WireTableFrame&) = delete;
  WireTableFrame& operator=(const WireTableFrame&) = delete;

 private:
  WireTableFrame(WireTableFrame&&) noexcept = default;
  WireTableFrame& operator=(WireTableFrame&&) noexcept = default;

  bool HasUnknownData() const;
  ::fidl::Envelope<uint16_t> a_;

  friend class ::test_protocollayouts::wire::LocalTablePayload;
  friend ::fidl::internal::WireTableBaseBuilder<
      ::test_protocollayouts::wire::LocalTablePayload,
      ::fidl::WireTableBuilder<
          ::test_protocollayouts::wire::LocalTablePayload>>;
  friend ::fidl::internal::WireTableBaseBuilder<
      ::test_protocollayouts::wire::LocalTablePayload,
      ::fidl::WireTableExternalBuilder<
          ::test_protocollayouts::wire::LocalTablePayload>>;
};

namespace test_protocollayouts {
namespace wire {
extern "C" const fidl_type_t test_protocollayouts_LocalTablePayloadTable;

class LocalTablePayload {
 public:
  LocalTablePayload() = default;
  LocalTablePayload(const LocalTablePayload& other) noexcept = default;
  LocalTablePayload& operator=(const LocalTablePayload& other) noexcept =
      default;
  LocalTablePayload(LocalTablePayload&& other) noexcept = default;
  LocalTablePayload& operator=(LocalTablePayload&& other) noexcept = default;

  ~LocalTablePayload() = default;

  // Returns whether no field is set.
  bool IsEmpty() const { return max_ordinal_ == 0; }

  // Returns whether the table references unknown fields.
  bool HasUnknownData() const;

  // Return a builder that by defaults allocates of an arena.
  static ::fidl::WireTableBuilder<
      ::test_protocollayouts::wire::LocalTablePayload>
  Builder(::fidl::AnyArena& arena);

  // Return a builder that relies on explicitly allocating |fidl::ObjectView|s.
  static ::fidl::WireTableExternalBuilder<
      ::test_protocollayouts::wire::LocalTablePayload>
  ExternalBuilder(::fidl::ObjectView<::fidl::WireTableFrame<
                      ::test_protocollayouts::wire::LocalTablePayload>>
                      frame);

  const uint16_t& a() const {
    ZX_ASSERT(has_a());
    return frame_ptr_->a_.get_data();
  }
  uint16_t& a() {
    ZX_ASSERT(has_a());
    return frame_ptr_->a_.get_data();
  }
  bool has_a() const { return max_ordinal_ >= 1 && frame_ptr_->a_.has_data(); }
#if defined(FIDL_WIRE_ALLOW_DEPRECATED_MUTABLE_TABLES) || false
 public:
#else   // !defined(FIDL_WIRE_ALLOW_DEPRECATED_MUTABLE_TABLES)
 private:
#endif  // FIDL_WIRE_ALLOW_DEPRECATED_MUTABLE_TABLES

  LocalTablePayload& set_a(uint16_t elem) {
    ZX_DEBUG_ASSERT(frame_ptr_ != nullptr);
    frame_ptr_->a_.set_data(std::move(elem));
    max_ordinal_ = std::max(max_ordinal_, static_cast<uint64_t>(1));
    return *this;
  }

  LocalTablePayload& clear_a() {
    ZX_DEBUG_ASSERT(frame_ptr_ != nullptr);
    frame_ptr_->a_.clear_data();
    return *this;
  }

  explicit LocalTablePayload(::fidl::AnyArena& allocator)
      : frame_ptr_(
            ::fidl::ObjectView<::fidl::WireTableFrame<
                ::test_protocollayouts::wire::LocalTablePayload>>(allocator)) {}
  // This constructor allows a user controlled allocation (not using a Arena).
  // It should only be used when performance is key.
  // As soon as the frame is given to the table, it must not be used directly or
  // for another table.
  explicit LocalTablePayload(
      ::fidl::ObjectView<::fidl::WireTableFrame<
          ::test_protocollayouts::wire::LocalTablePayload>>&& frame)
      : frame_ptr_(std::move(frame)) {}

  void Allocate(::fidl::AnyArena& allocator) {
    max_ordinal_ = 0;
    frame_ptr_ = ::fidl::ObjectView<::fidl::WireTableFrame<
        ::test_protocollayouts::wire::LocalTablePayload>>(allocator);
  }
  void Init(::fidl::ObjectView<::fidl::WireTableFrame<
                ::test_protocollayouts::wire::LocalTablePayload>>&& frame_ptr) {
    max_ordinal_ = 0;
    frame_ptr_ = std::move(frame_ptr);
  }

 private:
  friend ::fidl::internal::WireTableBaseBuilder<
      ::test_protocollayouts::wire::LocalTablePayload,
      ::fidl::WireTableBuilder<
          ::test_protocollayouts::wire::LocalTablePayload>>;
  friend ::fidl::internal::WireTableBaseBuilder<
      ::test_protocollayouts::wire::LocalTablePayload,
      ::fidl::WireTableExternalBuilder<
          ::test_protocollayouts::wire::LocalTablePayload>>;

  uint64_t max_ordinal_ = 0;
  ::fidl::ObjectView<
      ::fidl::WireTableFrame<::test_protocollayouts::wire::LocalTablePayload>>
      frame_ptr_;
};
}  // namespace wire
}  // namespace test_protocollayouts
template <typename BuilderImpl>
class ::fidl::internal::WireTableBaseBuilder<
    ::test_protocollayouts::wire::LocalTablePayload, BuilderImpl> {
 public:
  // Build and return the table. The builder should not be used after this.
  ::test_protocollayouts::wire::LocalTablePayload Build() {
    ZX_DEBUG_ASSERT(table_.frame_ptr_ != nullptr);
    ::test_protocollayouts::wire::LocalTablePayload t = std::move(table_);
    // Poison this builder to prevent accidental reuse.
    table_.frame_ptr_ = nullptr;
    return t;
  }

  BuilderImpl& a(uint16_t elem) {
    ZX_DEBUG_ASSERT(table_.frame_ptr_ != nullptr);
    table_.frame_ptr_->a_.set_data(std::move(elem));
    table_.max_ordinal_ =
        std::max(table_.max_ordinal_, static_cast<uint64_t>(1));
    return *static_cast<BuilderImpl*>(this);
  }

 protected:
  WireTableBaseBuilder(
      ::fidl::ObjectView<::fidl::WireTableFrame<
          ::test_protocollayouts::wire::LocalTablePayload>>&& frame)
      : table_(std::move(frame)) {}

 private:
  ::test_protocollayouts::wire::LocalTablePayload table_;
};

template <>
class ::fidl::WireTableBuilder<::test_protocollayouts::wire::LocalTablePayload>
    final : public ::fidl::internal::WireTableBaseBuilder<
                ::test_protocollayouts::wire::LocalTablePayload,
                ::fidl::WireTableBuilder<
                    ::test_protocollayouts::wire::LocalTablePayload>> {
  using Base = ::fidl::internal::WireTableBaseBuilder<
      ::test_protocollayouts::wire::LocalTablePayload,
      ::fidl::WireTableBuilder<
          ::test_protocollayouts::wire::LocalTablePayload>>;

 public:
 private:
  friend class ::test_protocollayouts::wire::LocalTablePayload;
  WireTableBuilder(::fidl::AnyArena& arena)
      : Base(::fidl::ObjectView<::fidl::WireTableFrame<
                 ::test_protocollayouts::wire::LocalTablePayload>>(arena)),
        arena_(arena) {}

  [[maybe_unused]] std::reference_wrapper<::fidl::AnyArena> arena_;
};

template <>
class ::fidl::WireTableExternalBuilder<
    ::test_protocollayouts::wire::LocalTablePayload>
    final : public ::fidl::internal::WireTableBaseBuilder<
                ::test_protocollayouts::wire::LocalTablePayload,
                ::fidl::WireTableExternalBuilder<
                    ::test_protocollayouts::wire::LocalTablePayload>> {
  using Base = ::fidl::internal::WireTableBaseBuilder<
      ::test_protocollayouts::wire::LocalTablePayload,
      ::fidl::WireTableExternalBuilder<
          ::test_protocollayouts::wire::LocalTablePayload>>;

 private:
  friend class ::test_protocollayouts::wire::LocalTablePayload;
  using Base::Base;
  WireTableExternalBuilder(
      ::fidl::WireTableFrame<::test_protocollayouts::wire::LocalTablePayload>*
          frame)
      : Base(::fidl::ObjectView<::fidl::WireTableFrame<
                 ::test_protocollayouts::wire::LocalTablePayload>>::
                 FromExternal(frame)) {}
};
namespace test_protocollayouts {
namespace wire {
inline ::fidl::WireTableBuilder<::test_protocollayouts::wire::LocalTablePayload>
LocalTablePayload::Builder(::fidl::AnyArena& arena) {
  return ::fidl::WireTableBuilder<
      ::test_protocollayouts::wire::LocalTablePayload>(arena);
}
inline ::fidl::WireTableExternalBuilder<
    ::test_protocollayouts::wire::LocalTablePayload>
LocalTablePayload::ExternalBuilder(
    ::fidl::ObjectView<
        ::fidl::WireTableFrame<::test_protocollayouts::wire::LocalTablePayload>>
        frame) {
  return ::fidl::WireTableExternalBuilder<
      ::test_protocollayouts::wire::LocalTablePayload>(std::move(frame));
}

extern "C" const fidl_type_t
    test_protocollayouts_MainProtocol_TwoWayImportWithError_ResultTable;

class MainProtocolTwoWayImportWithErrorResult {
 public:
  MainProtocolTwoWayImportWithErrorResult()
      : ordinal_(::test_protocollayouts::wire::
                     MainProtocolTwoWayImportWithErrorResult::Ordinal::Invalid),
        envelope_{} {}

  MainProtocolTwoWayImportWithErrorResult(
      const MainProtocolTwoWayImportWithErrorResult&) = default;
  MainProtocolTwoWayImportWithErrorResult& operator=(
      const MainProtocolTwoWayImportWithErrorResult&) = default;
  MainProtocolTwoWayImportWithErrorResult(
      MainProtocolTwoWayImportWithErrorResult&&) = default;
  MainProtocolTwoWayImportWithErrorResult& operator=(
      MainProtocolTwoWayImportWithErrorResult&&) = default;

  enum class Tag : fidl_xunion_tag_t {
    kResponse = 1,  // 0x1
    kErr = 2,       // 0x2
  };

  bool has_invalid_tag() const {
    return ordinal_ ==
           ::test_protocollayouts::wire::
               MainProtocolTwoWayImportWithErrorResult::Ordinal::Invalid;
  }

  bool is_response() const {
    return ordinal_ ==
           ::test_protocollayouts::wire::
               MainProtocolTwoWayImportWithErrorResult::Ordinal::kResponse;
  }

  static MainProtocolTwoWayImportWithErrorResult WithResponse(
      ::fidl::ObjectView<
          ::test_protocollayouts_imported::wire::ImportUnionPayload>
          val) {
    MainProtocolTwoWayImportWithErrorResult result;
    result.ordinal_ = ::test_protocollayouts::wire::
        MainProtocolTwoWayImportWithErrorResult::Ordinal::kResponse;
    result.envelope_
        .As<::test_protocollayouts_imported::wire::ImportUnionPayload>()
        .set_data(std::move(val));
    return result;
  }

  template <typename... Args>
  static MainProtocolTwoWayImportWithErrorResult WithResponse(
      ::fidl::AnyArena& allocator, Args&&... args) {
    return WithResponse(
        ::fidl::ObjectView<
            ::test_protocollayouts_imported::wire::ImportUnionPayload>(
            allocator, std::forward<Args>(args)...));
  }

  ::test_protocollayouts_imported::wire::ImportUnionPayload& response() {
    ZX_ASSERT(ordinal_ ==
              ::test_protocollayouts::wire::
                  MainProtocolTwoWayImportWithErrorResult::Ordinal::kResponse);
    return envelope_
        .As<::test_protocollayouts_imported::wire::ImportUnionPayload>()
        .get_data();
  }
  const ::test_protocollayouts_imported::wire::ImportUnionPayload& response()
      const {
    ZX_ASSERT(ordinal_ ==
              ::test_protocollayouts::wire::
                  MainProtocolTwoWayImportWithErrorResult::Ordinal::kResponse);
    return envelope_
        .As<::test_protocollayouts_imported::wire::ImportUnionPayload>()
        .get_data();
  }

  bool is_err() const {
    return ordinal_ ==
           ::test_protocollayouts::wire::
               MainProtocolTwoWayImportWithErrorResult::Ordinal::kErr;
  }

  static MainProtocolTwoWayImportWithErrorResult WithErr(uint32_t val) {
    MainProtocolTwoWayImportWithErrorResult result;
    result.ordinal_ = ::test_protocollayouts::wire::
        MainProtocolTwoWayImportWithErrorResult::Ordinal::kErr;
    result.envelope_.As<uint32_t>().set_data(std::move(val));
    return result;
  }

  uint32_t& err() {
    ZX_ASSERT(ordinal_ ==
              ::test_protocollayouts::wire::
                  MainProtocolTwoWayImportWithErrorResult::Ordinal::kErr);
    return envelope_.As<uint32_t>().get_data();
  }
  const uint32_t& err() const {
    ZX_ASSERT(ordinal_ ==
              ::test_protocollayouts::wire::
                  MainProtocolTwoWayImportWithErrorResult::Ordinal::kErr);
    return envelope_.As<uint32_t>().get_data();
  }
  ::test_protocollayouts::wire::MainProtocolTwoWayImportWithErrorResult::Tag
  Which() const {
    ZX_ASSERT(!has_invalid_tag());
    return static_cast<::test_protocollayouts::wire::
                           MainProtocolTwoWayImportWithErrorResult::Tag>(
        ordinal_);
  }

 private:
  enum class Ordinal : fidl_xunion_tag_t {
    Invalid = 0,
    kResponse = 1,  // 0x1
    kErr = 2,       // 0x2
  };

  static void SizeAndOffsetAssertionHelper();
  ::test_protocollayouts::wire::MainProtocolTwoWayImportWithErrorResult::Ordinal
      ordinal_;
  FIDL_ALIGNDECL
  ::fidl::UntypedEnvelope envelope_;
};

extern "C" const fidl_type_t
    test_protocollayouts_MainProtocol_TwoWayAnonWithError_ResponseTable;

class MainProtocolTwoWayAnonWithErrorResponse {
 public:
  MainProtocolTwoWayAnonWithErrorResponse()
      : ordinal_(::test_protocollayouts::wire::
                     MainProtocolTwoWayAnonWithErrorResponse::Ordinal::Invalid),
        envelope_{} {}

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

  enum class Tag : fidl_xunion_tag_t {
    kB = 1,  // 0x1
    kUnknown = ::std::numeric_limits<::fidl_union_tag_t>::max(),
  };

  bool has_invalid_tag() const {
    return ordinal_ ==
           ::test_protocollayouts::wire::
               MainProtocolTwoWayAnonWithErrorResponse::Ordinal::Invalid;
  }

  bool is_b() const {
    return ordinal_ == ::test_protocollayouts::wire::
                           MainProtocolTwoWayAnonWithErrorResponse::Ordinal::kB;
  }

  static MainProtocolTwoWayAnonWithErrorResponse WithB(bool val) {
    MainProtocolTwoWayAnonWithErrorResponse result;
    result.ordinal_ = ::test_protocollayouts::wire::
        MainProtocolTwoWayAnonWithErrorResponse::Ordinal::kB;
    result.envelope_.As<bool>().set_data(std::move(val));
    return result;
  }

  bool& b() {
    ZX_ASSERT(ordinal_ ==
              ::test_protocollayouts::wire::
                  MainProtocolTwoWayAnonWithErrorResponse::Ordinal::kB);
    return envelope_.As<bool>().get_data();
  }
  const bool& b() const {
    ZX_ASSERT(ordinal_ ==
              ::test_protocollayouts::wire::
                  MainProtocolTwoWayAnonWithErrorResponse::Ordinal::kB);
    return envelope_.As<bool>().get_data();
  }
  ::test_protocollayouts::wire::MainProtocolTwoWayAnonWithErrorResponse::Tag
  Which() const;

 private:
  enum class Ordinal : fidl_xunion_tag_t {
    Invalid = 0,
    kB = 1,  // 0x1
  };

  static void SizeAndOffsetAssertionHelper();
  ::test_protocollayouts::wire::MainProtocolTwoWayAnonWithErrorResponse::Ordinal
      ordinal_;
  FIDL_ALIGNDECL
  ::fidl::UntypedEnvelope envelope_;
};

extern "C" const fidl_type_t
    test_protocollayouts_MainProtocol_TwoWayAnonWithError_ResultTable;

class MainProtocolTwoWayAnonWithErrorResult {
 public:
  using Response =
      test_protocollayouts::wire::MainProtocolTwoWayAnonWithErrorResponse;

  MainProtocolTwoWayAnonWithErrorResult()
      : ordinal_(::test_protocollayouts::wire::
                     MainProtocolTwoWayAnonWithErrorResult::Ordinal::Invalid),
        envelope_{} {}

  MainProtocolTwoWayAnonWithErrorResult(
      const MainProtocolTwoWayAnonWithErrorResult&) = default;
  MainProtocolTwoWayAnonWithErrorResult& operator=(
      const MainProtocolTwoWayAnonWithErrorResult&) = default;
  MainProtocolTwoWayAnonWithErrorResult(
      MainProtocolTwoWayAnonWithErrorResult&&) = default;
  MainProtocolTwoWayAnonWithErrorResult& operator=(
      MainProtocolTwoWayAnonWithErrorResult&&) = default;

  enum class Tag : fidl_xunion_tag_t {
    kResponse = 1,  // 0x1
    kErr = 2,       // 0x2
  };

  bool has_invalid_tag() const {
    return ordinal_ ==
           ::test_protocollayouts::wire::MainProtocolTwoWayAnonWithErrorResult::
               Ordinal::Invalid;
  }

  bool is_response() const {
    return ordinal_ ==
           ::test_protocollayouts::wire::MainProtocolTwoWayAnonWithErrorResult::
               Ordinal::kResponse;
  }

  static MainProtocolTwoWayAnonWithErrorResult WithResponse(
      ::fidl::ObjectView<
          ::test_protocollayouts::wire::MainProtocolTwoWayAnonWithErrorResponse>
          val) {
    MainProtocolTwoWayAnonWithErrorResult result;
    result.ordinal_ = ::test_protocollayouts::wire::
        MainProtocolTwoWayAnonWithErrorResult::Ordinal::kResponse;
    result.envelope_
        .As<::test_protocollayouts::wire::
                MainProtocolTwoWayAnonWithErrorResponse>()
        .set_data(std::move(val));
    return result;
  }

  template <typename... Args>
  static MainProtocolTwoWayAnonWithErrorResult WithResponse(
      ::fidl::AnyArena& allocator, Args&&... args) {
    return WithResponse(
        ::fidl::ObjectView<::test_protocollayouts::wire::
                               MainProtocolTwoWayAnonWithErrorResponse>(
            allocator, std::forward<Args>(args)...));
  }

  ::test_protocollayouts::wire::MainProtocolTwoWayAnonWithErrorResponse&
  response() {
    ZX_ASSERT(ordinal_ ==
              ::test_protocollayouts::wire::
                  MainProtocolTwoWayAnonWithErrorResult::Ordinal::kResponse);
    return envelope_
        .As<::test_protocollayouts::wire::
                MainProtocolTwoWayAnonWithErrorResponse>()
        .get_data();
  }
  const ::test_protocollayouts::wire::MainProtocolTwoWayAnonWithErrorResponse&
  response() const {
    ZX_ASSERT(ordinal_ ==
              ::test_protocollayouts::wire::
                  MainProtocolTwoWayAnonWithErrorResult::Ordinal::kResponse);
    return envelope_
        .As<::test_protocollayouts::wire::
                MainProtocolTwoWayAnonWithErrorResponse>()
        .get_data();
  }

  bool is_err() const {
    return ordinal_ == ::test_protocollayouts::wire::
                           MainProtocolTwoWayAnonWithErrorResult::Ordinal::kErr;
  }

  static MainProtocolTwoWayAnonWithErrorResult WithErr(uint32_t val) {
    MainProtocolTwoWayAnonWithErrorResult result;
    result.ordinal_ = ::test_protocollayouts::wire::
        MainProtocolTwoWayAnonWithErrorResult::Ordinal::kErr;
    result.envelope_.As<uint32_t>().set_data(std::move(val));
    return result;
  }

  uint32_t& err() {
    ZX_ASSERT(ordinal_ ==
              ::test_protocollayouts::wire::
                  MainProtocolTwoWayAnonWithErrorResult::Ordinal::kErr);
    return envelope_.As<uint32_t>().get_data();
  }
  const uint32_t& err() const {
    ZX_ASSERT(ordinal_ ==
              ::test_protocollayouts::wire::
                  MainProtocolTwoWayAnonWithErrorResult::Ordinal::kErr);
    return envelope_.As<uint32_t>().get_data();
  }
  ::test_protocollayouts::wire::MainProtocolTwoWayAnonWithErrorResult::Tag
  Which() const {
    ZX_ASSERT(!has_invalid_tag());
    return static_cast<::test_protocollayouts::wire::
                           MainProtocolTwoWayAnonWithErrorResult::Tag>(
        ordinal_);
  }

 private:
  enum class Ordinal : fidl_xunion_tag_t {
    Invalid = 0,
    kResponse = 1,  // 0x1
    kErr = 2,       // 0x2
  };

  static void SizeAndOffsetAssertionHelper();
  ::test_protocollayouts::wire::MainProtocolTwoWayAnonWithErrorResult::Ordinal
      ordinal_;
  FIDL_ALIGNDECL
  ::fidl::UntypedEnvelope envelope_;
};

extern "C" const fidl_type_t
    test_protocollayouts_MainProtocol_OnImportWithError_ResultTable;

class MainProtocolOnImportWithErrorResult {
 public:
  MainProtocolOnImportWithErrorResult()
      : ordinal_(::test_protocollayouts::wire::
                     MainProtocolOnImportWithErrorResult::Ordinal::Invalid),
        envelope_{} {}

  MainProtocolOnImportWithErrorResult(
      const MainProtocolOnImportWithErrorResult&) = default;
  MainProtocolOnImportWithErrorResult& operator=(
      const MainProtocolOnImportWithErrorResult&) = default;
  MainProtocolOnImportWithErrorResult(MainProtocolOnImportWithErrorResult&&) =
      default;
  MainProtocolOnImportWithErrorResult& operator=(
      MainProtocolOnImportWithErrorResult&&) = default;

  enum class Tag : fidl_xunion_tag_t {
    kResponse = 1,  // 0x1
    kErr = 2,       // 0x2
  };

  bool has_invalid_tag() const {
    return ordinal_ ==
           ::test_protocollayouts::wire::MainProtocolOnImportWithErrorResult::
               Ordinal::Invalid;
  }

  bool is_response() const {
    return ordinal_ ==
           ::test_protocollayouts::wire::MainProtocolOnImportWithErrorResult::
               Ordinal::kResponse;
  }

  static MainProtocolOnImportWithErrorResult WithResponse(
      ::fidl::ObjectView<
          ::test_protocollayouts_imported::wire::ImportTablePayload>
          val) {
    MainProtocolOnImportWithErrorResult result;
    result.ordinal_ = ::test_protocollayouts::wire::
        MainProtocolOnImportWithErrorResult::Ordinal::kResponse;
    result.envelope_
        .As<::test_protocollayouts_imported::wire::ImportTablePayload>()
        .set_data(std::move(val));
    return result;
  }

  template <typename... Args>
  static MainProtocolOnImportWithErrorResult WithResponse(
      ::fidl::AnyArena& allocator, Args&&... args) {
    return WithResponse(
        ::fidl::ObjectView<
            ::test_protocollayouts_imported::wire::ImportTablePayload>(
            allocator, std::forward<Args>(args)...));
  }

  ::test_protocollayouts_imported::wire::ImportTablePayload& response() {
    ZX_ASSERT(ordinal_ ==
              ::test_protocollayouts::wire::
                  MainProtocolOnImportWithErrorResult::Ordinal::kResponse);
    return envelope_
        .As<::test_protocollayouts_imported::wire::ImportTablePayload>()
        .get_data();
  }
  const ::test_protocollayouts_imported::wire::ImportTablePayload& response()
      const {
    ZX_ASSERT(ordinal_ ==
              ::test_protocollayouts::wire::
                  MainProtocolOnImportWithErrorResult::Ordinal::kResponse);
    return envelope_
        .As<::test_protocollayouts_imported::wire::ImportTablePayload>()
        .get_data();
  }

  bool is_err() const {
    return ordinal_ == ::test_protocollayouts::wire::
                           MainProtocolOnImportWithErrorResult::Ordinal::kErr;
  }

  static MainProtocolOnImportWithErrorResult WithErr(uint32_t val) {
    MainProtocolOnImportWithErrorResult result;
    result.ordinal_ = ::test_protocollayouts::wire::
        MainProtocolOnImportWithErrorResult::Ordinal::kErr;
    result.envelope_.As<uint32_t>().set_data(std::move(val));
    return result;
  }

  uint32_t& err() {
    ZX_ASSERT(ordinal_ ==
              ::test_protocollayouts::wire::
                  MainProtocolOnImportWithErrorResult::Ordinal::kErr);
    return envelope_.As<uint32_t>().get_data();
  }
  const uint32_t& err() const {
    ZX_ASSERT(ordinal_ ==
              ::test_protocollayouts::wire::
                  MainProtocolOnImportWithErrorResult::Ordinal::kErr);
    return envelope_.As<uint32_t>().get_data();
  }
  ::test_protocollayouts::wire::MainProtocolOnImportWithErrorResult::Tag Which()
      const {
    ZX_ASSERT(!has_invalid_tag());
    return static_cast<
        ::test_protocollayouts::wire::MainProtocolOnImportWithErrorResult::Tag>(
        ordinal_);
  }

 private:
  enum class Ordinal : fidl_xunion_tag_t {
    Invalid = 0,
    kResponse = 1,  // 0x1
    kErr = 2,       // 0x2
  };

  static void SizeAndOffsetAssertionHelper();
  ::test_protocollayouts::wire::MainProtocolOnImportWithErrorResult::Ordinal
      ordinal_;
  FIDL_ALIGNDECL
  ::fidl::UntypedEnvelope envelope_;
};

extern "C" const fidl_type_t
    test_protocollayouts_MainProtocol_OnAnonWithError_ResultTable;

class MainProtocolOnAnonWithErrorResult {
 public:
  using Response =
      test_protocollayouts::wire::MainProtocolOnAnonWithErrorResponse;

  MainProtocolOnAnonWithErrorResult()
      : ordinal_(::test_protocollayouts::wire::
                     MainProtocolOnAnonWithErrorResult::Ordinal::Invalid),
        envelope_{} {}

  MainProtocolOnAnonWithErrorResult(const MainProtocolOnAnonWithErrorResult&) =
      default;
  MainProtocolOnAnonWithErrorResult& operator=(
      const MainProtocolOnAnonWithErrorResult&) = default;
  MainProtocolOnAnonWithErrorResult(MainProtocolOnAnonWithErrorResult&&) =
      default;
  MainProtocolOnAnonWithErrorResult& operator=(
      MainProtocolOnAnonWithErrorResult&&) = default;

  enum class Tag : fidl_xunion_tag_t {
    kResponse = 1,  // 0x1
    kErr = 2,       // 0x2
  };

  bool has_invalid_tag() const {
    return ordinal_ == ::test_protocollayouts::wire::
                           MainProtocolOnAnonWithErrorResult::Ordinal::Invalid;
  }

  bool is_response() const {
    return ordinal_ ==
           ::test_protocollayouts::wire::MainProtocolOnAnonWithErrorResult::
               Ordinal::kResponse;
  }

  static MainProtocolOnAnonWithErrorResult WithResponse(
      ::fidl::ObjectView<
          ::test_protocollayouts::wire::MainProtocolOnAnonWithErrorResponse>
          val) {
    MainProtocolOnAnonWithErrorResult result;
    result.ordinal_ = ::test_protocollayouts::wire::
        MainProtocolOnAnonWithErrorResult::Ordinal::kResponse;
    result.envelope_
        .As<::test_protocollayouts::wire::MainProtocolOnAnonWithErrorResponse>()
        .set_data(std::move(val));
    return result;
  }

  template <typename... Args>
  static MainProtocolOnAnonWithErrorResult WithResponse(
      ::fidl::AnyArena& allocator, Args&&... args) {
    return WithResponse(
        ::fidl::ObjectView<
            ::test_protocollayouts::wire::MainProtocolOnAnonWithErrorResponse>(
            allocator, std::forward<Args>(args)...));
  }

  ::test_protocollayouts::wire::MainProtocolOnAnonWithErrorResponse&
  response() {
    ZX_ASSERT(ordinal_ ==
              ::test_protocollayouts::wire::MainProtocolOnAnonWithErrorResult::
                  Ordinal::kResponse);
    return envelope_
        .As<::test_protocollayouts::wire::MainProtocolOnAnonWithErrorResponse>()
        .get_data();
  }
  const ::test_protocollayouts::wire::MainProtocolOnAnonWithErrorResponse&
  response() const {
    ZX_ASSERT(ordinal_ ==
              ::test_protocollayouts::wire::MainProtocolOnAnonWithErrorResult::
                  Ordinal::kResponse);
    return envelope_
        .As<::test_protocollayouts::wire::MainProtocolOnAnonWithErrorResponse>()
        .get_data();
  }

  bool is_err() const {
    return ordinal_ == ::test_protocollayouts::wire::
                           MainProtocolOnAnonWithErrorResult::Ordinal::kErr;
  }

  static MainProtocolOnAnonWithErrorResult WithErr(uint32_t val) {
    MainProtocolOnAnonWithErrorResult result;
    result.ordinal_ = ::test_protocollayouts::wire::
        MainProtocolOnAnonWithErrorResult::Ordinal::kErr;
    result.envelope_.As<uint32_t>().set_data(std::move(val));
    return result;
  }

  uint32_t& err() {
    ZX_ASSERT(ordinal_ == ::test_protocollayouts::wire::
                              MainProtocolOnAnonWithErrorResult::Ordinal::kErr);
    return envelope_.As<uint32_t>().get_data();
  }
  const uint32_t& err() const {
    ZX_ASSERT(ordinal_ == ::test_protocollayouts::wire::
                              MainProtocolOnAnonWithErrorResult::Ordinal::kErr);
    return envelope_.As<uint32_t>().get_data();
  }
  ::test_protocollayouts::wire::MainProtocolOnAnonWithErrorResult::Tag Which()
      const {
    ZX_ASSERT(!has_invalid_tag());
    return static_cast<
        ::test_protocollayouts::wire::MainProtocolOnAnonWithErrorResult::Tag>(
        ordinal_);
  }

 private:
  enum class Ordinal : fidl_xunion_tag_t {
    Invalid = 0,
    kResponse = 1,  // 0x1
    kErr = 2,       // 0x2
  };

  static void SizeAndOffsetAssertionHelper();
  ::test_protocollayouts::wire::MainProtocolOnAnonWithErrorResult::Ordinal
      ordinal_;
  FIDL_ALIGNDECL
  ::fidl::UntypedEnvelope envelope_;
};

extern "C" const fidl_type_t
    test_protocollayouts_MainProtocolTwoWayAnonRequestTable;

class MainProtocolTwoWayAnonRequest {
 public:
  MainProtocolTwoWayAnonRequest()
      : ordinal_(::test_protocollayouts::wire::MainProtocolTwoWayAnonRequest::
                     Ordinal::Invalid),
        envelope_{} {}

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

  enum class Tag : fidl_xunion_tag_t {
    kB = 1,  // 0x1
    kUnknown = ::std::numeric_limits<::fidl_union_tag_t>::max(),
  };

  bool has_invalid_tag() const {
    return ordinal_ == ::test_protocollayouts::wire::
                           MainProtocolTwoWayAnonRequest::Ordinal::Invalid;
  }

  bool is_b() const {
    return ordinal_ == ::test_protocollayouts::wire::
                           MainProtocolTwoWayAnonRequest::Ordinal::kB;
  }

  static MainProtocolTwoWayAnonRequest WithB(bool val) {
    MainProtocolTwoWayAnonRequest result;
    result.ordinal_ = ::test_protocollayouts::wire::
        MainProtocolTwoWayAnonRequest::Ordinal::kB;
    result.envelope_.As<bool>().set_data(std::move(val));
    return result;
  }

  bool& b() {
    ZX_ASSERT(ordinal_ == ::test_protocollayouts::wire::
                              MainProtocolTwoWayAnonRequest::Ordinal::kB);
    return envelope_.As<bool>().get_data();
  }
  const bool& b() const {
    ZX_ASSERT(ordinal_ == ::test_protocollayouts::wire::
                              MainProtocolTwoWayAnonRequest::Ordinal::kB);
    return envelope_.As<bool>().get_data();
  }
  ::test_protocollayouts::wire::MainProtocolTwoWayAnonRequest::Tag Which()
      const;

 private:
  enum class Ordinal : fidl_xunion_tag_t {
    Invalid = 0,
    kB = 1,  // 0x1
  };

  static void SizeAndOffsetAssertionHelper();
  ::test_protocollayouts::wire::MainProtocolTwoWayAnonRequest::Ordinal ordinal_;
  FIDL_ALIGNDECL
  ::fidl::UntypedEnvelope envelope_;
};

extern "C" const fidl_type_t
    test_protocollayouts_MainProtocolOnAnonRequestTable;

class MainProtocolOnAnonRequest {
 public:
  MainProtocolOnAnonRequest()
      : ordinal_(::test_protocollayouts::wire::MainProtocolOnAnonRequest::
                     Ordinal::Invalid),
        envelope_{} {}

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

  enum class Tag : fidl_xunion_tag_t {
    kB = 1,  // 0x1
    kUnknown = ::std::numeric_limits<::fidl_union_tag_t>::max(),
  };

  bool has_invalid_tag() const {
    return ordinal_ == ::test_protocollayouts::wire::MainProtocolOnAnonRequest::
                           Ordinal::Invalid;
  }

  bool is_b() const {
    return ordinal_ ==
           ::test_protocollayouts::wire::MainProtocolOnAnonRequest::Ordinal::kB;
  }

  static MainProtocolOnAnonRequest WithB(bool val) {
    MainProtocolOnAnonRequest result;
    result.ordinal_ =
        ::test_protocollayouts::wire::MainProtocolOnAnonRequest::Ordinal::kB;
    result.envelope_.As<bool>().set_data(std::move(val));
    return result;
  }

  bool& b() {
    ZX_ASSERT(
        ordinal_ ==
        ::test_protocollayouts::wire::MainProtocolOnAnonRequest::Ordinal::kB);
    return envelope_.As<bool>().get_data();
  }
  const bool& b() const {
    ZX_ASSERT(
        ordinal_ ==
        ::test_protocollayouts::wire::MainProtocolOnAnonRequest::Ordinal::kB);
    return envelope_.As<bool>().get_data();
  }
  ::test_protocollayouts::wire::MainProtocolOnAnonRequest::Tag Which() const;

 private:
  enum class Ordinal : fidl_xunion_tag_t {
    Invalid = 0,
    kB = 1,  // 0x1
  };

  static void SizeAndOffsetAssertionHelper();
  ::test_protocollayouts::wire::MainProtocolOnAnonRequest::Ordinal ordinal_;
  FIDL_ALIGNDECL
  ::fidl::UntypedEnvelope envelope_;
};

extern "C" const fidl_type_t test_protocollayouts_LocalUnionPayloadTable;

class LocalUnionPayload {
 public:
  LocalUnionPayload()
      : ordinal_(
            ::test_protocollayouts::wire::LocalUnionPayload::Ordinal::Invalid),
        envelope_{} {}

  LocalUnionPayload(const LocalUnionPayload&) = default;
  LocalUnionPayload& operator=(const LocalUnionPayload&) = default;
  LocalUnionPayload(LocalUnionPayload&&) = default;
  LocalUnionPayload& operator=(LocalUnionPayload&&) = default;

  enum class Tag : fidl_xunion_tag_t {
    kB = 1,  // 0x1
    kUnknown = ::std::numeric_limits<::fidl_union_tag_t>::max(),
  };

  bool has_invalid_tag() const {
    return ordinal_ ==
           ::test_protocollayouts::wire::LocalUnionPayload::Ordinal::Invalid;
  }

  bool is_b() const {
    return ordinal_ ==
           ::test_protocollayouts::wire::LocalUnionPayload::Ordinal::kB;
  }

  static LocalUnionPayload WithB(bool val) {
    LocalUnionPayload result;
    result.ordinal_ =
        ::test_protocollayouts::wire::LocalUnionPayload::Ordinal::kB;
    result.envelope_.As<bool>().set_data(std::move(val));
    return result;
  }

  bool& b() {
    ZX_ASSERT(ordinal_ ==
              ::test_protocollayouts::wire::LocalUnionPayload::Ordinal::kB);
    return envelope_.As<bool>().get_data();
  }
  const bool& b() const {
    ZX_ASSERT(ordinal_ ==
              ::test_protocollayouts::wire::LocalUnionPayload::Ordinal::kB);
    return envelope_.As<bool>().get_data();
  }
  ::test_protocollayouts::wire::LocalUnionPayload::Tag Which() const;

 private:
  enum class Ordinal : fidl_xunion_tag_t {
    Invalid = 0,
    kB = 1,  // 0x1
  };

  static void SizeAndOffsetAssertionHelper();
  ::test_protocollayouts::wire::LocalUnionPayload::Ordinal ordinal_;
  FIDL_ALIGNDECL
  ::fidl::UntypedEnvelope envelope_;
};

extern "C" const fidl_type_t
    test_protocollayouts_MainProtocol_TwoWayLocalWithError_ResultTable;

class MainProtocolTwoWayLocalWithErrorResult {
 public:
  MainProtocolTwoWayLocalWithErrorResult()
      : ordinal_(::test_protocollayouts::wire::
                     MainProtocolTwoWayLocalWithErrorResult::Ordinal::Invalid),
        envelope_{} {}

  MainProtocolTwoWayLocalWithErrorResult(
      const MainProtocolTwoWayLocalWithErrorResult&) = default;
  MainProtocolTwoWayLocalWithErrorResult& operator=(
      const MainProtocolTwoWayLocalWithErrorResult&) = default;
  MainProtocolTwoWayLocalWithErrorResult(
      MainProtocolTwoWayLocalWithErrorResult&&) = default;
  MainProtocolTwoWayLocalWithErrorResult& operator=(
      MainProtocolTwoWayLocalWithErrorResult&&) = default;

  enum class Tag : fidl_xunion_tag_t {
    kResponse = 1,  // 0x1
    kErr = 2,       // 0x2
  };

  bool has_invalid_tag() const {
    return ordinal_ ==
           ::test_protocollayouts::wire::
               MainProtocolTwoWayLocalWithErrorResult::Ordinal::Invalid;
  }

  bool is_response() const {
    return ordinal_ ==
           ::test_protocollayouts::wire::
               MainProtocolTwoWayLocalWithErrorResult::Ordinal::kResponse;
  }

  static MainProtocolTwoWayLocalWithErrorResult WithResponse(
      ::fidl::ObjectView<::test_protocollayouts::wire::LocalUnionPayload> val) {
    MainProtocolTwoWayLocalWithErrorResult result;
    result.ordinal_ = ::test_protocollayouts::wire::
        MainProtocolTwoWayLocalWithErrorResult::Ordinal::kResponse;
    result.envelope_.As<::test_protocollayouts::wire::LocalUnionPayload>()
        .set_data(std::move(val));
    return result;
  }

  template <typename... Args>
  static MainProtocolTwoWayLocalWithErrorResult WithResponse(
      ::fidl::AnyArena& allocator, Args&&... args) {
    return WithResponse(
        ::fidl::ObjectView<::test_protocollayouts::wire::LocalUnionPayload>(
            allocator, std::forward<Args>(args)...));
  }

  ::test_protocollayouts::wire::LocalUnionPayload& response() {
    ZX_ASSERT(ordinal_ ==
              ::test_protocollayouts::wire::
                  MainProtocolTwoWayLocalWithErrorResult::Ordinal::kResponse);
    return envelope_.As<::test_protocollayouts::wire::LocalUnionPayload>()
        .get_data();
  }
  const ::test_protocollayouts::wire::LocalUnionPayload& response() const {
    ZX_ASSERT(ordinal_ ==
              ::test_protocollayouts::wire::
                  MainProtocolTwoWayLocalWithErrorResult::Ordinal::kResponse);
    return envelope_.As<::test_protocollayouts::wire::LocalUnionPayload>()
        .get_data();
  }

  bool is_err() const {
    return ordinal_ ==
           ::test_protocollayouts::wire::
               MainProtocolTwoWayLocalWithErrorResult::Ordinal::kErr;
  }

  static MainProtocolTwoWayLocalWithErrorResult WithErr(uint32_t val) {
    MainProtocolTwoWayLocalWithErrorResult result;
    result.ordinal_ = ::test_protocollayouts::wire::
        MainProtocolTwoWayLocalWithErrorResult::Ordinal::kErr;
    result.envelope_.As<uint32_t>().set_data(std::move(val));
    return result;
  }

  uint32_t& err() {
    ZX_ASSERT(ordinal_ ==
              ::test_protocollayouts::wire::
                  MainProtocolTwoWayLocalWithErrorResult::Ordinal::kErr);
    return envelope_.As<uint32_t>().get_data();
  }
  const uint32_t& err() const {
    ZX_ASSERT(ordinal_ ==
              ::test_protocollayouts::wire::
                  MainProtocolTwoWayLocalWithErrorResult::Ordinal::kErr);
    return envelope_.As<uint32_t>().get_data();
  }
  ::test_protocollayouts::wire::MainProtocolTwoWayLocalWithErrorResult::Tag
  Which() const {
    ZX_ASSERT(!has_invalid_tag());
    return static_cast<::test_protocollayouts::wire::
                           MainProtocolTwoWayLocalWithErrorResult::Tag>(
        ordinal_);
  }

 private:
  enum class Ordinal : fidl_xunion_tag_t {
    Invalid = 0,
    kResponse = 1,  // 0x1
    kErr = 2,       // 0x2
  };

  static void SizeAndOffsetAssertionHelper();
  ::test_protocollayouts::wire::MainProtocolTwoWayLocalWithErrorResult::Ordinal
      ordinal_;
  FIDL_ALIGNDECL
  ::fidl::UntypedEnvelope envelope_;
};

extern "C" const fidl_type_t
    test_protocollayouts_MainProtocol_OnLocalWithError_ResultTable;

class MainProtocolOnLocalWithErrorResult {
 public:
  MainProtocolOnLocalWithErrorResult()
      : ordinal_(::test_protocollayouts::wire::
                     MainProtocolOnLocalWithErrorResult::Ordinal::Invalid),
        envelope_{} {}

  MainProtocolOnLocalWithErrorResult(
      const MainProtocolOnLocalWithErrorResult&) = default;
  MainProtocolOnLocalWithErrorResult& operator=(
      const MainProtocolOnLocalWithErrorResult&) = default;
  MainProtocolOnLocalWithErrorResult(MainProtocolOnLocalWithErrorResult&&) =
      default;
  MainProtocolOnLocalWithErrorResult& operator=(
      MainProtocolOnLocalWithErrorResult&&) = default;

  enum class Tag : fidl_xunion_tag_t {
    kResponse = 1,  // 0x1
    kErr = 2,       // 0x2
  };

  bool has_invalid_tag() const {
    return ordinal_ == ::test_protocollayouts::wire::
                           MainProtocolOnLocalWithErrorResult::Ordinal::Invalid;
  }

  bool is_response() const {
    return ordinal_ ==
           ::test_protocollayouts::wire::MainProtocolOnLocalWithErrorResult::
               Ordinal::kResponse;
  }

  static MainProtocolOnLocalWithErrorResult WithResponse(
      ::fidl::ObjectView<::test_protocollayouts::wire::LocalTablePayload> val) {
    MainProtocolOnLocalWithErrorResult result;
    result.ordinal_ = ::test_protocollayouts::wire::
        MainProtocolOnLocalWithErrorResult::Ordinal::kResponse;
    result.envelope_.As<::test_protocollayouts::wire::LocalTablePayload>()
        .set_data(std::move(val));
    return result;
  }

  template <typename... Args>
  static MainProtocolOnLocalWithErrorResult WithResponse(
      ::fidl::AnyArena& allocator, Args&&... args) {
    return WithResponse(
        ::fidl::ObjectView<::test_protocollayouts::wire::LocalTablePayload>(
            allocator, std::forward<Args>(args)...));
  }

  ::test_protocollayouts::wire::LocalTablePayload& response() {
    ZX_ASSERT(ordinal_ ==
              ::test_protocollayouts::wire::MainProtocolOnLocalWithErrorResult::
                  Ordinal::kResponse);
    return envelope_.As<::test_protocollayouts::wire::LocalTablePayload>()
        .get_data();
  }
  const ::test_protocollayouts::wire::LocalTablePayload& response() const {
    ZX_ASSERT(ordinal_ ==
              ::test_protocollayouts::wire::MainProtocolOnLocalWithErrorResult::
                  Ordinal::kResponse);
    return envelope_.As<::test_protocollayouts::wire::LocalTablePayload>()
        .get_data();
  }

  bool is_err() const {
    return ordinal_ == ::test_protocollayouts::wire::
                           MainProtocolOnLocalWithErrorResult::Ordinal::kErr;
  }

  static MainProtocolOnLocalWithErrorResult WithErr(uint32_t val) {
    MainProtocolOnLocalWithErrorResult result;
    result.ordinal_ = ::test_protocollayouts::wire::
        MainProtocolOnLocalWithErrorResult::Ordinal::kErr;
    result.envelope_.As<uint32_t>().set_data(std::move(val));
    return result;
  }

  uint32_t& err() {
    ZX_ASSERT(ordinal_ ==
              ::test_protocollayouts::wire::MainProtocolOnLocalWithErrorResult::
                  Ordinal::kErr);
    return envelope_.As<uint32_t>().get_data();
  }
  const uint32_t& err() const {
    ZX_ASSERT(ordinal_ ==
              ::test_protocollayouts::wire::MainProtocolOnLocalWithErrorResult::
                  Ordinal::kErr);
    return envelope_.As<uint32_t>().get_data();
  }
  ::test_protocollayouts::wire::MainProtocolOnLocalWithErrorResult::Tag Which()
      const {
    ZX_ASSERT(!has_invalid_tag());
    return static_cast<
        ::test_protocollayouts::wire::MainProtocolOnLocalWithErrorResult::Tag>(
        ordinal_);
  }

 private:
  enum class Ordinal : fidl_xunion_tag_t {
    Invalid = 0,
    kResponse = 1,  // 0x1
    kErr = 2,       // 0x2
  };

  static void SizeAndOffsetAssertionHelper();
  ::test_protocollayouts::wire::MainProtocolOnLocalWithErrorResult::Ordinal
      ordinal_;
  FIDL_ALIGNDECL
  ::fidl::UntypedEnvelope envelope_;
};

extern "C" const fidl_type_t
    test_protocollayouts_MainProtocolTwoWayImportWithErrorTopResponseTable;

struct MainProtocolTwoWayImportWithErrorTopResponse {
  using Result =
      test_protocollayouts::wire::MainProtocolTwoWayImportWithErrorResult;

  ::test_protocollayouts::wire::MainProtocolTwoWayImportWithErrorResult result =
      {};
};

extern "C" const fidl_type_t
    test_protocollayouts_MainProtocolTwoWayAnonWithErrorTopResponseTable;

struct MainProtocolTwoWayAnonWithErrorTopResponse {
  using Result =
      test_protocollayouts::wire::MainProtocolTwoWayAnonWithErrorResult;

  ::test_protocollayouts::wire::MainProtocolTwoWayAnonWithErrorResult result =
      {};
};

extern "C" const fidl_type_t
    test_protocollayouts_MainProtocolOnImportWithErrorRequestTable;

struct MainProtocolOnImportWithErrorRequest {
  using Result =
      test_protocollayouts::wire::MainProtocolOnImportWithErrorResult;

  ::test_protocollayouts::wire::MainProtocolOnImportWithErrorResult result = {};
};

extern "C" const fidl_type_t
    test_protocollayouts_MainProtocolOnAnonWithErrorRequestTable;

struct MainProtocolOnAnonWithErrorRequest {
  using Result = test_protocollayouts::wire::MainProtocolOnAnonWithErrorResult;

  ::test_protocollayouts::wire::MainProtocolOnAnonWithErrorResult result = {};
};

extern "C" const fidl_type_t
    test_protocollayouts_MainProtocolTwoWayLocalWithErrorTopResponseTable;

struct MainProtocolTwoWayLocalWithErrorTopResponse {
  using Result =
      test_protocollayouts::wire::MainProtocolTwoWayLocalWithErrorResult;

  ::test_protocollayouts::wire::MainProtocolTwoWayLocalWithErrorResult result =
      {};
};

extern "C" const fidl_type_t
    test_protocollayouts_MainProtocolOnLocalWithErrorRequestTable;

struct MainProtocolOnLocalWithErrorRequest {
  using Result = test_protocollayouts::wire::MainProtocolOnLocalWithErrorResult;

  ::test_protocollayouts::wire::MainProtocolOnLocalWithErrorResult result = {};
};

}  // namespace wire
}  // namespace test_protocollayouts
namespace fidl {

template <>
struct TypeTraits<::test_protocollayouts::wire::
                      MainProtocolTwoWayImportWithErrorTopResponse> {
  static constexpr const fidl_type_t* kType =
      &::test_protocollayouts::wire::
          test_protocollayouts_MainProtocolTwoWayImportWithErrorTopResponseTable;
  static constexpr uint32_t kMaxNumHandles = 0;
  static constexpr uint32_t kPrimarySize = 16;
  static constexpr uint32_t kPrimarySizeV1 = 24;
  [[maybe_unused]] static constexpr uint32_t kMaxOutOfLine = 16;
  static constexpr uint32_t kMaxOutOfLineV1 = 32;
  static constexpr bool kHasPointer = true;
};

template <>
struct IsFidlType<
    ::test_protocollayouts::wire::MainProtocolTwoWayImportWithErrorTopResponse>
    : public std::true_type {};
template <>
struct IsStruct<
    ::test_protocollayouts::wire::MainProtocolTwoWayImportWithErrorTopResponse>
    : public std::true_type {};
static_assert(std::is_standard_layout_v<
              ::test_protocollayouts::wire::
                  MainProtocolTwoWayImportWithErrorTopResponse>);
static_assert(offsetof(::test_protocollayouts::wire::
                           MainProtocolTwoWayImportWithErrorTopResponse,
                       result) == 0);
static_assert(
    sizeof(::test_protocollayouts::wire::
               MainProtocolTwoWayImportWithErrorTopResponse) ==
    TypeTraits<::test_protocollayouts::wire::
                   MainProtocolTwoWayImportWithErrorTopResponse>::kPrimarySize);

template <>
struct TypeTraits<
    ::test_protocollayouts::wire::MainProtocolTwoWayAnonWithErrorTopResponse> {
  static constexpr const fidl_type_t* kType =
      &::test_protocollayouts::wire::
          test_protocollayouts_MainProtocolTwoWayAnonWithErrorTopResponseTable;
  static constexpr uint32_t kMaxNumHandles = 0;
  static constexpr uint32_t kPrimarySize = 16;
  static constexpr uint32_t kPrimarySizeV1 = 24;
  [[maybe_unused]] static constexpr uint32_t kMaxOutOfLine = 16;
  static constexpr uint32_t kMaxOutOfLineV1 = 32;
  static constexpr bool kHasPointer = true;
};

template <>
struct IsFidlType<
    ::test_protocollayouts::wire::MainProtocolTwoWayAnonWithErrorTopResponse>
    : public std::true_type {};
template <>
struct IsStruct<
    ::test_protocollayouts::wire::MainProtocolTwoWayAnonWithErrorTopResponse>
    : public std::true_type {};
static_assert(
    std::is_standard_layout_v<::test_protocollayouts::wire::
                                  MainProtocolTwoWayAnonWithErrorTopResponse>);
static_assert(offsetof(::test_protocollayouts::wire::
                           MainProtocolTwoWayAnonWithErrorTopResponse,
                       result) == 0);
static_assert(
    sizeof(::test_protocollayouts::wire::
               MainProtocolTwoWayAnonWithErrorTopResponse) ==
    TypeTraits<::test_protocollayouts::wire::
                   MainProtocolTwoWayAnonWithErrorTopResponse>::kPrimarySize);

template <>
struct TypeTraits<
    ::test_protocollayouts::wire::MainProtocolOnImportWithErrorRequest> {
  static constexpr const fidl_type_t* kType =
      &::test_protocollayouts::wire::
          test_protocollayouts_MainProtocolOnImportWithErrorRequestTable;
  static constexpr uint32_t kMaxNumHandles = 0;
  static constexpr uint32_t kPrimarySize = 16;
  static constexpr uint32_t kPrimarySizeV1 = 24;
  [[maybe_unused]] static constexpr uint32_t kMaxOutOfLine = 24;
  static constexpr uint32_t kMaxOutOfLineV1 = 40;
  static constexpr bool kHasPointer = true;
};

template <>
struct IsFidlType<
    ::test_protocollayouts::wire::MainProtocolOnImportWithErrorRequest>
    : public std::true_type {};
template <>
struct IsStruct<
    ::test_protocollayouts::wire::MainProtocolOnImportWithErrorRequest>
    : public std::true_type {};
static_assert(
    std::is_standard_layout_v<
        ::test_protocollayouts::wire::MainProtocolOnImportWithErrorRequest>);
static_assert(
    offsetof(::test_protocollayouts::wire::MainProtocolOnImportWithErrorRequest,
             result) == 0);
static_assert(
    sizeof(
        ::test_protocollayouts::wire::MainProtocolOnImportWithErrorRequest) ==
    TypeTraits<::test_protocollayouts::wire::
                   MainProtocolOnImportWithErrorRequest>::kPrimarySize);

template <>
struct TypeTraits<
    ::test_protocollayouts::wire::MainProtocolOnAnonWithErrorRequest> {
  static constexpr const fidl_type_t* kType =
      &::test_protocollayouts::wire::
          test_protocollayouts_MainProtocolOnAnonWithErrorRequestTable;
  static constexpr uint32_t kMaxNumHandles = 0;
  static constexpr uint32_t kPrimarySize = 16;
  static constexpr uint32_t kPrimarySizeV1 = 24;
  [[maybe_unused]] static constexpr uint32_t kMaxOutOfLine = 24;
  static constexpr uint32_t kMaxOutOfLineV1 = 40;
  static constexpr bool kHasPointer = true;
};

template <>
struct IsFidlType<
    ::test_protocollayouts::wire::MainProtocolOnAnonWithErrorRequest>
    : public std::true_type {};
template <>
struct IsStruct<
    ::test_protocollayouts::wire::MainProtocolOnAnonWithErrorRequest>
    : public std::true_type {};
static_assert(
    std::is_standard_layout_v<
        ::test_protocollayouts::wire::MainProtocolOnAnonWithErrorRequest>);
static_assert(
    offsetof(::test_protocollayouts::wire::MainProtocolOnAnonWithErrorRequest,
             result) == 0);
static_assert(
    sizeof(::test_protocollayouts::wire::MainProtocolOnAnonWithErrorRequest) ==
    TypeTraits<::test_protocollayouts::wire::
                   MainProtocolOnAnonWithErrorRequest>::kPrimarySize);

template <>
struct TypeTraits<
    ::test_protocollayouts::wire::MainProtocolTwoWayLocalWithErrorTopResponse> {
  static constexpr const fidl_type_t* kType =
      &::test_protocollayouts::wire::
          test_protocollayouts_MainProtocolTwoWayLocalWithErrorTopResponseTable;
  static constexpr uint32_t kMaxNumHandles = 0;
  static constexpr uint32_t kPrimarySize = 16;
  static constexpr uint32_t kPrimarySizeV1 = 24;
  [[maybe_unused]] static constexpr uint32_t kMaxOutOfLine = 16;
  static constexpr uint32_t kMaxOutOfLineV1 = 32;
  static constexpr bool kHasPointer = true;
};

template <>
struct IsFidlType<
    ::test_protocollayouts::wire::MainProtocolTwoWayLocalWithErrorTopResponse>
    : public std::true_type {};
template <>
struct IsStruct<
    ::test_protocollayouts::wire::MainProtocolTwoWayLocalWithErrorTopResponse>
    : public std::true_type {};
static_assert(
    std::is_standard_layout_v<::test_protocollayouts::wire::
                                  MainProtocolTwoWayLocalWithErrorTopResponse>);
static_assert(offsetof(::test_protocollayouts::wire::
                           MainProtocolTwoWayLocalWithErrorTopResponse,
                       result) == 0);
static_assert(
    sizeof(::test_protocollayouts::wire::
               MainProtocolTwoWayLocalWithErrorTopResponse) ==
    TypeTraits<::test_protocollayouts::wire::
                   MainProtocolTwoWayLocalWithErrorTopResponse>::kPrimarySize);

template <>
struct TypeTraits<
    ::test_protocollayouts::wire::MainProtocolOnLocalWithErrorRequest> {
  static constexpr const fidl_type_t* kType =
      &::test_protocollayouts::wire::
          test_protocollayouts_MainProtocolOnLocalWithErrorRequestTable;
  static constexpr uint32_t kMaxNumHandles = 0;
  static constexpr uint32_t kPrimarySize = 16;
  static constexpr uint32_t kPrimarySizeV1 = 24;
  [[maybe_unused]] static constexpr uint32_t kMaxOutOfLine = 24;
  static constexpr uint32_t kMaxOutOfLineV1 = 40;
  static constexpr bool kHasPointer = true;
};

template <>
struct IsFidlType<
    ::test_protocollayouts::wire::MainProtocolOnLocalWithErrorRequest>
    : public std::true_type {};
template <>
struct IsStruct<
    ::test_protocollayouts::wire::MainProtocolOnLocalWithErrorRequest>
    : public std::true_type {};
static_assert(
    std::is_standard_layout_v<
        ::test_protocollayouts::wire::MainProtocolOnLocalWithErrorRequest>);
static_assert(
    offsetof(::test_protocollayouts::wire::MainProtocolOnLocalWithErrorRequest,
             result) == 0);
static_assert(
    sizeof(::test_protocollayouts::wire::MainProtocolOnLocalWithErrorRequest) ==
    TypeTraits<::test_protocollayouts::wire::
                   MainProtocolOnLocalWithErrorRequest>::kPrimarySize);

template <>
struct TypeTraits<
    ::test_protocollayouts::wire::MainProtocolOnAnonWithErrorResponse> {
  static constexpr const fidl_type_t* kType =
      &::test_protocollayouts::wire::
          test_protocollayouts_MainProtocol_OnAnonWithError_ResponseTable;
  static constexpr uint32_t kMaxNumHandles = 0;
  static constexpr uint32_t kPrimarySize = 16;
  static constexpr uint32_t kPrimarySizeV1 = 16;
  [[maybe_unused]] static constexpr uint32_t kMaxOutOfLine = 8;
  static constexpr uint32_t kMaxOutOfLineV1 = 24;
  static constexpr bool kHasPointer = true;
};

template <>
struct IsFidlType<
    ::test_protocollayouts::wire::MainProtocolOnAnonWithErrorResponse>
    : public std::true_type {};
template <>
struct IsTable<
    ::test_protocollayouts::wire::MainProtocolOnAnonWithErrorResponse>
    : public std::true_type {};
static_assert(
    std::is_standard_layout_v<
        ::test_protocollayouts::wire::MainProtocolOnAnonWithErrorResponse>);

template <>
struct TypeTraits<
    ::test_protocollayouts::wire::MainProtocolTwoWayAnonWithErrorRequest> {
  static constexpr const fidl_type_t* kType =
      &::test_protocollayouts::wire::
          test_protocollayouts_MainProtocolTwoWayAnonWithErrorRequestTable;
  static constexpr uint32_t kMaxNumHandles = 0;
  static constexpr uint32_t kPrimarySize = 16;
  static constexpr uint32_t kPrimarySizeV1 = 16;
  [[maybe_unused]] static constexpr uint32_t kMaxOutOfLine = 8;
  static constexpr uint32_t kMaxOutOfLineV1 = 24;
  static constexpr bool kHasPointer = true;
};

template <>
struct IsFidlType<
    ::test_protocollayouts::wire::MainProtocolTwoWayAnonWithErrorRequest>
    : public std::true_type {};
template <>
struct IsTable<
    ::test_protocollayouts::wire::MainProtocolTwoWayAnonWithErrorRequest>
    : public std::true_type {};
static_assert(
    std::is_standard_layout_v<
        ::test_protocollayouts::wire::MainProtocolTwoWayAnonWithErrorRequest>);

template <>
struct TypeTraits<
    ::test_protocollayouts::wire::MainProtocolTwoWayAnonResponse> {
  static constexpr const fidl_type_t* kType =
      &::test_protocollayouts::wire::
          test_protocollayouts_MainProtocolTwoWayAnonResponseTable;
  static constexpr uint32_t kMaxNumHandles = 0;
  static constexpr uint32_t kPrimarySize = 16;
  static constexpr uint32_t kPrimarySizeV1 = 16;
  [[maybe_unused]] static constexpr uint32_t kMaxOutOfLine = 8;
  static constexpr uint32_t kMaxOutOfLineV1 = 24;
  static constexpr bool kHasPointer = true;
};

template <>
struct IsFidlType<::test_protocollayouts::wire::MainProtocolTwoWayAnonResponse>
    : public std::true_type {};
template <>
struct IsTable<::test_protocollayouts::wire::MainProtocolTwoWayAnonResponse>
    : public std::true_type {};
static_assert(std::is_standard_layout_v<
              ::test_protocollayouts::wire::MainProtocolTwoWayAnonResponse>);

template <>
struct TypeTraits<::test_protocollayouts::wire::MainProtocolOneWayAnonRequest> {
  static constexpr const fidl_type_t* kType =
      &::test_protocollayouts::wire::
          test_protocollayouts_MainProtocolOneWayAnonRequestTable;
  static constexpr uint32_t kMaxNumHandles = 0;
  static constexpr uint32_t kPrimarySize = 16;
  static constexpr uint32_t kPrimarySizeV1 = 16;
  [[maybe_unused]] static constexpr uint32_t kMaxOutOfLine = 8;
  static constexpr uint32_t kMaxOutOfLineV1 = 24;
  static constexpr bool kHasPointer = true;
};

template <>
struct IsFidlType<::test_protocollayouts::wire::MainProtocolOneWayAnonRequest>
    : public std::true_type {};
template <>
struct IsTable<::test_protocollayouts::wire::MainProtocolOneWayAnonRequest>
    : public std::true_type {};
static_assert(std::is_standard_layout_v<
              ::test_protocollayouts::wire::MainProtocolOneWayAnonRequest>);

template <>
struct TypeTraits<::test_protocollayouts::wire::LocalTablePayload> {
  static constexpr const fidl_type_t* kType =
      &::test_protocollayouts::wire::
          test_protocollayouts_LocalTablePayloadTable;
  static constexpr uint32_t kMaxNumHandles = 0;
  static constexpr uint32_t kPrimarySize = 16;
  static constexpr uint32_t kPrimarySizeV1 = 16;
  [[maybe_unused]] static constexpr uint32_t kMaxOutOfLine = 8;
  static constexpr uint32_t kMaxOutOfLineV1 = 24;
  static constexpr bool kHasPointer = true;
};

template <>
struct IsFidlType<::test_protocollayouts::wire::LocalTablePayload>
    : public std::true_type {};
template <>
struct IsTable<::test_protocollayouts::wire::LocalTablePayload>
    : public std::true_type {};
static_assert(
    std::is_standard_layout_v<::test_protocollayouts::wire::LocalTablePayload>);

template <>
struct TypeTraits<
    ::test_protocollayouts::wire::MainProtocolTwoWayImportWithErrorResult> {
  static constexpr const fidl_type_t* kType =
      &::test_protocollayouts::wire::
          test_protocollayouts_MainProtocol_TwoWayImportWithError_ResultTable;
  static constexpr uint32_t kMaxNumHandles = 0;
  static constexpr uint32_t kPrimarySize = 16;
  static constexpr uint32_t kPrimarySizeV1 = 24;
  [[maybe_unused]] static constexpr uint32_t kMaxOutOfLine = 16;
  static constexpr uint32_t kMaxOutOfLineV1 = 32;
  static constexpr bool kHasPointer = true;
};

template <>
struct IsFidlType<
    ::test_protocollayouts::wire::MainProtocolTwoWayImportWithErrorResult>
    : public std::true_type {};
template <>
struct IsUnion<
    ::test_protocollayouts::wire::MainProtocolTwoWayImportWithErrorResult>
    : public std::true_type {};
static_assert(
    std::is_standard_layout_v<
        ::test_protocollayouts::wire::MainProtocolTwoWayImportWithErrorResult>);

template <>
struct TypeTraits<
    ::test_protocollayouts::wire::MainProtocolTwoWayAnonWithErrorResponse> {
  static constexpr const fidl_type_t* kType =
      &::test_protocollayouts::wire::
          test_protocollayouts_MainProtocol_TwoWayAnonWithError_ResponseTable;
  static constexpr uint32_t kMaxNumHandles = 0;
  static constexpr uint32_t kPrimarySize = 16;
  static constexpr uint32_t kPrimarySizeV1 = 24;
  [[maybe_unused]] static constexpr uint32_t kMaxOutOfLine = 0;
  static constexpr uint32_t kMaxOutOfLineV1 = 8;
  static constexpr bool kHasPointer = true;
};

template <>
struct IsFidlType<
    ::test_protocollayouts::wire::MainProtocolTwoWayAnonWithErrorResponse>
    : public std::true_type {};
template <>
struct IsUnion<
    ::test_protocollayouts::wire::MainProtocolTwoWayAnonWithErrorResponse>
    : public std::true_type {};
static_assert(
    std::is_standard_layout_v<
        ::test_protocollayouts::wire::MainProtocolTwoWayAnonWithErrorResponse>);

template <>
struct TypeTraits<
    ::test_protocollayouts::wire::MainProtocolTwoWayAnonWithErrorResult> {
  static constexpr const fidl_type_t* kType =
      &::test_protocollayouts::wire::
          test_protocollayouts_MainProtocol_TwoWayAnonWithError_ResultTable;
  static constexpr uint32_t kMaxNumHandles = 0;
  static constexpr uint32_t kPrimarySize = 16;
  static constexpr uint32_t kPrimarySizeV1 = 24;
  [[maybe_unused]] static constexpr uint32_t kMaxOutOfLine = 16;
  static constexpr uint32_t kMaxOutOfLineV1 = 32;
  static constexpr bool kHasPointer = true;
};

template <>
struct IsFidlType<
    ::test_protocollayouts::wire::MainProtocolTwoWayAnonWithErrorResult>
    : public std::true_type {};
template <>
struct IsUnion<
    ::test_protocollayouts::wire::MainProtocolTwoWayAnonWithErrorResult>
    : public std::true_type {};
static_assert(
    std::is_standard_layout_v<
        ::test_protocollayouts::wire::MainProtocolTwoWayAnonWithErrorResult>);

template <>
struct TypeTraits<
    ::test_protocollayouts::wire::MainProtocolOnImportWithErrorResult> {
  static constexpr const fidl_type_t* kType =
      &::test_protocollayouts::wire::
          test_protocollayouts_MainProtocol_OnImportWithError_ResultTable;
  static constexpr uint32_t kMaxNumHandles = 0;
  static constexpr uint32_t kPrimarySize = 16;
  static constexpr uint32_t kPrimarySizeV1 = 24;
  [[maybe_unused]] static constexpr uint32_t kMaxOutOfLine = 24;
  static constexpr uint32_t kMaxOutOfLineV1 = 40;
  static constexpr bool kHasPointer = true;
};

template <>
struct IsFidlType<
    ::test_protocollayouts::wire::MainProtocolOnImportWithErrorResult>
    : public std::true_type {};
template <>
struct IsUnion<
    ::test_protocollayouts::wire::MainProtocolOnImportWithErrorResult>
    : public std::true_type {};
static_assert(
    std::is_standard_layout_v<
        ::test_protocollayouts::wire::MainProtocolOnImportWithErrorResult>);

template <>
struct TypeTraits<
    ::test_protocollayouts::wire::MainProtocolOnAnonWithErrorResult> {
  static constexpr const fidl_type_t* kType =
      &::test_protocollayouts::wire::
          test_protocollayouts_MainProtocol_OnAnonWithError_ResultTable;
  static constexpr uint32_t kMaxNumHandles = 0;
  static constexpr uint32_t kPrimarySize = 16;
  static constexpr uint32_t kPrimarySizeV1 = 24;
  [[maybe_unused]] static constexpr uint32_t kMaxOutOfLine = 24;
  static constexpr uint32_t kMaxOutOfLineV1 = 40;
  static constexpr bool kHasPointer = true;
};

template <>
struct IsFidlType<
    ::test_protocollayouts::wire::MainProtocolOnAnonWithErrorResult>
    : public std::true_type {};
template <>
struct IsUnion<::test_protocollayouts::wire::MainProtocolOnAnonWithErrorResult>
    : public std::true_type {};
static_assert(std::is_standard_layout_v<
              ::test_protocollayouts::wire::MainProtocolOnAnonWithErrorResult>);

template <>
struct TypeTraits<::test_protocollayouts::wire::MainProtocolTwoWayAnonRequest> {
  static constexpr const fidl_type_t* kType =
      &::test_protocollayouts::wire::
          test_protocollayouts_MainProtocolTwoWayAnonRequestTable;
  static constexpr uint32_t kMaxNumHandles = 0;
  static constexpr uint32_t kPrimarySize = 16;
  static constexpr uint32_t kPrimarySizeV1 = 24;
  [[maybe_unused]] static constexpr uint32_t kMaxOutOfLine = 0;
  static constexpr uint32_t kMaxOutOfLineV1 = 8;
  static constexpr bool kHasPointer = true;
};

template <>
struct IsFidlType<::test_protocollayouts::wire::MainProtocolTwoWayAnonRequest>
    : public std::true_type {};
template <>
struct IsUnion<::test_protocollayouts::wire::MainProtocolTwoWayAnonRequest>
    : public std::true_type {};
static_assert(std::is_standard_layout_v<
              ::test_protocollayouts::wire::MainProtocolTwoWayAnonRequest>);

template <>
struct TypeTraits<::test_protocollayouts::wire::MainProtocolOnAnonRequest> {
  static constexpr const fidl_type_t* kType =
      &::test_protocollayouts::wire::
          test_protocollayouts_MainProtocolOnAnonRequestTable;
  static constexpr uint32_t kMaxNumHandles = 0;
  static constexpr uint32_t kPrimarySize = 16;
  static constexpr uint32_t kPrimarySizeV1 = 24;
  [[maybe_unused]] static constexpr uint32_t kMaxOutOfLine = 0;
  static constexpr uint32_t kMaxOutOfLineV1 = 8;
  static constexpr bool kHasPointer = true;
};

template <>
struct IsFidlType<::test_protocollayouts::wire::MainProtocolOnAnonRequest>
    : public std::true_type {};
template <>
struct IsUnion<::test_protocollayouts::wire::MainProtocolOnAnonRequest>
    : public std::true_type {};
static_assert(std::is_standard_layout_v<
              ::test_protocollayouts::wire::MainProtocolOnAnonRequest>);

template <>
struct TypeTraits<::test_protocollayouts::wire::LocalUnionPayload> {
  static constexpr const fidl_type_t* kType =
      &::test_protocollayouts::wire::
          test_protocollayouts_LocalUnionPayloadTable;
  static constexpr uint32_t kMaxNumHandles = 0;
  static constexpr uint32_t kPrimarySize = 16;
  static constexpr uint32_t kPrimarySizeV1 = 24;
  [[maybe_unused]] static constexpr uint32_t kMaxOutOfLine = 0;
  static constexpr uint32_t kMaxOutOfLineV1 = 8;
  static constexpr bool kHasPointer = true;
};

template <>
struct IsFidlType<::test_protocollayouts::wire::LocalUnionPayload>
    : public std::true_type {};
template <>
struct IsUnion<::test_protocollayouts::wire::LocalUnionPayload>
    : public std::true_type {};
static_assert(
    std::is_standard_layout_v<::test_protocollayouts::wire::LocalUnionPayload>);

template <>
struct TypeTraits<
    ::test_protocollayouts::wire::MainProtocolTwoWayLocalWithErrorResult> {
  static constexpr const fidl_type_t* kType =
      &::test_protocollayouts::wire::
          test_protocollayouts_MainProtocol_TwoWayLocalWithError_ResultTable;
  static constexpr uint32_t kMaxNumHandles = 0;
  static constexpr uint32_t kPrimarySize = 16;
  static constexpr uint32_t kPrimarySizeV1 = 24;
  [[maybe_unused]] static constexpr uint32_t kMaxOutOfLine = 16;
  static constexpr uint32_t kMaxOutOfLineV1 = 32;
  static constexpr bool kHasPointer = true;
};

template <>
struct IsFidlType<
    ::test_protocollayouts::wire::MainProtocolTwoWayLocalWithErrorResult>
    : public std::true_type {};
template <>
struct IsUnion<
    ::test_protocollayouts::wire::MainProtocolTwoWayLocalWithErrorResult>
    : public std::true_type {};
static_assert(
    std::is_standard_layout_v<
        ::test_protocollayouts::wire::MainProtocolTwoWayLocalWithErrorResult>);

template <>
struct TypeTraits<
    ::test_protocollayouts::wire::MainProtocolOnLocalWithErrorResult> {
  static constexpr const fidl_type_t* kType =
      &::test_protocollayouts::wire::
          test_protocollayouts_MainProtocol_OnLocalWithError_ResultTable;
  static constexpr uint32_t kMaxNumHandles = 0;
  static constexpr uint32_t kPrimarySize = 16;
  static constexpr uint32_t kPrimarySizeV1 = 24;
  [[maybe_unused]] static constexpr uint32_t kMaxOutOfLine = 24;
  static constexpr uint32_t kMaxOutOfLineV1 = 40;
  static constexpr bool kHasPointer = true;
};

template <>
struct IsFidlType<
    ::test_protocollayouts::wire::MainProtocolOnLocalWithErrorResult>
    : public std::true_type {};
template <>
struct IsUnion<::test_protocollayouts::wire::MainProtocolOnLocalWithErrorResult>
    : public std::true_type {};
static_assert(
    std::is_standard_layout_v<
        ::test_protocollayouts::wire::MainProtocolOnLocalWithErrorResult>);

}  // namespace fidl
