// WARNING: This file is machine generated by fidlgen.
  
  // fidl_experiment = output_index_json

  #pragma once

  #include <cinttypes>

  #include <lib/fidl/cpp/wire/internal/framework_err.h>
  #include <lib/fidl/cpp/wire/array.h>
  #include <lib/fidl/cpp/wire/envelope.h>
  #include <lib/fidl/cpp/wire/message_storage.h>
  #include <lib/fidl/cpp/wire/message.h>
  #include <lib/fidl/cpp/wire/object_view.h>
  #include <lib/fidl/cpp/wire/string_view.h>
  #include <lib/fidl/cpp/wire/traits.h>
  #include <lib/fidl/cpp/wire/wire_types.h>
  #include <lib/stdcompat/optional.h>
#ifdef __Fuchsia__
#include <lib/zx/channel.h>
    

#endif  // __Fuchsia__


  #include <fidl/test.protocollayoutssamelibrary/cpp/markers.h>
  #include <fidl/test.protocollayoutssamelibrary/cpp/common_types.h>
  

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

  namespace test_protocollayoutssamelibrary {


  
  
  
  
namespace wire {

class TablePayload;


class ComposedProtocolOneWayAnonComposedRequest;


class ComposedProtocolTwoWayAnonComposedResponse;


class ComposedProtocolTwoWayAnonComposedWithErrorRequest;


class MainProtocolOneWayAnonRequest;


class MainProtocolTwoWayAnonResponse;


class MainProtocolTwoWayAnonWithErrorRequest;
  


class UnionPayload;


class ComposedProtocolTwoWayAnonComposedRequest;


class ComposedProtocolTwoWayAnonComposedWithErrorResponse;


class ComposedProtocolTwoWayAnonComposedWithErrorResult;


class ComposedProtocolOnAnonComposedRequest;


class ComposedProtocolTwoWayNamedComposedWithErrorResult;


class MainProtocolTwoWayLocalWithErrorResult;


class MainProtocolTwoWayAnonRequest;


class MainProtocolTwoWayAnonWithErrorResponse;


class MainProtocolTwoWayAnonWithErrorResult;


class MainProtocolOnAnonRequest;

  
  


}  // namespace wire
}  // namespace test_protocollayoutssamelibrary

template<>
class ::fidl::WireTableBuilder<::test_protocollayoutssamelibrary::wire::TablePayload>;
template<>
class ::fidl::WireTableExternalBuilder<::test_protocollayoutssamelibrary::wire::TablePayload>;

template <>
struct ::fidl::WireTableFrame<::test_protocollayoutssamelibrary::wire::TablePayload> 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;
  uint64_t ComputeMaxOrdinal() const;
  ::fidl::Envelope<uint16_t> a_;

  friend class ::test_protocollayoutssamelibrary::wire::TablePayload;
  friend ::fidl::internal::WireTableBaseBuilder<::test_protocollayoutssamelibrary::wire::TablePayload, ::fidl::WireTableBuilder<::test_protocollayoutssamelibrary::wire::TablePayload>>;
  friend ::fidl::internal::WireTableBaseBuilder<::test_protocollayoutssamelibrary::wire::TablePayload, ::fidl::WireTableExternalBuilder<::test_protocollayoutssamelibrary::wire::TablePayload>>;
};

namespace test_protocollayoutssamelibrary {
namespace wire {


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

  ~TablePayload() = 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_protocollayoutssamelibrary::wire::TablePayload> Builder(::fidl::AnyArena& arena);

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

  [[ nodiscard ]] uint16_t& a() const {
    ZX_ASSERT(has_a());
    return frame_ptr_->a_.get_data();
  }
  [[ nodiscard ]] 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

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

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

  explicit TablePayload(::fidl::AnyArena& allocator)
      : frame_ptr_(::fidl::ObjectView<::fidl::WireTableFrame<::test_protocollayoutssamelibrary::wire::TablePayload>>(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 TablePayload(::fidl::ObjectView<::fidl::WireTableFrame<::test_protocollayoutssamelibrary::wire::TablePayload>>&& frame)
      : frame_ptr_(std::move(frame)) {}

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

 private:
  friend ::fidl::internal::WireTableBaseBuilder<::test_protocollayoutssamelibrary::wire::TablePayload, ::fidl::WireTableBuilder<::test_protocollayoutssamelibrary::wire::TablePayload>>;
  friend ::fidl::internal::WireTableBaseBuilder<::test_protocollayoutssamelibrary::wire::TablePayload, ::fidl::WireTableExternalBuilder<::test_protocollayoutssamelibrary::wire::TablePayload>>;

  uint64_t max_ordinal_ = 0;
  ::fidl::ObjectView<::fidl::WireTableFrame<::test_protocollayoutssamelibrary::wire::TablePayload>> frame_ptr_;
};}  // namespace wire
}  // namespace test_protocollayoutssamelibrary

template<typename BuilderImpl>
class ::fidl::internal::WireTableBaseBuilder<::test_protocollayoutssamelibrary::wire::TablePayload, BuilderImpl> {
 protected:
  // |Wrapper_Ignore_Me_| wraps a |fidl::ObjectView<T>| and reduces its
  // priority in overload resolution. When the user writes `{}` as the
  // setter argument, that would default construct the field instead of
  // constructing a NULL object view.
  template <typename U>
  struct Wrapper_Ignore_Me_ {
    Wrapper_Ignore_Me_(U v) : value(v) {}
    U value;
  };

 public:
  // Build and return the table. The builder should not be used after this.
  ::test_protocollayoutssamelibrary::wire::TablePayload Build() {
    ZX_DEBUG_ASSERT(table_.frame_ptr_ != nullptr);
    ::test_protocollayoutssamelibrary::wire::TablePayload t = std::move(table_);
    // Poison this builder to prevent accidental reuse.
    table_.frame_ptr_ = nullptr;
    return t;
  }
    [[ nodiscard ]] bool has_a() const {
      return table_.has_a();
    }

    // Clears the a field.
    //
    // This method should be used sparingly, such as only during tests, as it has
    // O(number_of_fields) complexity.
    void clear_a() {
      table_.clear_a();
    }

    // Getter for a.
    //
    
    [[ nodiscard ]] uint16_t& a() const {
      return table_.a();
    }

    // Setter for a.
    //
    
      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_protocollayoutssamelibrary::wire::TablePayload>>&& frame)
    : table_(std::move(frame)) {}

 private:
  ::test_protocollayoutssamelibrary::wire::TablePayload table_;
};

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

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

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

};

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

 private:
  friend class ::test_protocollayoutssamelibrary::wire::TablePayload;
  using Base::Base;
  WireTableExternalBuilder(::fidl::WireTableFrame<::test_protocollayoutssamelibrary::wire::TablePayload>* frame)
      : Base(::fidl::ObjectView<::fidl::WireTableFrame<::test_protocollayoutssamelibrary::wire::TablePayload>>::FromExternal(frame)) {}
};namespace test_protocollayoutssamelibrary {
namespace wire {

inline ::fidl::WireTableBuilder<::test_protocollayoutssamelibrary::wire::TablePayload> TablePayload::Builder(::fidl::AnyArena& arena) {
  return ::fidl::WireTableBuilder<::test_protocollayoutssamelibrary::wire::TablePayload>(arena);
}
inline ::fidl::WireTableExternalBuilder<::test_protocollayoutssamelibrary::wire::TablePayload> TablePayload::ExternalBuilder(::fidl::ObjectView<::fidl::WireTableFrame<::test_protocollayoutssamelibrary::wire::TablePayload>> frame) {
  return ::fidl::WireTableExternalBuilder<::test_protocollayoutssamelibrary::wire::TablePayload>(std::move(frame));
}


}  // namespace wire
}  // namespace test_protocollayoutssamelibrary

template<>
class ::fidl::WireTableBuilder<::test_protocollayoutssamelibrary::wire::ComposedProtocolOneWayAnonComposedRequest>;
template<>
class ::fidl::WireTableExternalBuilder<::test_protocollayoutssamelibrary::wire::ComposedProtocolOneWayAnonComposedRequest>;

template <>
struct ::fidl::WireTableFrame<::test_protocollayoutssamelibrary::wire::ComposedProtocolOneWayAnonComposedRequest> 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;
  uint64_t ComputeMaxOrdinal() const;
  ::fidl::Envelope<uint16_t> a_;

  friend class ::test_protocollayoutssamelibrary::wire::ComposedProtocolOneWayAnonComposedRequest;
  friend ::fidl::internal::WireTableBaseBuilder<::test_protocollayoutssamelibrary::wire::ComposedProtocolOneWayAnonComposedRequest, ::fidl::WireTableBuilder<::test_protocollayoutssamelibrary::wire::ComposedProtocolOneWayAnonComposedRequest>>;
  friend ::fidl::internal::WireTableBaseBuilder<::test_protocollayoutssamelibrary::wire::ComposedProtocolOneWayAnonComposedRequest, ::fidl::WireTableExternalBuilder<::test_protocollayoutssamelibrary::wire::ComposedProtocolOneWayAnonComposedRequest>>;
};

namespace test_protocollayoutssamelibrary {
namespace wire {


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

  ~ComposedProtocolOneWayAnonComposedRequest() = 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_protocollayoutssamelibrary::wire::ComposedProtocolOneWayAnonComposedRequest> Builder(::fidl::AnyArena& arena);

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

  [[ nodiscard ]] uint16_t& a() const {
    ZX_ASSERT(has_a());
    return frame_ptr_->a_.get_data();
  }
  [[ nodiscard ]] 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

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

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

  explicit ComposedProtocolOneWayAnonComposedRequest(::fidl::AnyArena& allocator)
      : frame_ptr_(::fidl::ObjectView<::fidl::WireTableFrame<::test_protocollayoutssamelibrary::wire::ComposedProtocolOneWayAnonComposedRequest>>(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 ComposedProtocolOneWayAnonComposedRequest(::fidl::ObjectView<::fidl::WireTableFrame<::test_protocollayoutssamelibrary::wire::ComposedProtocolOneWayAnonComposedRequest>>&& frame)
      : frame_ptr_(std::move(frame)) {}

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

 private:
  friend ::fidl::internal::WireTableBaseBuilder<::test_protocollayoutssamelibrary::wire::ComposedProtocolOneWayAnonComposedRequest, ::fidl::WireTableBuilder<::test_protocollayoutssamelibrary::wire::ComposedProtocolOneWayAnonComposedRequest>>;
  friend ::fidl::internal::WireTableBaseBuilder<::test_protocollayoutssamelibrary::wire::ComposedProtocolOneWayAnonComposedRequest, ::fidl::WireTableExternalBuilder<::test_protocollayoutssamelibrary::wire::ComposedProtocolOneWayAnonComposedRequest>>;

  uint64_t max_ordinal_ = 0;
  ::fidl::ObjectView<::fidl::WireTableFrame<::test_protocollayoutssamelibrary::wire::ComposedProtocolOneWayAnonComposedRequest>> frame_ptr_;
};}  // namespace wire
}  // namespace test_protocollayoutssamelibrary

template<typename BuilderImpl>
class ::fidl::internal::WireTableBaseBuilder<::test_protocollayoutssamelibrary::wire::ComposedProtocolOneWayAnonComposedRequest, BuilderImpl> {
 protected:
  // |Wrapper_Ignore_Me_| wraps a |fidl::ObjectView<T>| and reduces its
  // priority in overload resolution. When the user writes `{}` as the
  // setter argument, that would default construct the field instead of
  // constructing a NULL object view.
  template <typename U>
  struct Wrapper_Ignore_Me_ {
    Wrapper_Ignore_Me_(U v) : value(v) {}
    U value;
  };

 public:
  // Build and return the table. The builder should not be used after this.
  ::test_protocollayoutssamelibrary::wire::ComposedProtocolOneWayAnonComposedRequest Build() {
    ZX_DEBUG_ASSERT(table_.frame_ptr_ != nullptr);
    ::test_protocollayoutssamelibrary::wire::ComposedProtocolOneWayAnonComposedRequest t = std::move(table_);
    // Poison this builder to prevent accidental reuse.
    table_.frame_ptr_ = nullptr;
    return t;
  }
    [[ nodiscard ]] bool has_a() const {
      return table_.has_a();
    }

    // Clears the a field.
    //
    // This method should be used sparingly, such as only during tests, as it has
    // O(number_of_fields) complexity.
    void clear_a() {
      table_.clear_a();
    }

    // Getter for a.
    //
    
    [[ nodiscard ]] uint16_t& a() const {
      return table_.a();
    }

    // Setter for a.
    //
    
      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_protocollayoutssamelibrary::wire::ComposedProtocolOneWayAnonComposedRequest>>&& frame)
    : table_(std::move(frame)) {}

 private:
  ::test_protocollayoutssamelibrary::wire::ComposedProtocolOneWayAnonComposedRequest table_;
};

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

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

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

};

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

 private:
  friend class ::test_protocollayoutssamelibrary::wire::ComposedProtocolOneWayAnonComposedRequest;
  using Base::Base;
  WireTableExternalBuilder(::fidl::WireTableFrame<::test_protocollayoutssamelibrary::wire::ComposedProtocolOneWayAnonComposedRequest>* frame)
      : Base(::fidl::ObjectView<::fidl::WireTableFrame<::test_protocollayoutssamelibrary::wire::ComposedProtocolOneWayAnonComposedRequest>>::FromExternal(frame)) {}
};namespace test_protocollayoutssamelibrary {
namespace wire {

inline ::fidl::WireTableBuilder<::test_protocollayoutssamelibrary::wire::ComposedProtocolOneWayAnonComposedRequest> ComposedProtocolOneWayAnonComposedRequest::Builder(::fidl::AnyArena& arena) {
  return ::fidl::WireTableBuilder<::test_protocollayoutssamelibrary::wire::ComposedProtocolOneWayAnonComposedRequest>(arena);
}
inline ::fidl::WireTableExternalBuilder<::test_protocollayoutssamelibrary::wire::ComposedProtocolOneWayAnonComposedRequest> ComposedProtocolOneWayAnonComposedRequest::ExternalBuilder(::fidl::ObjectView<::fidl::WireTableFrame<::test_protocollayoutssamelibrary::wire::ComposedProtocolOneWayAnonComposedRequest>> frame) {
  return ::fidl::WireTableExternalBuilder<::test_protocollayoutssamelibrary::wire::ComposedProtocolOneWayAnonComposedRequest>(std::move(frame));
}


}  // namespace wire
}  // namespace test_protocollayoutssamelibrary

template<>
class ::fidl::WireTableBuilder<::test_protocollayoutssamelibrary::wire::ComposedProtocolTwoWayAnonComposedResponse>;
template<>
class ::fidl::WireTableExternalBuilder<::test_protocollayoutssamelibrary::wire::ComposedProtocolTwoWayAnonComposedResponse>;

template <>
struct ::fidl::WireTableFrame<::test_protocollayoutssamelibrary::wire::ComposedProtocolTwoWayAnonComposedResponse> 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;
  uint64_t ComputeMaxOrdinal() const;
  ::fidl::Envelope<uint16_t> a_;

  friend class ::test_protocollayoutssamelibrary::wire::ComposedProtocolTwoWayAnonComposedResponse;
  friend ::fidl::internal::WireTableBaseBuilder<::test_protocollayoutssamelibrary::wire::ComposedProtocolTwoWayAnonComposedResponse, ::fidl::WireTableBuilder<::test_protocollayoutssamelibrary::wire::ComposedProtocolTwoWayAnonComposedResponse>>;
  friend ::fidl::internal::WireTableBaseBuilder<::test_protocollayoutssamelibrary::wire::ComposedProtocolTwoWayAnonComposedResponse, ::fidl::WireTableExternalBuilder<::test_protocollayoutssamelibrary::wire::ComposedProtocolTwoWayAnonComposedResponse>>;
};

namespace test_protocollayoutssamelibrary {
namespace wire {


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

  ~ComposedProtocolTwoWayAnonComposedResponse() = 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_protocollayoutssamelibrary::wire::ComposedProtocolTwoWayAnonComposedResponse> Builder(::fidl::AnyArena& arena);

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

  [[ nodiscard ]] uint16_t& a() const {
    ZX_ASSERT(has_a());
    return frame_ptr_->a_.get_data();
  }
  [[ nodiscard ]] 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

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

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

  explicit ComposedProtocolTwoWayAnonComposedResponse(::fidl::AnyArena& allocator)
      : frame_ptr_(::fidl::ObjectView<::fidl::WireTableFrame<::test_protocollayoutssamelibrary::wire::ComposedProtocolTwoWayAnonComposedResponse>>(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 ComposedProtocolTwoWayAnonComposedResponse(::fidl::ObjectView<::fidl::WireTableFrame<::test_protocollayoutssamelibrary::wire::ComposedProtocolTwoWayAnonComposedResponse>>&& frame)
      : frame_ptr_(std::move(frame)) {}

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

 private:
  friend ::fidl::internal::WireTableBaseBuilder<::test_protocollayoutssamelibrary::wire::ComposedProtocolTwoWayAnonComposedResponse, ::fidl::WireTableBuilder<::test_protocollayoutssamelibrary::wire::ComposedProtocolTwoWayAnonComposedResponse>>;
  friend ::fidl::internal::WireTableBaseBuilder<::test_protocollayoutssamelibrary::wire::ComposedProtocolTwoWayAnonComposedResponse, ::fidl::WireTableExternalBuilder<::test_protocollayoutssamelibrary::wire::ComposedProtocolTwoWayAnonComposedResponse>>;

  uint64_t max_ordinal_ = 0;
  ::fidl::ObjectView<::fidl::WireTableFrame<::test_protocollayoutssamelibrary::wire::ComposedProtocolTwoWayAnonComposedResponse>> frame_ptr_;
};}  // namespace wire
}  // namespace test_protocollayoutssamelibrary

template<typename BuilderImpl>
class ::fidl::internal::WireTableBaseBuilder<::test_protocollayoutssamelibrary::wire::ComposedProtocolTwoWayAnonComposedResponse, BuilderImpl> {
 protected:
  // |Wrapper_Ignore_Me_| wraps a |fidl::ObjectView<T>| and reduces its
  // priority in overload resolution. When the user writes `{}` as the
  // setter argument, that would default construct the field instead of
  // constructing a NULL object view.
  template <typename U>
  struct Wrapper_Ignore_Me_ {
    Wrapper_Ignore_Me_(U v) : value(v) {}
    U value;
  };

 public:
  // Build and return the table. The builder should not be used after this.
  ::test_protocollayoutssamelibrary::wire::ComposedProtocolTwoWayAnonComposedResponse Build() {
    ZX_DEBUG_ASSERT(table_.frame_ptr_ != nullptr);
    ::test_protocollayoutssamelibrary::wire::ComposedProtocolTwoWayAnonComposedResponse t = std::move(table_);
    // Poison this builder to prevent accidental reuse.
    table_.frame_ptr_ = nullptr;
    return t;
  }
    [[ nodiscard ]] bool has_a() const {
      return table_.has_a();
    }

    // Clears the a field.
    //
    // This method should be used sparingly, such as only during tests, as it has
    // O(number_of_fields) complexity.
    void clear_a() {
      table_.clear_a();
    }

    // Getter for a.
    //
    
    [[ nodiscard ]] uint16_t& a() const {
      return table_.a();
    }

    // Setter for a.
    //
    
      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_protocollayoutssamelibrary::wire::ComposedProtocolTwoWayAnonComposedResponse>>&& frame)
    : table_(std::move(frame)) {}

 private:
  ::test_protocollayoutssamelibrary::wire::ComposedProtocolTwoWayAnonComposedResponse table_;
};

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

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

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

};

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

 private:
  friend class ::test_protocollayoutssamelibrary::wire::ComposedProtocolTwoWayAnonComposedResponse;
  using Base::Base;
  WireTableExternalBuilder(::fidl::WireTableFrame<::test_protocollayoutssamelibrary::wire::ComposedProtocolTwoWayAnonComposedResponse>* frame)
      : Base(::fidl::ObjectView<::fidl::WireTableFrame<::test_protocollayoutssamelibrary::wire::ComposedProtocolTwoWayAnonComposedResponse>>::FromExternal(frame)) {}
};namespace test_protocollayoutssamelibrary {
namespace wire {

inline ::fidl::WireTableBuilder<::test_protocollayoutssamelibrary::wire::ComposedProtocolTwoWayAnonComposedResponse> ComposedProtocolTwoWayAnonComposedResponse::Builder(::fidl::AnyArena& arena) {
  return ::fidl::WireTableBuilder<::test_protocollayoutssamelibrary::wire::ComposedProtocolTwoWayAnonComposedResponse>(arena);
}
inline ::fidl::WireTableExternalBuilder<::test_protocollayoutssamelibrary::wire::ComposedProtocolTwoWayAnonComposedResponse> ComposedProtocolTwoWayAnonComposedResponse::ExternalBuilder(::fidl::ObjectView<::fidl::WireTableFrame<::test_protocollayoutssamelibrary::wire::ComposedProtocolTwoWayAnonComposedResponse>> frame) {
  return ::fidl::WireTableExternalBuilder<::test_protocollayoutssamelibrary::wire::ComposedProtocolTwoWayAnonComposedResponse>(std::move(frame));
}


}  // namespace wire
}  // namespace test_protocollayoutssamelibrary

template<>
class ::fidl::WireTableBuilder<::test_protocollayoutssamelibrary::wire::ComposedProtocolTwoWayAnonComposedWithErrorRequest>;
template<>
class ::fidl::WireTableExternalBuilder<::test_protocollayoutssamelibrary::wire::ComposedProtocolTwoWayAnonComposedWithErrorRequest>;

template <>
struct ::fidl::WireTableFrame<::test_protocollayoutssamelibrary::wire::ComposedProtocolTwoWayAnonComposedWithErrorRequest> 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;
  uint64_t ComputeMaxOrdinal() const;
  ::fidl::Envelope<uint16_t> a_;

  friend class ::test_protocollayoutssamelibrary::wire::ComposedProtocolTwoWayAnonComposedWithErrorRequest;
  friend ::fidl::internal::WireTableBaseBuilder<::test_protocollayoutssamelibrary::wire::ComposedProtocolTwoWayAnonComposedWithErrorRequest, ::fidl::WireTableBuilder<::test_protocollayoutssamelibrary::wire::ComposedProtocolTwoWayAnonComposedWithErrorRequest>>;
  friend ::fidl::internal::WireTableBaseBuilder<::test_protocollayoutssamelibrary::wire::ComposedProtocolTwoWayAnonComposedWithErrorRequest, ::fidl::WireTableExternalBuilder<::test_protocollayoutssamelibrary::wire::ComposedProtocolTwoWayAnonComposedWithErrorRequest>>;
};

namespace test_protocollayoutssamelibrary {
namespace wire {


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

  ~ComposedProtocolTwoWayAnonComposedWithErrorRequest() = 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_protocollayoutssamelibrary::wire::ComposedProtocolTwoWayAnonComposedWithErrorRequest> Builder(::fidl::AnyArena& arena);

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

  [[ nodiscard ]] uint16_t& a() const {
    ZX_ASSERT(has_a());
    return frame_ptr_->a_.get_data();
  }
  [[ nodiscard ]] 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

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

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

  explicit ComposedProtocolTwoWayAnonComposedWithErrorRequest(::fidl::AnyArena& allocator)
      : frame_ptr_(::fidl::ObjectView<::fidl::WireTableFrame<::test_protocollayoutssamelibrary::wire::ComposedProtocolTwoWayAnonComposedWithErrorRequest>>(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 ComposedProtocolTwoWayAnonComposedWithErrorRequest(::fidl::ObjectView<::fidl::WireTableFrame<::test_protocollayoutssamelibrary::wire::ComposedProtocolTwoWayAnonComposedWithErrorRequest>>&& frame)
      : frame_ptr_(std::move(frame)) {}

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

 private:
  friend ::fidl::internal::WireTableBaseBuilder<::test_protocollayoutssamelibrary::wire::ComposedProtocolTwoWayAnonComposedWithErrorRequest, ::fidl::WireTableBuilder<::test_protocollayoutssamelibrary::wire::ComposedProtocolTwoWayAnonComposedWithErrorRequest>>;
  friend ::fidl::internal::WireTableBaseBuilder<::test_protocollayoutssamelibrary::wire::ComposedProtocolTwoWayAnonComposedWithErrorRequest, ::fidl::WireTableExternalBuilder<::test_protocollayoutssamelibrary::wire::ComposedProtocolTwoWayAnonComposedWithErrorRequest>>;

  uint64_t max_ordinal_ = 0;
  ::fidl::ObjectView<::fidl::WireTableFrame<::test_protocollayoutssamelibrary::wire::ComposedProtocolTwoWayAnonComposedWithErrorRequest>> frame_ptr_;
};}  // namespace wire
}  // namespace test_protocollayoutssamelibrary

template<typename BuilderImpl>
class ::fidl::internal::WireTableBaseBuilder<::test_protocollayoutssamelibrary::wire::ComposedProtocolTwoWayAnonComposedWithErrorRequest, BuilderImpl> {
 protected:
  // |Wrapper_Ignore_Me_| wraps a |fidl::ObjectView<T>| and reduces its
  // priority in overload resolution. When the user writes `{}` as the
  // setter argument, that would default construct the field instead of
  // constructing a NULL object view.
  template <typename U>
  struct Wrapper_Ignore_Me_ {
    Wrapper_Ignore_Me_(U v) : value(v) {}
    U value;
  };

 public:
  // Build and return the table. The builder should not be used after this.
  ::test_protocollayoutssamelibrary::wire::ComposedProtocolTwoWayAnonComposedWithErrorRequest Build() {
    ZX_DEBUG_ASSERT(table_.frame_ptr_ != nullptr);
    ::test_protocollayoutssamelibrary::wire::ComposedProtocolTwoWayAnonComposedWithErrorRequest t = std::move(table_);
    // Poison this builder to prevent accidental reuse.
    table_.frame_ptr_ = nullptr;
    return t;
  }
    [[ nodiscard ]] bool has_a() const {
      return table_.has_a();
    }

    // Clears the a field.
    //
    // This method should be used sparingly, such as only during tests, as it has
    // O(number_of_fields) complexity.
    void clear_a() {
      table_.clear_a();
    }

    // Getter for a.
    //
    
    [[ nodiscard ]] uint16_t& a() const {
      return table_.a();
    }

    // Setter for a.
    //
    
      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_protocollayoutssamelibrary::wire::ComposedProtocolTwoWayAnonComposedWithErrorRequest>>&& frame)
    : table_(std::move(frame)) {}

 private:
  ::test_protocollayoutssamelibrary::wire::ComposedProtocolTwoWayAnonComposedWithErrorRequest table_;
};

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

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

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

};

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

 private:
  friend class ::test_protocollayoutssamelibrary::wire::ComposedProtocolTwoWayAnonComposedWithErrorRequest;
  using Base::Base;
  WireTableExternalBuilder(::fidl::WireTableFrame<::test_protocollayoutssamelibrary::wire::ComposedProtocolTwoWayAnonComposedWithErrorRequest>* frame)
      : Base(::fidl::ObjectView<::fidl::WireTableFrame<::test_protocollayoutssamelibrary::wire::ComposedProtocolTwoWayAnonComposedWithErrorRequest>>::FromExternal(frame)) {}
};namespace test_protocollayoutssamelibrary {
namespace wire {

inline ::fidl::WireTableBuilder<::test_protocollayoutssamelibrary::wire::ComposedProtocolTwoWayAnonComposedWithErrorRequest> ComposedProtocolTwoWayAnonComposedWithErrorRequest::Builder(::fidl::AnyArena& arena) {
  return ::fidl::WireTableBuilder<::test_protocollayoutssamelibrary::wire::ComposedProtocolTwoWayAnonComposedWithErrorRequest>(arena);
}
inline ::fidl::WireTableExternalBuilder<::test_protocollayoutssamelibrary::wire::ComposedProtocolTwoWayAnonComposedWithErrorRequest> ComposedProtocolTwoWayAnonComposedWithErrorRequest::ExternalBuilder(::fidl::ObjectView<::fidl::WireTableFrame<::test_protocollayoutssamelibrary::wire::ComposedProtocolTwoWayAnonComposedWithErrorRequest>> frame) {
  return ::fidl::WireTableExternalBuilder<::test_protocollayoutssamelibrary::wire::ComposedProtocolTwoWayAnonComposedWithErrorRequest>(std::move(frame));
}


}  // namespace wire
}  // namespace test_protocollayoutssamelibrary

template<>
class ::fidl::WireTableBuilder<::test_protocollayoutssamelibrary::wire::MainProtocolOneWayAnonRequest>;
template<>
class ::fidl::WireTableExternalBuilder<::test_protocollayoutssamelibrary::wire::MainProtocolOneWayAnonRequest>;

template <>
struct ::fidl::WireTableFrame<::test_protocollayoutssamelibrary::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;
  uint64_t ComputeMaxOrdinal() const;
  ::fidl::Envelope<uint16_t> a_;

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

namespace test_protocollayoutssamelibrary {
namespace wire {


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_protocollayoutssamelibrary::wire::MainProtocolOneWayAnonRequest> Builder(::fidl::AnyArena& arena);

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

  [[ nodiscard ]] uint16_t& a() const {
    ZX_ASSERT(has_a());
    return frame_ptr_->a_.get_data();
  }
  [[ nodiscard ]] 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();
    max_ordinal_ = frame_ptr_->ComputeMaxOrdinal();
    return *this;
  }

  explicit MainProtocolOneWayAnonRequest(::fidl::AnyArena& allocator)
      : frame_ptr_(::fidl::ObjectView<::fidl::WireTableFrame<::test_protocollayoutssamelibrary::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_protocollayoutssamelibrary::wire::MainProtocolOneWayAnonRequest>>&& frame)
      : frame_ptr_(std::move(frame)) {}

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

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

  uint64_t max_ordinal_ = 0;
  ::fidl::ObjectView<::fidl::WireTableFrame<::test_protocollayoutssamelibrary::wire::MainProtocolOneWayAnonRequest>> frame_ptr_;
};}  // namespace wire
}  // namespace test_protocollayoutssamelibrary

template<typename BuilderImpl>
class ::fidl::internal::WireTableBaseBuilder<::test_protocollayoutssamelibrary::wire::MainProtocolOneWayAnonRequest, BuilderImpl> {
 protected:
  // |Wrapper_Ignore_Me_| wraps a |fidl::ObjectView<T>| and reduces its
  // priority in overload resolution. When the user writes `{}` as the
  // setter argument, that would default construct the field instead of
  // constructing a NULL object view.
  template <typename U>
  struct Wrapper_Ignore_Me_ {
    Wrapper_Ignore_Me_(U v) : value(v) {}
    U value;
  };

 public:
  // Build and return the table. The builder should not be used after this.
  ::test_protocollayoutssamelibrary::wire::MainProtocolOneWayAnonRequest Build() {
    ZX_DEBUG_ASSERT(table_.frame_ptr_ != nullptr);
    ::test_protocollayoutssamelibrary::wire::MainProtocolOneWayAnonRequest t = std::move(table_);
    // Poison this builder to prevent accidental reuse.
    table_.frame_ptr_ = nullptr;
    return t;
  }
    [[ nodiscard ]] bool has_a() const {
      return table_.has_a();
    }

    // Clears the a field.
    //
    // This method should be used sparingly, such as only during tests, as it has
    // O(number_of_fields) complexity.
    void clear_a() {
      table_.clear_a();
    }

    // Getter for a.
    //
    
    [[ nodiscard ]] uint16_t& a() const {
      return table_.a();
    }

    // Setter for a.
    //
    
      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_protocollayoutssamelibrary::wire::MainProtocolOneWayAnonRequest>>&& frame)
    : table_(std::move(frame)) {}

 private:
  ::test_protocollayoutssamelibrary::wire::MainProtocolOneWayAnonRequest table_;
};

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

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

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

};

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

 private:
  friend class ::test_protocollayoutssamelibrary::wire::MainProtocolOneWayAnonRequest;
  using Base::Base;
  WireTableExternalBuilder(::fidl::WireTableFrame<::test_protocollayoutssamelibrary::wire::MainProtocolOneWayAnonRequest>* frame)
      : Base(::fidl::ObjectView<::fidl::WireTableFrame<::test_protocollayoutssamelibrary::wire::MainProtocolOneWayAnonRequest>>::FromExternal(frame)) {}
};namespace test_protocollayoutssamelibrary {
namespace wire {

inline ::fidl::WireTableBuilder<::test_protocollayoutssamelibrary::wire::MainProtocolOneWayAnonRequest> MainProtocolOneWayAnonRequest::Builder(::fidl::AnyArena& arena) {
  return ::fidl::WireTableBuilder<::test_protocollayoutssamelibrary::wire::MainProtocolOneWayAnonRequest>(arena);
}
inline ::fidl::WireTableExternalBuilder<::test_protocollayoutssamelibrary::wire::MainProtocolOneWayAnonRequest> MainProtocolOneWayAnonRequest::ExternalBuilder(::fidl::ObjectView<::fidl::WireTableFrame<::test_protocollayoutssamelibrary::wire::MainProtocolOneWayAnonRequest>> frame) {
  return ::fidl::WireTableExternalBuilder<::test_protocollayoutssamelibrary::wire::MainProtocolOneWayAnonRequest>(std::move(frame));
}


}  // namespace wire
}  // namespace test_protocollayoutssamelibrary

template<>
class ::fidl::WireTableBuilder<::test_protocollayoutssamelibrary::wire::MainProtocolTwoWayAnonResponse>;
template<>
class ::fidl::WireTableExternalBuilder<::test_protocollayoutssamelibrary::wire::MainProtocolTwoWayAnonResponse>;

template <>
struct ::fidl::WireTableFrame<::test_protocollayoutssamelibrary::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;
  uint64_t ComputeMaxOrdinal() const;
  ::fidl::Envelope<uint16_t> a_;

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

namespace test_protocollayoutssamelibrary {
namespace wire {


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_protocollayoutssamelibrary::wire::MainProtocolTwoWayAnonResponse> Builder(::fidl::AnyArena& arena);

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

  [[ nodiscard ]] uint16_t& a() const {
    ZX_ASSERT(has_a());
    return frame_ptr_->a_.get_data();
  }
  [[ nodiscard ]] 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();
    max_ordinal_ = frame_ptr_->ComputeMaxOrdinal();
    return *this;
  }

  explicit MainProtocolTwoWayAnonResponse(::fidl::AnyArena& allocator)
      : frame_ptr_(::fidl::ObjectView<::fidl::WireTableFrame<::test_protocollayoutssamelibrary::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_protocollayoutssamelibrary::wire::MainProtocolTwoWayAnonResponse>>&& frame)
      : frame_ptr_(std::move(frame)) {}

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

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

  uint64_t max_ordinal_ = 0;
  ::fidl::ObjectView<::fidl::WireTableFrame<::test_protocollayoutssamelibrary::wire::MainProtocolTwoWayAnonResponse>> frame_ptr_;
};}  // namespace wire
}  // namespace test_protocollayoutssamelibrary

template<typename BuilderImpl>
class ::fidl::internal::WireTableBaseBuilder<::test_protocollayoutssamelibrary::wire::MainProtocolTwoWayAnonResponse, BuilderImpl> {
 protected:
  // |Wrapper_Ignore_Me_| wraps a |fidl::ObjectView<T>| and reduces its
  // priority in overload resolution. When the user writes `{}` as the
  // setter argument, that would default construct the field instead of
  // constructing a NULL object view.
  template <typename U>
  struct Wrapper_Ignore_Me_ {
    Wrapper_Ignore_Me_(U v) : value(v) {}
    U value;
  };

 public:
  // Build and return the table. The builder should not be used after this.
  ::test_protocollayoutssamelibrary::wire::MainProtocolTwoWayAnonResponse Build() {
    ZX_DEBUG_ASSERT(table_.frame_ptr_ != nullptr);
    ::test_protocollayoutssamelibrary::wire::MainProtocolTwoWayAnonResponse t = std::move(table_);
    // Poison this builder to prevent accidental reuse.
    table_.frame_ptr_ = nullptr;
    return t;
  }
    [[ nodiscard ]] bool has_a() const {
      return table_.has_a();
    }

    // Clears the a field.
    //
    // This method should be used sparingly, such as only during tests, as it has
    // O(number_of_fields) complexity.
    void clear_a() {
      table_.clear_a();
    }

    // Getter for a.
    //
    
    [[ nodiscard ]] uint16_t& a() const {
      return table_.a();
    }

    // Setter for a.
    //
    
      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_protocollayoutssamelibrary::wire::MainProtocolTwoWayAnonResponse>>&& frame)
    : table_(std::move(frame)) {}

 private:
  ::test_protocollayoutssamelibrary::wire::MainProtocolTwoWayAnonResponse table_;
};

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

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

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

};

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

 private:
  friend class ::test_protocollayoutssamelibrary::wire::MainProtocolTwoWayAnonResponse;
  using Base::Base;
  WireTableExternalBuilder(::fidl::WireTableFrame<::test_protocollayoutssamelibrary::wire::MainProtocolTwoWayAnonResponse>* frame)
      : Base(::fidl::ObjectView<::fidl::WireTableFrame<::test_protocollayoutssamelibrary::wire::MainProtocolTwoWayAnonResponse>>::FromExternal(frame)) {}
};namespace test_protocollayoutssamelibrary {
namespace wire {

inline ::fidl::WireTableBuilder<::test_protocollayoutssamelibrary::wire::MainProtocolTwoWayAnonResponse> MainProtocolTwoWayAnonResponse::Builder(::fidl::AnyArena& arena) {
  return ::fidl::WireTableBuilder<::test_protocollayoutssamelibrary::wire::MainProtocolTwoWayAnonResponse>(arena);
}
inline ::fidl::WireTableExternalBuilder<::test_protocollayoutssamelibrary::wire::MainProtocolTwoWayAnonResponse> MainProtocolTwoWayAnonResponse::ExternalBuilder(::fidl::ObjectView<::fidl::WireTableFrame<::test_protocollayoutssamelibrary::wire::MainProtocolTwoWayAnonResponse>> frame) {
  return ::fidl::WireTableExternalBuilder<::test_protocollayoutssamelibrary::wire::MainProtocolTwoWayAnonResponse>(std::move(frame));
}


}  // namespace wire
}  // namespace test_protocollayoutssamelibrary

template<>
class ::fidl::WireTableBuilder<::test_protocollayoutssamelibrary::wire::MainProtocolTwoWayAnonWithErrorRequest>;
template<>
class ::fidl::WireTableExternalBuilder<::test_protocollayoutssamelibrary::wire::MainProtocolTwoWayAnonWithErrorRequest>;

template <>
struct ::fidl::WireTableFrame<::test_protocollayoutssamelibrary::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;
  uint64_t ComputeMaxOrdinal() const;
  ::fidl::Envelope<uint16_t> a_;

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

namespace test_protocollayoutssamelibrary {
namespace wire {


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_protocollayoutssamelibrary::wire::MainProtocolTwoWayAnonWithErrorRequest> Builder(::fidl::AnyArena& arena);

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

  [[ nodiscard ]] uint16_t& a() const {
    ZX_ASSERT(has_a());
    return frame_ptr_->a_.get_data();
  }
  [[ nodiscard ]] 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();
    max_ordinal_ = frame_ptr_->ComputeMaxOrdinal();
    return *this;
  }

  explicit MainProtocolTwoWayAnonWithErrorRequest(::fidl::AnyArena& allocator)
      : frame_ptr_(::fidl::ObjectView<::fidl::WireTableFrame<::test_protocollayoutssamelibrary::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_protocollayoutssamelibrary::wire::MainProtocolTwoWayAnonWithErrorRequest>>&& frame)
      : frame_ptr_(std::move(frame)) {}

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

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

  uint64_t max_ordinal_ = 0;
  ::fidl::ObjectView<::fidl::WireTableFrame<::test_protocollayoutssamelibrary::wire::MainProtocolTwoWayAnonWithErrorRequest>> frame_ptr_;
};}  // namespace wire
}  // namespace test_protocollayoutssamelibrary

template<typename BuilderImpl>
class ::fidl::internal::WireTableBaseBuilder<::test_protocollayoutssamelibrary::wire::MainProtocolTwoWayAnonWithErrorRequest, BuilderImpl> {
 protected:
  // |Wrapper_Ignore_Me_| wraps a |fidl::ObjectView<T>| and reduces its
  // priority in overload resolution. When the user writes `{}` as the
  // setter argument, that would default construct the field instead of
  // constructing a NULL object view.
  template <typename U>
  struct Wrapper_Ignore_Me_ {
    Wrapper_Ignore_Me_(U v) : value(v) {}
    U value;
  };

 public:
  // Build and return the table. The builder should not be used after this.
  ::test_protocollayoutssamelibrary::wire::MainProtocolTwoWayAnonWithErrorRequest Build() {
    ZX_DEBUG_ASSERT(table_.frame_ptr_ != nullptr);
    ::test_protocollayoutssamelibrary::wire::MainProtocolTwoWayAnonWithErrorRequest t = std::move(table_);
    // Poison this builder to prevent accidental reuse.
    table_.frame_ptr_ = nullptr;
    return t;
  }
    [[ nodiscard ]] bool has_a() const {
      return table_.has_a();
    }

    // Clears the a field.
    //
    // This method should be used sparingly, such as only during tests, as it has
    // O(number_of_fields) complexity.
    void clear_a() {
      table_.clear_a();
    }

    // Getter for a.
    //
    
    [[ nodiscard ]] uint16_t& a() const {
      return table_.a();
    }

    // Setter for a.
    //
    
      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_protocollayoutssamelibrary::wire::MainProtocolTwoWayAnonWithErrorRequest>>&& frame)
    : table_(std::move(frame)) {}

 private:
  ::test_protocollayoutssamelibrary::wire::MainProtocolTwoWayAnonWithErrorRequest table_;
};

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

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

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

};

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

 private:
  friend class ::test_protocollayoutssamelibrary::wire::MainProtocolTwoWayAnonWithErrorRequest;
  using Base::Base;
  WireTableExternalBuilder(::fidl::WireTableFrame<::test_protocollayoutssamelibrary::wire::MainProtocolTwoWayAnonWithErrorRequest>* frame)
      : Base(::fidl::ObjectView<::fidl::WireTableFrame<::test_protocollayoutssamelibrary::wire::MainProtocolTwoWayAnonWithErrorRequest>>::FromExternal(frame)) {}
};namespace test_protocollayoutssamelibrary {
namespace wire {

inline ::fidl::WireTableBuilder<::test_protocollayoutssamelibrary::wire::MainProtocolTwoWayAnonWithErrorRequest> MainProtocolTwoWayAnonWithErrorRequest::Builder(::fidl::AnyArena& arena) {
  return ::fidl::WireTableBuilder<::test_protocollayoutssamelibrary::wire::MainProtocolTwoWayAnonWithErrorRequest>(arena);
}
inline ::fidl::WireTableExternalBuilder<::test_protocollayoutssamelibrary::wire::MainProtocolTwoWayAnonWithErrorRequest> MainProtocolTwoWayAnonWithErrorRequest::ExternalBuilder(::fidl::ObjectView<::fidl::WireTableFrame<::test_protocollayoutssamelibrary::wire::MainProtocolTwoWayAnonWithErrorRequest>> frame) {
  return ::fidl::WireTableExternalBuilder<::test_protocollayoutssamelibrary::wire::MainProtocolTwoWayAnonWithErrorRequest>(std::move(frame));
}
  




class UnionPayload {
  public:

  UnionPayload() : ordinal_(::test_protocollayoutssamelibrary::wire::UnionPayload::Ordinal::Invalid), envelope_{} {}

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

  enum class Tag : fidl_xunion_tag_t {
    kB = 1,  // 0x1
  };

  bool has_invalid_tag() const { return ordinal_ == ::test_protocollayoutssamelibrary::wire::UnionPayload::Ordinal::Invalid; }

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


  bool& b() {
    ZX_ASSERT(ordinal_ == ::test_protocollayoutssamelibrary::wire::UnionPayload::Ordinal::kB);
    return envelope_.As<bool>().get_data();
  }
  const bool& b() const {
    ZX_ASSERT(ordinal_ == ::test_protocollayoutssamelibrary::wire::UnionPayload::Ordinal::kB);
    return envelope_.As<bool>().get_data();
  }
  ::test_protocollayoutssamelibrary::wire::UnionPayload::Tag Which() const {
    ZX_ASSERT(!has_invalid_tag());
    return static_cast<::test_protocollayoutssamelibrary::wire::UnionPayload::Tag>(ordinal_);
  }

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

  static void SizeAndOffsetAssertionHelper();
  ::test_protocollayoutssamelibrary::wire::UnionPayload::Ordinal ordinal_;
  FIDL_ALIGNDECL
  ::fidl::UntypedEnvelope envelope_;
};




class ComposedProtocolTwoWayAnonComposedRequest {
  public:

  ComposedProtocolTwoWayAnonComposedRequest() : ordinal_(::test_protocollayoutssamelibrary::wire::ComposedProtocolTwoWayAnonComposedRequest::Ordinal::Invalid), envelope_{} {}

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

  enum class Tag : fidl_xunion_tag_t {
    kB = 1,  // 0x1
  };

  bool has_invalid_tag() const { return ordinal_ == ::test_protocollayoutssamelibrary::wire::ComposedProtocolTwoWayAnonComposedRequest::Ordinal::Invalid; }

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


  bool& b() {
    ZX_ASSERT(ordinal_ == ::test_protocollayoutssamelibrary::wire::ComposedProtocolTwoWayAnonComposedRequest::Ordinal::kB);
    return envelope_.As<bool>().get_data();
  }
  const bool& b() const {
    ZX_ASSERT(ordinal_ == ::test_protocollayoutssamelibrary::wire::ComposedProtocolTwoWayAnonComposedRequest::Ordinal::kB);
    return envelope_.As<bool>().get_data();
  }
  ::test_protocollayoutssamelibrary::wire::ComposedProtocolTwoWayAnonComposedRequest::Tag Which() const {
    ZX_ASSERT(!has_invalid_tag());
    return static_cast<::test_protocollayoutssamelibrary::wire::ComposedProtocolTwoWayAnonComposedRequest::Tag>(ordinal_);
  }

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

  static void SizeAndOffsetAssertionHelper();
  ::test_protocollayoutssamelibrary::wire::ComposedProtocolTwoWayAnonComposedRequest::Ordinal ordinal_;
  FIDL_ALIGNDECL
  ::fidl::UntypedEnvelope envelope_;
};




class ComposedProtocolTwoWayAnonComposedWithErrorResponse {
  public:

  ComposedProtocolTwoWayAnonComposedWithErrorResponse() : ordinal_(::test_protocollayoutssamelibrary::wire::ComposedProtocolTwoWayAnonComposedWithErrorResponse::Ordinal::Invalid), envelope_{} {}

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

  enum class Tag : fidl_xunion_tag_t {
    kB = 1,  // 0x1
  };

  bool has_invalid_tag() const { return ordinal_ == ::test_protocollayoutssamelibrary::wire::ComposedProtocolTwoWayAnonComposedWithErrorResponse::Ordinal::Invalid; }

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


  bool& b() {
    ZX_ASSERT(ordinal_ == ::test_protocollayoutssamelibrary::wire::ComposedProtocolTwoWayAnonComposedWithErrorResponse::Ordinal::kB);
    return envelope_.As<bool>().get_data();
  }
  const bool& b() const {
    ZX_ASSERT(ordinal_ == ::test_protocollayoutssamelibrary::wire::ComposedProtocolTwoWayAnonComposedWithErrorResponse::Ordinal::kB);
    return envelope_.As<bool>().get_data();
  }
  ::test_protocollayoutssamelibrary::wire::ComposedProtocolTwoWayAnonComposedWithErrorResponse::Tag Which() const {
    ZX_ASSERT(!has_invalid_tag());
    return static_cast<::test_protocollayoutssamelibrary::wire::ComposedProtocolTwoWayAnonComposedWithErrorResponse::Tag>(ordinal_);
  }

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

  static void SizeAndOffsetAssertionHelper();
  ::test_protocollayoutssamelibrary::wire::ComposedProtocolTwoWayAnonComposedWithErrorResponse::Ordinal ordinal_;
  FIDL_ALIGNDECL
  ::fidl::UntypedEnvelope envelope_;
};




class ComposedProtocolTwoWayAnonComposedWithErrorResult {
  public:
  using Response = test_protocollayoutssamelibrary::wire::ComposedProtocolTwoWayAnonComposedWithErrorResponse;

  ComposedProtocolTwoWayAnonComposedWithErrorResult() : ordinal_(::test_protocollayoutssamelibrary::wire::ComposedProtocolTwoWayAnonComposedWithErrorResult::Ordinal::Invalid), envelope_{} {}

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

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

  bool has_invalid_tag() const { return ordinal_ == ::test_protocollayoutssamelibrary::wire::ComposedProtocolTwoWayAnonComposedWithErrorResult::Ordinal::Invalid; }

  bool is_response() const { return ordinal_ == ::test_protocollayoutssamelibrary::wire::ComposedProtocolTwoWayAnonComposedWithErrorResult::Ordinal::kResponse; }
  
  static ComposedProtocolTwoWayAnonComposedWithErrorResult WithResponse(::fidl::ObjectView<::test_protocollayoutssamelibrary::wire::ComposedProtocolTwoWayAnonComposedWithErrorResponse> val) {
    ComposedProtocolTwoWayAnonComposedWithErrorResult result;
    result.ordinal_ = ::test_protocollayoutssamelibrary::wire::ComposedProtocolTwoWayAnonComposedWithErrorResult::Ordinal::kResponse;
    result.envelope_.As<::test_protocollayoutssamelibrary::wire::ComposedProtocolTwoWayAnonComposedWithErrorResponse>().set_data(std::move(val));
    return result;
  }

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


  ::test_protocollayoutssamelibrary::wire::ComposedProtocolTwoWayAnonComposedWithErrorResponse& response() {
    ZX_ASSERT(ordinal_ == ::test_protocollayoutssamelibrary::wire::ComposedProtocolTwoWayAnonComposedWithErrorResult::Ordinal::kResponse);
    return envelope_.As<::test_protocollayoutssamelibrary::wire::ComposedProtocolTwoWayAnonComposedWithErrorResponse>().get_data();
  }
  const ::test_protocollayoutssamelibrary::wire::ComposedProtocolTwoWayAnonComposedWithErrorResponse& response() const {
    ZX_ASSERT(ordinal_ == ::test_protocollayoutssamelibrary::wire::ComposedProtocolTwoWayAnonComposedWithErrorResult::Ordinal::kResponse);
    return envelope_.As<::test_protocollayoutssamelibrary::wire::ComposedProtocolTwoWayAnonComposedWithErrorResponse>().get_data();
  }

  bool is_err() const { return ordinal_ == ::test_protocollayoutssamelibrary::wire::ComposedProtocolTwoWayAnonComposedWithErrorResult::Ordinal::kErr; }
  
  static ComposedProtocolTwoWayAnonComposedWithErrorResult WithErr(uint32_t val) {
    ComposedProtocolTwoWayAnonComposedWithErrorResult result;
    result.ordinal_ = ::test_protocollayoutssamelibrary::wire::ComposedProtocolTwoWayAnonComposedWithErrorResult::Ordinal::kErr;
    result.envelope_.As<uint32_t>().set_data(std::move(val));
    return result;
  }


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

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

  static void SizeAndOffsetAssertionHelper();
  ::test_protocollayoutssamelibrary::wire::ComposedProtocolTwoWayAnonComposedWithErrorResult::Ordinal ordinal_;
  FIDL_ALIGNDECL
  ::fidl::UntypedEnvelope envelope_;
};




class ComposedProtocolOnAnonComposedRequest {
  public:

  ComposedProtocolOnAnonComposedRequest() : ordinal_(::test_protocollayoutssamelibrary::wire::ComposedProtocolOnAnonComposedRequest::Ordinal::Invalid), envelope_{} {}

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

  enum class Tag : fidl_xunion_tag_t {
    kB = 1,  // 0x1
  };

  bool has_invalid_tag() const { return ordinal_ == ::test_protocollayoutssamelibrary::wire::ComposedProtocolOnAnonComposedRequest::Ordinal::Invalid; }

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


  bool& b() {
    ZX_ASSERT(ordinal_ == ::test_protocollayoutssamelibrary::wire::ComposedProtocolOnAnonComposedRequest::Ordinal::kB);
    return envelope_.As<bool>().get_data();
  }
  const bool& b() const {
    ZX_ASSERT(ordinal_ == ::test_protocollayoutssamelibrary::wire::ComposedProtocolOnAnonComposedRequest::Ordinal::kB);
    return envelope_.As<bool>().get_data();
  }
  ::test_protocollayoutssamelibrary::wire::ComposedProtocolOnAnonComposedRequest::Tag Which() const {
    ZX_ASSERT(!has_invalid_tag());
    return static_cast<::test_protocollayoutssamelibrary::wire::ComposedProtocolOnAnonComposedRequest::Tag>(ordinal_);
  }

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

  static void SizeAndOffsetAssertionHelper();
  ::test_protocollayoutssamelibrary::wire::ComposedProtocolOnAnonComposedRequest::Ordinal ordinal_;
  FIDL_ALIGNDECL
  ::fidl::UntypedEnvelope envelope_;
};




class ComposedProtocolTwoWayNamedComposedWithErrorResult {
  public:

  ComposedProtocolTwoWayNamedComposedWithErrorResult() : ordinal_(::test_protocollayoutssamelibrary::wire::ComposedProtocolTwoWayNamedComposedWithErrorResult::Ordinal::Invalid), envelope_{} {}

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

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

  bool has_invalid_tag() const { return ordinal_ == ::test_protocollayoutssamelibrary::wire::ComposedProtocolTwoWayNamedComposedWithErrorResult::Ordinal::Invalid; }

  bool is_response() const { return ordinal_ == ::test_protocollayoutssamelibrary::wire::ComposedProtocolTwoWayNamedComposedWithErrorResult::Ordinal::kResponse; }
  
  static ComposedProtocolTwoWayNamedComposedWithErrorResult WithResponse(::fidl::ObjectView<::test_protocollayoutssamelibrary::wire::UnionPayload> val) {
    ComposedProtocolTwoWayNamedComposedWithErrorResult result;
    result.ordinal_ = ::test_protocollayoutssamelibrary::wire::ComposedProtocolTwoWayNamedComposedWithErrorResult::Ordinal::kResponse;
    result.envelope_.As<::test_protocollayoutssamelibrary::wire::UnionPayload>().set_data(std::move(val));
    return result;
  }

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


  ::test_protocollayoutssamelibrary::wire::UnionPayload& response() {
    ZX_ASSERT(ordinal_ == ::test_protocollayoutssamelibrary::wire::ComposedProtocolTwoWayNamedComposedWithErrorResult::Ordinal::kResponse);
    return envelope_.As<::test_protocollayoutssamelibrary::wire::UnionPayload>().get_data();
  }
  const ::test_protocollayoutssamelibrary::wire::UnionPayload& response() const {
    ZX_ASSERT(ordinal_ == ::test_protocollayoutssamelibrary::wire::ComposedProtocolTwoWayNamedComposedWithErrorResult::Ordinal::kResponse);
    return envelope_.As<::test_protocollayoutssamelibrary::wire::UnionPayload>().get_data();
  }

  bool is_err() const { return ordinal_ == ::test_protocollayoutssamelibrary::wire::ComposedProtocolTwoWayNamedComposedWithErrorResult::Ordinal::kErr; }
  
  static ComposedProtocolTwoWayNamedComposedWithErrorResult WithErr(uint32_t val) {
    ComposedProtocolTwoWayNamedComposedWithErrorResult result;
    result.ordinal_ = ::test_protocollayoutssamelibrary::wire::ComposedProtocolTwoWayNamedComposedWithErrorResult::Ordinal::kErr;
    result.envelope_.As<uint32_t>().set_data(std::move(val));
    return result;
  }


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

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

  static void SizeAndOffsetAssertionHelper();
  ::test_protocollayoutssamelibrary::wire::ComposedProtocolTwoWayNamedComposedWithErrorResult::Ordinal ordinal_;
  FIDL_ALIGNDECL
  ::fidl::UntypedEnvelope envelope_;
};




class MainProtocolTwoWayLocalWithErrorResult {
  public:

  MainProtocolTwoWayLocalWithErrorResult() : ordinal_(::test_protocollayoutssamelibrary::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_protocollayoutssamelibrary::wire::MainProtocolTwoWayLocalWithErrorResult::Ordinal::Invalid; }

  bool is_response() const { return ordinal_ == ::test_protocollayoutssamelibrary::wire::MainProtocolTwoWayLocalWithErrorResult::Ordinal::kResponse; }
  
  static MainProtocolTwoWayLocalWithErrorResult WithResponse(::fidl::ObjectView<::test_protocollayoutssamelibrary::wire::UnionPayload> val) {
    MainProtocolTwoWayLocalWithErrorResult result;
    result.ordinal_ = ::test_protocollayoutssamelibrary::wire::MainProtocolTwoWayLocalWithErrorResult::Ordinal::kResponse;
    result.envelope_.As<::test_protocollayoutssamelibrary::wire::UnionPayload>().set_data(std::move(val));
    return result;
  }

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


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

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


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

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

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




class MainProtocolTwoWayAnonRequest {
  public:

  MainProtocolTwoWayAnonRequest() : ordinal_(::test_protocollayoutssamelibrary::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
    _do_not_handle_this__write_a_default_case_instead = ::std::numeric_limits<::fidl_union_tag_t>::max(),
  };
  constexpr bool IsUnknown() const {
    return Which() == ::test_protocollayoutssamelibrary::wire::MainProtocolTwoWayAnonRequest::Tag::_do_not_handle_this__write_a_default_case_instead;
  }

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

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


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

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

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




class MainProtocolTwoWayAnonWithErrorResponse {
  public:

  MainProtocolTwoWayAnonWithErrorResponse() : ordinal_(::test_protocollayoutssamelibrary::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
    _do_not_handle_this__write_a_default_case_instead = ::std::numeric_limits<::fidl_union_tag_t>::max(),
  };
  constexpr bool IsUnknown() const {
    return Which() == ::test_protocollayoutssamelibrary::wire::MainProtocolTwoWayAnonWithErrorResponse::Tag::_do_not_handle_this__write_a_default_case_instead;
  }

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

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


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

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

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




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

  MainProtocolTwoWayAnonWithErrorResult() : ordinal_(::test_protocollayoutssamelibrary::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_protocollayoutssamelibrary::wire::MainProtocolTwoWayAnonWithErrorResult::Ordinal::Invalid; }

  bool is_response() const { return ordinal_ == ::test_protocollayoutssamelibrary::wire::MainProtocolTwoWayAnonWithErrorResult::Ordinal::kResponse; }
  
  static MainProtocolTwoWayAnonWithErrorResult WithResponse(::fidl::ObjectView<::test_protocollayoutssamelibrary::wire::MainProtocolTwoWayAnonWithErrorResponse> val) {
    MainProtocolTwoWayAnonWithErrorResult result;
    result.ordinal_ = ::test_protocollayoutssamelibrary::wire::MainProtocolTwoWayAnonWithErrorResult::Ordinal::kResponse;
    result.envelope_.As<::test_protocollayoutssamelibrary::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_protocollayoutssamelibrary::wire::MainProtocolTwoWayAnonWithErrorResponse>(allocator,
                                         std::forward<Args>(args)...));
  }


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

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


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

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

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




class MainProtocolOnAnonRequest {
  public:

  MainProtocolOnAnonRequest() : ordinal_(::test_protocollayoutssamelibrary::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
    _do_not_handle_this__write_a_default_case_instead = ::std::numeric_limits<::fidl_union_tag_t>::max(),
  };
  constexpr bool IsUnknown() const {
    return Which() == ::test_protocollayoutssamelibrary::wire::MainProtocolOnAnonRequest::Tag::_do_not_handle_this__write_a_default_case_instead;
  }

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

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


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

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

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

  }  // namespace wire
}  // namespace test_protocollayoutssamelibrary
namespace fidl {


  
  
  
  


template <>
struct TypeTraits<::test_protocollayoutssamelibrary::wire::TablePayload> {
  static constexpr uint32_t kMaxNumHandles = 0;
  static constexpr uint32_t kMaxDepth = 2;
  static constexpr uint32_t kPrimarySize = 16;
  [[maybe_unused]]
  static constexpr uint32_t kMaxOutOfLine = 8;
  static constexpr bool kHasFlexibleEnvelope = true;
  static constexpr bool kHasPointer = true;
};

template <>
struct IsFidlType<::test_protocollayoutssamelibrary::wire::TablePayload> : public std::true_type {};
template <>
struct IsWire<::test_protocollayoutssamelibrary::wire::TablePayload> : public std::true_type {};
template <>
struct IsTable<::test_protocollayoutssamelibrary::wire::TablePayload> : public std::true_type {};
static_assert(std::is_standard_layout_v<::test_protocollayoutssamelibrary::wire::TablePayload>);

template <bool IsRecursive>
struct ::fidl::internal::WireCodingTraits<::test_protocollayoutssamelibrary::wire::TablePayload, ::fidl::internal::WireCodingConstraintEmpty, IsRecursive>
  : ::fidl::internal::WireTableCodingTraitsBase<IsRecursive> {
  using Base = ::fidl::internal::WireTableCodingTraitsBase<IsRecursive>;
  static constexpr size_t kInlineSize = 16;
  static constexpr bool kIsMemcpyCompatible = false;

  static void Encode(internal::WireEncoder* encoder, ::test_protocollayoutssamelibrary::wire::TablePayload* value, ::fidl::internal::WirePosition position, RecursionDepth<IsRecursive> recursion_depth) {
    RecursionDepth<IsRecursive> inner_depth = recursion_depth.Add(encoder, 2);
    if (!inner_depth.IsValid()) {
      return;
    }

    ::fidl::internal::WirePosition vector_position;
    if (Base::PreworkResult::kEarlyExit ==
      Base::PrepareForBodyEncode(encoder, value, position, &vector_position)) {
      return;
    }

    fidl_vector_t* vec = reinterpret_cast<fidl_vector_t*>(value);
    fidl_envelope_t* envelopes = static_cast<fidl_envelope_t*>(vec->data);
    for (size_t i = 0; i < vec->count; i++) {
      
      size_t encode_inline_size = 0;
      switch (i) {
        case 0:
          encode_inline_size = ::fidl::internal::WireCodingTraits<uint16_t, fidl::internal::WireCodingConstraintEmpty, IsRecursive>::kInlineSize;
          break;
      }
      ::fidl::internal::EncodeFn<IsRecursive> encode_fn = nullptr;
      switch (i) {
        case 0:
          encode_fn = ::fidl::internal::MakeEncodeFn<uint16_t, fidl::internal::WireCodingConstraintEmpty, IsRecursive>();
          break;
      }
      WirePosition envelope_position = vector_position + i * sizeof(fidl_envelope_t);
      WireEncodeEnvelope(encode_inline_size, encode_fn, encoder, &envelopes[i], envelope_position, inner_depth);
    }
  }
  static void Decode(internal::WireDecoder* decoder, ::fidl::internal::WirePosition position, RecursionDepth<IsRecursive> recursion_depth) {
    RecursionDepth<IsRecursive> inner_depth = recursion_depth.Add(decoder, 2);
    if (!inner_depth.IsValid()) {
      return;
    }

    ::fidl::internal::WirePosition vector_position;
    if (Base::PreworkResult::kEarlyExit == Base::DecodePrework(decoder, position, &vector_position)) {
      return;
    }

    fidl_vector_t* vec = position.As<fidl_vector_t>();
    for (size_t i = 0; i < vec->count; i++) {
      
      size_t decode_inline_size = 0;
      switch (i) {
        case 0:
          decode_inline_size = ::fidl::internal::WireCodingTraits<uint16_t, fidl::internal::WireCodingConstraintEmpty, IsRecursive>::kInlineSize;
          break;
      }
      DecodeFn<IsRecursive> decode_fn = nullptr;
      switch(i) {
        case 0:
          decode_fn = ::fidl::internal::MakeDecodeFn<uint16_t, fidl::internal::WireCodingConstraintEmpty, IsRecursive>();
          break;
      }
      ::fidl::internal::WireDecodeOptionalEnvelope(decode_inline_size, decode_fn, decoder, vector_position + i * sizeof(fidl_envelope_t), inner_depth);
    }
  }
};


template <>
struct TypeTraits<::test_protocollayoutssamelibrary::wire::ComposedProtocolOneWayAnonComposedRequest> {
  static constexpr uint32_t kMaxNumHandles = 0;
  static constexpr uint32_t kMaxDepth = 2;
  static constexpr uint32_t kPrimarySize = 16;
  [[maybe_unused]]
  static constexpr uint32_t kMaxOutOfLine = 8;
  static constexpr bool kHasFlexibleEnvelope = true;
  static constexpr bool kHasPointer = true;
};

template <>
struct IsFidlType<::test_protocollayoutssamelibrary::wire::ComposedProtocolOneWayAnonComposedRequest> : public std::true_type {};
template <>
struct IsWire<::test_protocollayoutssamelibrary::wire::ComposedProtocolOneWayAnonComposedRequest> : public std::true_type {};
template <>
struct IsTable<::test_protocollayoutssamelibrary::wire::ComposedProtocolOneWayAnonComposedRequest> : public std::true_type {};
static_assert(std::is_standard_layout_v<::test_protocollayoutssamelibrary::wire::ComposedProtocolOneWayAnonComposedRequest>);

template <bool IsRecursive>
struct ::fidl::internal::WireCodingTraits<::test_protocollayoutssamelibrary::wire::ComposedProtocolOneWayAnonComposedRequest, ::fidl::internal::WireCodingConstraintEmpty, IsRecursive>
  : ::fidl::internal::WireTableCodingTraitsBase<IsRecursive> {
  using Base = ::fidl::internal::WireTableCodingTraitsBase<IsRecursive>;
  static constexpr size_t kInlineSize = 16;
  static constexpr bool kIsMemcpyCompatible = false;

  static void Encode(internal::WireEncoder* encoder, ::test_protocollayoutssamelibrary::wire::ComposedProtocolOneWayAnonComposedRequest* value, ::fidl::internal::WirePosition position, RecursionDepth<IsRecursive> recursion_depth) {
    RecursionDepth<IsRecursive> inner_depth = recursion_depth.Add(encoder, 2);
    if (!inner_depth.IsValid()) {
      return;
    }

    ::fidl::internal::WirePosition vector_position;
    if (Base::PreworkResult::kEarlyExit ==
      Base::PrepareForBodyEncode(encoder, value, position, &vector_position)) {
      return;
    }

    fidl_vector_t* vec = reinterpret_cast<fidl_vector_t*>(value);
    fidl_envelope_t* envelopes = static_cast<fidl_envelope_t*>(vec->data);
    for (size_t i = 0; i < vec->count; i++) {
      
      size_t encode_inline_size = 0;
      switch (i) {
        case 0:
          encode_inline_size = ::fidl::internal::WireCodingTraits<uint16_t, fidl::internal::WireCodingConstraintEmpty, IsRecursive>::kInlineSize;
          break;
      }
      ::fidl::internal::EncodeFn<IsRecursive> encode_fn = nullptr;
      switch (i) {
        case 0:
          encode_fn = ::fidl::internal::MakeEncodeFn<uint16_t, fidl::internal::WireCodingConstraintEmpty, IsRecursive>();
          break;
      }
      WirePosition envelope_position = vector_position + i * sizeof(fidl_envelope_t);
      WireEncodeEnvelope(encode_inline_size, encode_fn, encoder, &envelopes[i], envelope_position, inner_depth);
    }
  }
  static void Decode(internal::WireDecoder* decoder, ::fidl::internal::WirePosition position, RecursionDepth<IsRecursive> recursion_depth) {
    RecursionDepth<IsRecursive> inner_depth = recursion_depth.Add(decoder, 2);
    if (!inner_depth.IsValid()) {
      return;
    }

    ::fidl::internal::WirePosition vector_position;
    if (Base::PreworkResult::kEarlyExit == Base::DecodePrework(decoder, position, &vector_position)) {
      return;
    }

    fidl_vector_t* vec = position.As<fidl_vector_t>();
    for (size_t i = 0; i < vec->count; i++) {
      
      size_t decode_inline_size = 0;
      switch (i) {
        case 0:
          decode_inline_size = ::fidl::internal::WireCodingTraits<uint16_t, fidl::internal::WireCodingConstraintEmpty, IsRecursive>::kInlineSize;
          break;
      }
      DecodeFn<IsRecursive> decode_fn = nullptr;
      switch(i) {
        case 0:
          decode_fn = ::fidl::internal::MakeDecodeFn<uint16_t, fidl::internal::WireCodingConstraintEmpty, IsRecursive>();
          break;
      }
      ::fidl::internal::WireDecodeOptionalEnvelope(decode_inline_size, decode_fn, decoder, vector_position + i * sizeof(fidl_envelope_t), inner_depth);
    }
  }
};


template <>
struct TypeTraits<::test_protocollayoutssamelibrary::wire::ComposedProtocolTwoWayAnonComposedResponse> {
  static constexpr uint32_t kMaxNumHandles = 0;
  static constexpr uint32_t kMaxDepth = 2;
  static constexpr uint32_t kPrimarySize = 16;
  [[maybe_unused]]
  static constexpr uint32_t kMaxOutOfLine = 8;
  static constexpr bool kHasFlexibleEnvelope = true;
  static constexpr bool kHasPointer = true;
};

template <>
struct IsFidlType<::test_protocollayoutssamelibrary::wire::ComposedProtocolTwoWayAnonComposedResponse> : public std::true_type {};
template <>
struct IsWire<::test_protocollayoutssamelibrary::wire::ComposedProtocolTwoWayAnonComposedResponse> : public std::true_type {};
template <>
struct IsTable<::test_protocollayoutssamelibrary::wire::ComposedProtocolTwoWayAnonComposedResponse> : public std::true_type {};
static_assert(std::is_standard_layout_v<::test_protocollayoutssamelibrary::wire::ComposedProtocolTwoWayAnonComposedResponse>);

template <bool IsRecursive>
struct ::fidl::internal::WireCodingTraits<::test_protocollayoutssamelibrary::wire::ComposedProtocolTwoWayAnonComposedResponse, ::fidl::internal::WireCodingConstraintEmpty, IsRecursive>
  : ::fidl::internal::WireTableCodingTraitsBase<IsRecursive> {
  using Base = ::fidl::internal::WireTableCodingTraitsBase<IsRecursive>;
  static constexpr size_t kInlineSize = 16;
  static constexpr bool kIsMemcpyCompatible = false;

  static void Encode(internal::WireEncoder* encoder, ::test_protocollayoutssamelibrary::wire::ComposedProtocolTwoWayAnonComposedResponse* value, ::fidl::internal::WirePosition position, RecursionDepth<IsRecursive> recursion_depth) {
    RecursionDepth<IsRecursive> inner_depth = recursion_depth.Add(encoder, 2);
    if (!inner_depth.IsValid()) {
      return;
    }

    ::fidl::internal::WirePosition vector_position;
    if (Base::PreworkResult::kEarlyExit ==
      Base::PrepareForBodyEncode(encoder, value, position, &vector_position)) {
      return;
    }

    fidl_vector_t* vec = reinterpret_cast<fidl_vector_t*>(value);
    fidl_envelope_t* envelopes = static_cast<fidl_envelope_t*>(vec->data);
    for (size_t i = 0; i < vec->count; i++) {
      
      size_t encode_inline_size = 0;
      switch (i) {
        case 0:
          encode_inline_size = ::fidl::internal::WireCodingTraits<uint16_t, fidl::internal::WireCodingConstraintEmpty, IsRecursive>::kInlineSize;
          break;
      }
      ::fidl::internal::EncodeFn<IsRecursive> encode_fn = nullptr;
      switch (i) {
        case 0:
          encode_fn = ::fidl::internal::MakeEncodeFn<uint16_t, fidl::internal::WireCodingConstraintEmpty, IsRecursive>();
          break;
      }
      WirePosition envelope_position = vector_position + i * sizeof(fidl_envelope_t);
      WireEncodeEnvelope(encode_inline_size, encode_fn, encoder, &envelopes[i], envelope_position, inner_depth);
    }
  }
  static void Decode(internal::WireDecoder* decoder, ::fidl::internal::WirePosition position, RecursionDepth<IsRecursive> recursion_depth) {
    RecursionDepth<IsRecursive> inner_depth = recursion_depth.Add(decoder, 2);
    if (!inner_depth.IsValid()) {
      return;
    }

    ::fidl::internal::WirePosition vector_position;
    if (Base::PreworkResult::kEarlyExit == Base::DecodePrework(decoder, position, &vector_position)) {
      return;
    }

    fidl_vector_t* vec = position.As<fidl_vector_t>();
    for (size_t i = 0; i < vec->count; i++) {
      
      size_t decode_inline_size = 0;
      switch (i) {
        case 0:
          decode_inline_size = ::fidl::internal::WireCodingTraits<uint16_t, fidl::internal::WireCodingConstraintEmpty, IsRecursive>::kInlineSize;
          break;
      }
      DecodeFn<IsRecursive> decode_fn = nullptr;
      switch(i) {
        case 0:
          decode_fn = ::fidl::internal::MakeDecodeFn<uint16_t, fidl::internal::WireCodingConstraintEmpty, IsRecursive>();
          break;
      }
      ::fidl::internal::WireDecodeOptionalEnvelope(decode_inline_size, decode_fn, decoder, vector_position + i * sizeof(fidl_envelope_t), inner_depth);
    }
  }
};


template <>
struct TypeTraits<::test_protocollayoutssamelibrary::wire::ComposedProtocolTwoWayAnonComposedWithErrorRequest> {
  static constexpr uint32_t kMaxNumHandles = 0;
  static constexpr uint32_t kMaxDepth = 2;
  static constexpr uint32_t kPrimarySize = 16;
  [[maybe_unused]]
  static constexpr uint32_t kMaxOutOfLine = 8;
  static constexpr bool kHasFlexibleEnvelope = true;
  static constexpr bool kHasPointer = true;
};

template <>
struct IsFidlType<::test_protocollayoutssamelibrary::wire::ComposedProtocolTwoWayAnonComposedWithErrorRequest> : public std::true_type {};
template <>
struct IsWire<::test_protocollayoutssamelibrary::wire::ComposedProtocolTwoWayAnonComposedWithErrorRequest> : public std::true_type {};
template <>
struct IsTable<::test_protocollayoutssamelibrary::wire::ComposedProtocolTwoWayAnonComposedWithErrorRequest> : public std::true_type {};
static_assert(std::is_standard_layout_v<::test_protocollayoutssamelibrary::wire::ComposedProtocolTwoWayAnonComposedWithErrorRequest>);

template <bool IsRecursive>
struct ::fidl::internal::WireCodingTraits<::test_protocollayoutssamelibrary::wire::ComposedProtocolTwoWayAnonComposedWithErrorRequest, ::fidl::internal::WireCodingConstraintEmpty, IsRecursive>
  : ::fidl::internal::WireTableCodingTraitsBase<IsRecursive> {
  using Base = ::fidl::internal::WireTableCodingTraitsBase<IsRecursive>;
  static constexpr size_t kInlineSize = 16;
  static constexpr bool kIsMemcpyCompatible = false;

  static void Encode(internal::WireEncoder* encoder, ::test_protocollayoutssamelibrary::wire::ComposedProtocolTwoWayAnonComposedWithErrorRequest* value, ::fidl::internal::WirePosition position, RecursionDepth<IsRecursive> recursion_depth) {
    RecursionDepth<IsRecursive> inner_depth = recursion_depth.Add(encoder, 2);
    if (!inner_depth.IsValid()) {
      return;
    }

    ::fidl::internal::WirePosition vector_position;
    if (Base::PreworkResult::kEarlyExit ==
      Base::PrepareForBodyEncode(encoder, value, position, &vector_position)) {
      return;
    }

    fidl_vector_t* vec = reinterpret_cast<fidl_vector_t*>(value);
    fidl_envelope_t* envelopes = static_cast<fidl_envelope_t*>(vec->data);
    for (size_t i = 0; i < vec->count; i++) {
      
      size_t encode_inline_size = 0;
      switch (i) {
        case 0:
          encode_inline_size = ::fidl::internal::WireCodingTraits<uint16_t, fidl::internal::WireCodingConstraintEmpty, IsRecursive>::kInlineSize;
          break;
      }
      ::fidl::internal::EncodeFn<IsRecursive> encode_fn = nullptr;
      switch (i) {
        case 0:
          encode_fn = ::fidl::internal::MakeEncodeFn<uint16_t, fidl::internal::WireCodingConstraintEmpty, IsRecursive>();
          break;
      }
      WirePosition envelope_position = vector_position + i * sizeof(fidl_envelope_t);
      WireEncodeEnvelope(encode_inline_size, encode_fn, encoder, &envelopes[i], envelope_position, inner_depth);
    }
  }
  static void Decode(internal::WireDecoder* decoder, ::fidl::internal::WirePosition position, RecursionDepth<IsRecursive> recursion_depth) {
    RecursionDepth<IsRecursive> inner_depth = recursion_depth.Add(decoder, 2);
    if (!inner_depth.IsValid()) {
      return;
    }

    ::fidl::internal::WirePosition vector_position;
    if (Base::PreworkResult::kEarlyExit == Base::DecodePrework(decoder, position, &vector_position)) {
      return;
    }

    fidl_vector_t* vec = position.As<fidl_vector_t>();
    for (size_t i = 0; i < vec->count; i++) {
      
      size_t decode_inline_size = 0;
      switch (i) {
        case 0:
          decode_inline_size = ::fidl::internal::WireCodingTraits<uint16_t, fidl::internal::WireCodingConstraintEmpty, IsRecursive>::kInlineSize;
          break;
      }
      DecodeFn<IsRecursive> decode_fn = nullptr;
      switch(i) {
        case 0:
          decode_fn = ::fidl::internal::MakeDecodeFn<uint16_t, fidl::internal::WireCodingConstraintEmpty, IsRecursive>();
          break;
      }
      ::fidl::internal::WireDecodeOptionalEnvelope(decode_inline_size, decode_fn, decoder, vector_position + i * sizeof(fidl_envelope_t), inner_depth);
    }
  }
};


template <>
struct TypeTraits<::test_protocollayoutssamelibrary::wire::MainProtocolOneWayAnonRequest> {
  static constexpr uint32_t kMaxNumHandles = 0;
  static constexpr uint32_t kMaxDepth = 2;
  static constexpr uint32_t kPrimarySize = 16;
  [[maybe_unused]]
  static constexpr uint32_t kMaxOutOfLine = 8;
  static constexpr bool kHasFlexibleEnvelope = true;
  static constexpr bool kHasPointer = true;
};

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

template <bool IsRecursive>
struct ::fidl::internal::WireCodingTraits<::test_protocollayoutssamelibrary::wire::MainProtocolOneWayAnonRequest, ::fidl::internal::WireCodingConstraintEmpty, IsRecursive>
  : ::fidl::internal::WireTableCodingTraitsBase<IsRecursive> {
  using Base = ::fidl::internal::WireTableCodingTraitsBase<IsRecursive>;
  static constexpr size_t kInlineSize = 16;
  static constexpr bool kIsMemcpyCompatible = false;

  static void Encode(internal::WireEncoder* encoder, ::test_protocollayoutssamelibrary::wire::MainProtocolOneWayAnonRequest* value, ::fidl::internal::WirePosition position, RecursionDepth<IsRecursive> recursion_depth) {
    RecursionDepth<IsRecursive> inner_depth = recursion_depth.Add(encoder, 2);
    if (!inner_depth.IsValid()) {
      return;
    }

    ::fidl::internal::WirePosition vector_position;
    if (Base::PreworkResult::kEarlyExit ==
      Base::PrepareForBodyEncode(encoder, value, position, &vector_position)) {
      return;
    }

    fidl_vector_t* vec = reinterpret_cast<fidl_vector_t*>(value);
    fidl_envelope_t* envelopes = static_cast<fidl_envelope_t*>(vec->data);
    for (size_t i = 0; i < vec->count; i++) {
      
      size_t encode_inline_size = 0;
      switch (i) {
        case 0:
          encode_inline_size = ::fidl::internal::WireCodingTraits<uint16_t, fidl::internal::WireCodingConstraintEmpty, IsRecursive>::kInlineSize;
          break;
      }
      ::fidl::internal::EncodeFn<IsRecursive> encode_fn = nullptr;
      switch (i) {
        case 0:
          encode_fn = ::fidl::internal::MakeEncodeFn<uint16_t, fidl::internal::WireCodingConstraintEmpty, IsRecursive>();
          break;
      }
      WirePosition envelope_position = vector_position + i * sizeof(fidl_envelope_t);
      WireEncodeEnvelope(encode_inline_size, encode_fn, encoder, &envelopes[i], envelope_position, inner_depth);
    }
  }
  static void Decode(internal::WireDecoder* decoder, ::fidl::internal::WirePosition position, RecursionDepth<IsRecursive> recursion_depth) {
    RecursionDepth<IsRecursive> inner_depth = recursion_depth.Add(decoder, 2);
    if (!inner_depth.IsValid()) {
      return;
    }

    ::fidl::internal::WirePosition vector_position;
    if (Base::PreworkResult::kEarlyExit == Base::DecodePrework(decoder, position, &vector_position)) {
      return;
    }

    fidl_vector_t* vec = position.As<fidl_vector_t>();
    for (size_t i = 0; i < vec->count; i++) {
      
      size_t decode_inline_size = 0;
      switch (i) {
        case 0:
          decode_inline_size = ::fidl::internal::WireCodingTraits<uint16_t, fidl::internal::WireCodingConstraintEmpty, IsRecursive>::kInlineSize;
          break;
      }
      DecodeFn<IsRecursive> decode_fn = nullptr;
      switch(i) {
        case 0:
          decode_fn = ::fidl::internal::MakeDecodeFn<uint16_t, fidl::internal::WireCodingConstraintEmpty, IsRecursive>();
          break;
      }
      ::fidl::internal::WireDecodeOptionalEnvelope(decode_inline_size, decode_fn, decoder, vector_position + i * sizeof(fidl_envelope_t), inner_depth);
    }
  }
};


template <>
struct TypeTraits<::test_protocollayoutssamelibrary::wire::MainProtocolTwoWayAnonResponse> {
  static constexpr uint32_t kMaxNumHandles = 0;
  static constexpr uint32_t kMaxDepth = 2;
  static constexpr uint32_t kPrimarySize = 16;
  [[maybe_unused]]
  static constexpr uint32_t kMaxOutOfLine = 8;
  static constexpr bool kHasFlexibleEnvelope = true;
  static constexpr bool kHasPointer = true;
};

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

template <bool IsRecursive>
struct ::fidl::internal::WireCodingTraits<::test_protocollayoutssamelibrary::wire::MainProtocolTwoWayAnonResponse, ::fidl::internal::WireCodingConstraintEmpty, IsRecursive>
  : ::fidl::internal::WireTableCodingTraitsBase<IsRecursive> {
  using Base = ::fidl::internal::WireTableCodingTraitsBase<IsRecursive>;
  static constexpr size_t kInlineSize = 16;
  static constexpr bool kIsMemcpyCompatible = false;

  static void Encode(internal::WireEncoder* encoder, ::test_protocollayoutssamelibrary::wire::MainProtocolTwoWayAnonResponse* value, ::fidl::internal::WirePosition position, RecursionDepth<IsRecursive> recursion_depth) {
    RecursionDepth<IsRecursive> inner_depth = recursion_depth.Add(encoder, 2);
    if (!inner_depth.IsValid()) {
      return;
    }

    ::fidl::internal::WirePosition vector_position;
    if (Base::PreworkResult::kEarlyExit ==
      Base::PrepareForBodyEncode(encoder, value, position, &vector_position)) {
      return;
    }

    fidl_vector_t* vec = reinterpret_cast<fidl_vector_t*>(value);
    fidl_envelope_t* envelopes = static_cast<fidl_envelope_t*>(vec->data);
    for (size_t i = 0; i < vec->count; i++) {
      
      size_t encode_inline_size = 0;
      switch (i) {
        case 0:
          encode_inline_size = ::fidl::internal::WireCodingTraits<uint16_t, fidl::internal::WireCodingConstraintEmpty, IsRecursive>::kInlineSize;
          break;
      }
      ::fidl::internal::EncodeFn<IsRecursive> encode_fn = nullptr;
      switch (i) {
        case 0:
          encode_fn = ::fidl::internal::MakeEncodeFn<uint16_t, fidl::internal::WireCodingConstraintEmpty, IsRecursive>();
          break;
      }
      WirePosition envelope_position = vector_position + i * sizeof(fidl_envelope_t);
      WireEncodeEnvelope(encode_inline_size, encode_fn, encoder, &envelopes[i], envelope_position, inner_depth);
    }
  }
  static void Decode(internal::WireDecoder* decoder, ::fidl::internal::WirePosition position, RecursionDepth<IsRecursive> recursion_depth) {
    RecursionDepth<IsRecursive> inner_depth = recursion_depth.Add(decoder, 2);
    if (!inner_depth.IsValid()) {
      return;
    }

    ::fidl::internal::WirePosition vector_position;
    if (Base::PreworkResult::kEarlyExit == Base::DecodePrework(decoder, position, &vector_position)) {
      return;
    }

    fidl_vector_t* vec = position.As<fidl_vector_t>();
    for (size_t i = 0; i < vec->count; i++) {
      
      size_t decode_inline_size = 0;
      switch (i) {
        case 0:
          decode_inline_size = ::fidl::internal::WireCodingTraits<uint16_t, fidl::internal::WireCodingConstraintEmpty, IsRecursive>::kInlineSize;
          break;
      }
      DecodeFn<IsRecursive> decode_fn = nullptr;
      switch(i) {
        case 0:
          decode_fn = ::fidl::internal::MakeDecodeFn<uint16_t, fidl::internal::WireCodingConstraintEmpty, IsRecursive>();
          break;
      }
      ::fidl::internal::WireDecodeOptionalEnvelope(decode_inline_size, decode_fn, decoder, vector_position + i * sizeof(fidl_envelope_t), inner_depth);
    }
  }
};


template <>
struct TypeTraits<::test_protocollayoutssamelibrary::wire::MainProtocolTwoWayAnonWithErrorRequest> {
  static constexpr uint32_t kMaxNumHandles = 0;
  static constexpr uint32_t kMaxDepth = 2;
  static constexpr uint32_t kPrimarySize = 16;
  [[maybe_unused]]
  static constexpr uint32_t kMaxOutOfLine = 8;
  static constexpr bool kHasFlexibleEnvelope = true;
  static constexpr bool kHasPointer = true;
};

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

template <bool IsRecursive>
struct ::fidl::internal::WireCodingTraits<::test_protocollayoutssamelibrary::wire::MainProtocolTwoWayAnonWithErrorRequest, ::fidl::internal::WireCodingConstraintEmpty, IsRecursive>
  : ::fidl::internal::WireTableCodingTraitsBase<IsRecursive> {
  using Base = ::fidl::internal::WireTableCodingTraitsBase<IsRecursive>;
  static constexpr size_t kInlineSize = 16;
  static constexpr bool kIsMemcpyCompatible = false;

  static void Encode(internal::WireEncoder* encoder, ::test_protocollayoutssamelibrary::wire::MainProtocolTwoWayAnonWithErrorRequest* value, ::fidl::internal::WirePosition position, RecursionDepth<IsRecursive> recursion_depth) {
    RecursionDepth<IsRecursive> inner_depth = recursion_depth.Add(encoder, 2);
    if (!inner_depth.IsValid()) {
      return;
    }

    ::fidl::internal::WirePosition vector_position;
    if (Base::PreworkResult::kEarlyExit ==
      Base::PrepareForBodyEncode(encoder, value, position, &vector_position)) {
      return;
    }

    fidl_vector_t* vec = reinterpret_cast<fidl_vector_t*>(value);
    fidl_envelope_t* envelopes = static_cast<fidl_envelope_t*>(vec->data);
    for (size_t i = 0; i < vec->count; i++) {
      
      size_t encode_inline_size = 0;
      switch (i) {
        case 0:
          encode_inline_size = ::fidl::internal::WireCodingTraits<uint16_t, fidl::internal::WireCodingConstraintEmpty, IsRecursive>::kInlineSize;
          break;
      }
      ::fidl::internal::EncodeFn<IsRecursive> encode_fn = nullptr;
      switch (i) {
        case 0:
          encode_fn = ::fidl::internal::MakeEncodeFn<uint16_t, fidl::internal::WireCodingConstraintEmpty, IsRecursive>();
          break;
      }
      WirePosition envelope_position = vector_position + i * sizeof(fidl_envelope_t);
      WireEncodeEnvelope(encode_inline_size, encode_fn, encoder, &envelopes[i], envelope_position, inner_depth);
    }
  }
  static void Decode(internal::WireDecoder* decoder, ::fidl::internal::WirePosition position, RecursionDepth<IsRecursive> recursion_depth) {
    RecursionDepth<IsRecursive> inner_depth = recursion_depth.Add(decoder, 2);
    if (!inner_depth.IsValid()) {
      return;
    }

    ::fidl::internal::WirePosition vector_position;
    if (Base::PreworkResult::kEarlyExit == Base::DecodePrework(decoder, position, &vector_position)) {
      return;
    }

    fidl_vector_t* vec = position.As<fidl_vector_t>();
    for (size_t i = 0; i < vec->count; i++) {
      
      size_t decode_inline_size = 0;
      switch (i) {
        case 0:
          decode_inline_size = ::fidl::internal::WireCodingTraits<uint16_t, fidl::internal::WireCodingConstraintEmpty, IsRecursive>::kInlineSize;
          break;
      }
      DecodeFn<IsRecursive> decode_fn = nullptr;
      switch(i) {
        case 0:
          decode_fn = ::fidl::internal::MakeDecodeFn<uint16_t, fidl::internal::WireCodingConstraintEmpty, IsRecursive>();
          break;
      }
      ::fidl::internal::WireDecodeOptionalEnvelope(decode_inline_size, decode_fn, decoder, vector_position + i * sizeof(fidl_envelope_t), inner_depth);
    }
  }
};
  


template <>
struct TypeTraits<::test_protocollayoutssamelibrary::wire::UnionPayload> {
  static constexpr uint32_t kMaxNumHandles = 0;
  static constexpr uint32_t kMaxDepth = 1;
  static constexpr uint32_t kPrimarySize = 16;
  [[maybe_unused]]
  static constexpr uint32_t kMaxOutOfLine = 0;
  static constexpr bool kHasFlexibleEnvelope = false;
  static constexpr bool kHasPointer = true;
};

template <>
struct IsFidlType<::test_protocollayoutssamelibrary::wire::UnionPayload> : public std::true_type {};
template <>
struct IsWire<::test_protocollayoutssamelibrary::wire::UnionPayload> : public std::true_type {};
template <>
struct IsUnion<::test_protocollayoutssamelibrary::wire::UnionPayload> : public std::true_type {};
static_assert(std::is_standard_layout_v<::test_protocollayoutssamelibrary::wire::UnionPayload>);

template <typename Constraint, bool IsRecursive>
struct ::fidl::internal::WireCodingTraits<::test_protocollayoutssamelibrary::wire::UnionPayload, Constraint, IsRecursive> {
  static constexpr size_t kInlineSize = 16;
  static constexpr bool kIsMemcpyCompatible = false;

  static void Encode(internal::WireEncoder* encoder, ::test_protocollayoutssamelibrary::wire::UnionPayload* value, ::fidl::internal::WirePosition position, RecursionDepth<IsRecursive> recursion_depth) {
    fidl_union_t* u = reinterpret_cast<fidl_union_t*>(value);

    if (unlikely(u->tag == 0)) {
      if constexpr (Constraint::is_optional) {
        *position.As<fidl_union_t>() = {};
        return;
      }
      encoder->SetError(kCodingErrorInvalidUnionTag);
      return;
    }

    RecursionDepth<IsRecursive> inner_depth = recursion_depth.Add(encoder, 1);
    if (!inner_depth.IsValid()) {
      return;
    }

    *position.As<fidl_xunion_tag_t>() = u->tag;

    
    size_t encode_inline_size;
    switch (u->tag) {
      case 1: // ::test_protocollayoutssamelibrary::wire::UnionPayload::Tag::kB
        encode_inline_size = ::fidl::internal::WireCodingTraits<bool, fidl::internal::WireCodingConstraintEmpty, IsRecursive>::kInlineSize;
        break;
      default:
        encode_inline_size = 0;
        break;
    }
    ::fidl::internal::EncodeFn<IsRecursive> encode_fn;
    switch (u->tag) {
      case 1: // ::test_protocollayoutssamelibrary::wire::UnionPayload::Tag::kB
        encode_fn = ::fidl::internal::MakeEncodeFn<bool, fidl::internal::WireCodingConstraintEmpty, IsRecursive>();
        break;
      default:
        encode_fn = nullptr;
        break;
    }
    WireEncodeEnvelope(encode_inline_size, encode_fn, encoder, &u->envelope, position + sizeof(fidl_xunion_tag_t), inner_depth);
  }

  static void Decode(internal::WireDecoder* decoder, ::fidl::internal::WirePosition position, RecursionDepth<IsRecursive> recursion_depth) {
    ::test_protocollayoutssamelibrary::wire::UnionPayload::Tag tag = *position.As<::test_protocollayoutssamelibrary::wire::UnionPayload::Tag>();
    if (unlikely(static_cast<uint64_t>(tag) == 0)) {
      if constexpr (!Constraint::is_optional) {
        decoder->SetError(kCodingErrorInvalidUnionTag);
        return;
      }
      static_assert(sizeof(fidl_envelope_t) == sizeof(uint64_t));
      if (*(position + sizeof(fidl_xunion_tag_t)).As<uint64_t>() != 0) {
        decoder->SetError(kCodingErrorZeroTagButNonZeroEnvelope);
      }
      return;
    }

    RecursionDepth<IsRecursive> inner_depth = recursion_depth.Add(decoder, 1);
    if (!inner_depth.IsValid()) {
      return;
    }

    
    size_t decode_inline_size;
    switch (tag) {
      case ::test_protocollayoutssamelibrary::wire::UnionPayload::Tag::kB:
        decode_inline_size = ::fidl::internal::WireCodingTraits<bool, fidl::internal::WireCodingConstraintEmpty, IsRecursive>::kInlineSize;
        break;
      default:
        decode_inline_size = 0;
        break;
    }
    DecodeFn<IsRecursive> decode_fn;
    switch(tag) {
      case ::test_protocollayoutssamelibrary::wire::UnionPayload::Tag::kB:
        decode_fn = ::fidl::internal::MakeDecodeFn<bool, fidl::internal::WireCodingConstraintEmpty, IsRecursive>();
        break;
      default:
        decode_fn = nullptr;
        break;
    }
    ::fidl::internal::WireDecodeStrictEnvelope(decode_inline_size, decode_fn, decoder, position + sizeof(fidl_xunion_tag_t), inner_depth);
  }
};

// Top-level union.
template <bool IsRecursive>
struct ::fidl::internal::WireCodingTraits<::test_protocollayoutssamelibrary::wire::UnionPayload, ::fidl::internal::WireCodingConstraintEmpty, IsRecursive>
  : public ::fidl::internal::WireCodingTraits<::test_protocollayoutssamelibrary::wire::UnionPayload, ::fidl::internal::WireCodingConstraintUnion<false>, IsRecursive> {};


template <>
struct TypeTraits<::test_protocollayoutssamelibrary::wire::ComposedProtocolTwoWayAnonComposedRequest> {
  static constexpr uint32_t kMaxNumHandles = 0;
  static constexpr uint32_t kMaxDepth = 1;
  static constexpr uint32_t kPrimarySize = 16;
  [[maybe_unused]]
  static constexpr uint32_t kMaxOutOfLine = 0;
  static constexpr bool kHasFlexibleEnvelope = false;
  static constexpr bool kHasPointer = true;
};

template <>
struct IsFidlType<::test_protocollayoutssamelibrary::wire::ComposedProtocolTwoWayAnonComposedRequest> : public std::true_type {};
template <>
struct IsWire<::test_protocollayoutssamelibrary::wire::ComposedProtocolTwoWayAnonComposedRequest> : public std::true_type {};
template <>
struct IsUnion<::test_protocollayoutssamelibrary::wire::ComposedProtocolTwoWayAnonComposedRequest> : public std::true_type {};
static_assert(std::is_standard_layout_v<::test_protocollayoutssamelibrary::wire::ComposedProtocolTwoWayAnonComposedRequest>);

template <typename Constraint, bool IsRecursive>
struct ::fidl::internal::WireCodingTraits<::test_protocollayoutssamelibrary::wire::ComposedProtocolTwoWayAnonComposedRequest, Constraint, IsRecursive> {
  static constexpr size_t kInlineSize = 16;
  static constexpr bool kIsMemcpyCompatible = false;

  static void Encode(internal::WireEncoder* encoder, ::test_protocollayoutssamelibrary::wire::ComposedProtocolTwoWayAnonComposedRequest* value, ::fidl::internal::WirePosition position, RecursionDepth<IsRecursive> recursion_depth) {
    fidl_union_t* u = reinterpret_cast<fidl_union_t*>(value);

    if (unlikely(u->tag == 0)) {
      if constexpr (Constraint::is_optional) {
        *position.As<fidl_union_t>() = {};
        return;
      }
      encoder->SetError(kCodingErrorInvalidUnionTag);
      return;
    }

    RecursionDepth<IsRecursive> inner_depth = recursion_depth.Add(encoder, 1);
    if (!inner_depth.IsValid()) {
      return;
    }

    *position.As<fidl_xunion_tag_t>() = u->tag;

    
    size_t encode_inline_size;
    switch (u->tag) {
      case 1: // ::test_protocollayoutssamelibrary::wire::ComposedProtocolTwoWayAnonComposedRequest::Tag::kB
        encode_inline_size = ::fidl::internal::WireCodingTraits<bool, fidl::internal::WireCodingConstraintEmpty, IsRecursive>::kInlineSize;
        break;
      default:
        encode_inline_size = 0;
        break;
    }
    ::fidl::internal::EncodeFn<IsRecursive> encode_fn;
    switch (u->tag) {
      case 1: // ::test_protocollayoutssamelibrary::wire::ComposedProtocolTwoWayAnonComposedRequest::Tag::kB
        encode_fn = ::fidl::internal::MakeEncodeFn<bool, fidl::internal::WireCodingConstraintEmpty, IsRecursive>();
        break;
      default:
        encode_fn = nullptr;
        break;
    }
    WireEncodeEnvelope(encode_inline_size, encode_fn, encoder, &u->envelope, position + sizeof(fidl_xunion_tag_t), inner_depth);
  }

  static void Decode(internal::WireDecoder* decoder, ::fidl::internal::WirePosition position, RecursionDepth<IsRecursive> recursion_depth) {
    ::test_protocollayoutssamelibrary::wire::ComposedProtocolTwoWayAnonComposedRequest::Tag tag = *position.As<::test_protocollayoutssamelibrary::wire::ComposedProtocolTwoWayAnonComposedRequest::Tag>();
    if (unlikely(static_cast<uint64_t>(tag) == 0)) {
      if constexpr (!Constraint::is_optional) {
        decoder->SetError(kCodingErrorInvalidUnionTag);
        return;
      }
      static_assert(sizeof(fidl_envelope_t) == sizeof(uint64_t));
      if (*(position + sizeof(fidl_xunion_tag_t)).As<uint64_t>() != 0) {
        decoder->SetError(kCodingErrorZeroTagButNonZeroEnvelope);
      }
      return;
    }

    RecursionDepth<IsRecursive> inner_depth = recursion_depth.Add(decoder, 1);
    if (!inner_depth.IsValid()) {
      return;
    }

    
    size_t decode_inline_size;
    switch (tag) {
      case ::test_protocollayoutssamelibrary::wire::ComposedProtocolTwoWayAnonComposedRequest::Tag::kB:
        decode_inline_size = ::fidl::internal::WireCodingTraits<bool, fidl::internal::WireCodingConstraintEmpty, IsRecursive>::kInlineSize;
        break;
      default:
        decode_inline_size = 0;
        break;
    }
    DecodeFn<IsRecursive> decode_fn;
    switch(tag) {
      case ::test_protocollayoutssamelibrary::wire::ComposedProtocolTwoWayAnonComposedRequest::Tag::kB:
        decode_fn = ::fidl::internal::MakeDecodeFn<bool, fidl::internal::WireCodingConstraintEmpty, IsRecursive>();
        break;
      default:
        decode_fn = nullptr;
        break;
    }
    ::fidl::internal::WireDecodeStrictEnvelope(decode_inline_size, decode_fn, decoder, position + sizeof(fidl_xunion_tag_t), inner_depth);
  }
};

// Top-level union.
template <bool IsRecursive>
struct ::fidl::internal::WireCodingTraits<::test_protocollayoutssamelibrary::wire::ComposedProtocolTwoWayAnonComposedRequest, ::fidl::internal::WireCodingConstraintEmpty, IsRecursive>
  : public ::fidl::internal::WireCodingTraits<::test_protocollayoutssamelibrary::wire::ComposedProtocolTwoWayAnonComposedRequest, ::fidl::internal::WireCodingConstraintUnion<false>, IsRecursive> {};


template <>
struct TypeTraits<::test_protocollayoutssamelibrary::wire::ComposedProtocolTwoWayAnonComposedWithErrorResponse> {
  static constexpr uint32_t kMaxNumHandles = 0;
  static constexpr uint32_t kMaxDepth = 1;
  static constexpr uint32_t kPrimarySize = 16;
  [[maybe_unused]]
  static constexpr uint32_t kMaxOutOfLine = 0;
  static constexpr bool kHasFlexibleEnvelope = false;
  static constexpr bool kHasPointer = true;
};

template <>
struct IsFidlType<::test_protocollayoutssamelibrary::wire::ComposedProtocolTwoWayAnonComposedWithErrorResponse> : public std::true_type {};
template <>
struct IsWire<::test_protocollayoutssamelibrary::wire::ComposedProtocolTwoWayAnonComposedWithErrorResponse> : public std::true_type {};
template <>
struct IsUnion<::test_protocollayoutssamelibrary::wire::ComposedProtocolTwoWayAnonComposedWithErrorResponse> : public std::true_type {};
static_assert(std::is_standard_layout_v<::test_protocollayoutssamelibrary::wire::ComposedProtocolTwoWayAnonComposedWithErrorResponse>);

template <typename Constraint, bool IsRecursive>
struct ::fidl::internal::WireCodingTraits<::test_protocollayoutssamelibrary::wire::ComposedProtocolTwoWayAnonComposedWithErrorResponse, Constraint, IsRecursive> {
  static constexpr size_t kInlineSize = 16;
  static constexpr bool kIsMemcpyCompatible = false;

  static void Encode(internal::WireEncoder* encoder, ::test_protocollayoutssamelibrary::wire::ComposedProtocolTwoWayAnonComposedWithErrorResponse* value, ::fidl::internal::WirePosition position, RecursionDepth<IsRecursive> recursion_depth) {
    fidl_union_t* u = reinterpret_cast<fidl_union_t*>(value);

    if (unlikely(u->tag == 0)) {
      if constexpr (Constraint::is_optional) {
        *position.As<fidl_union_t>() = {};
        return;
      }
      encoder->SetError(kCodingErrorInvalidUnionTag);
      return;
    }

    RecursionDepth<IsRecursive> inner_depth = recursion_depth.Add(encoder, 1);
    if (!inner_depth.IsValid()) {
      return;
    }

    *position.As<fidl_xunion_tag_t>() = u->tag;

    
    size_t encode_inline_size;
    switch (u->tag) {
      case 1: // ::test_protocollayoutssamelibrary::wire::ComposedProtocolTwoWayAnonComposedWithErrorResponse::Tag::kB
        encode_inline_size = ::fidl::internal::WireCodingTraits<bool, fidl::internal::WireCodingConstraintEmpty, IsRecursive>::kInlineSize;
        break;
      default:
        encode_inline_size = 0;
        break;
    }
    ::fidl::internal::EncodeFn<IsRecursive> encode_fn;
    switch (u->tag) {
      case 1: // ::test_protocollayoutssamelibrary::wire::ComposedProtocolTwoWayAnonComposedWithErrorResponse::Tag::kB
        encode_fn = ::fidl::internal::MakeEncodeFn<bool, fidl::internal::WireCodingConstraintEmpty, IsRecursive>();
        break;
      default:
        encode_fn = nullptr;
        break;
    }
    WireEncodeEnvelope(encode_inline_size, encode_fn, encoder, &u->envelope, position + sizeof(fidl_xunion_tag_t), inner_depth);
  }

  static void Decode(internal::WireDecoder* decoder, ::fidl::internal::WirePosition position, RecursionDepth<IsRecursive> recursion_depth) {
    ::test_protocollayoutssamelibrary::wire::ComposedProtocolTwoWayAnonComposedWithErrorResponse::Tag tag = *position.As<::test_protocollayoutssamelibrary::wire::ComposedProtocolTwoWayAnonComposedWithErrorResponse::Tag>();
    if (unlikely(static_cast<uint64_t>(tag) == 0)) {
      if constexpr (!Constraint::is_optional) {
        decoder->SetError(kCodingErrorInvalidUnionTag);
        return;
      }
      static_assert(sizeof(fidl_envelope_t) == sizeof(uint64_t));
      if (*(position + sizeof(fidl_xunion_tag_t)).As<uint64_t>() != 0) {
        decoder->SetError(kCodingErrorZeroTagButNonZeroEnvelope);
      }
      return;
    }

    RecursionDepth<IsRecursive> inner_depth = recursion_depth.Add(decoder, 1);
    if (!inner_depth.IsValid()) {
      return;
    }

    
    size_t decode_inline_size;
    switch (tag) {
      case ::test_protocollayoutssamelibrary::wire::ComposedProtocolTwoWayAnonComposedWithErrorResponse::Tag::kB:
        decode_inline_size = ::fidl::internal::WireCodingTraits<bool, fidl::internal::WireCodingConstraintEmpty, IsRecursive>::kInlineSize;
        break;
      default:
        decode_inline_size = 0;
        break;
    }
    DecodeFn<IsRecursive> decode_fn;
    switch(tag) {
      case ::test_protocollayoutssamelibrary::wire::ComposedProtocolTwoWayAnonComposedWithErrorResponse::Tag::kB:
        decode_fn = ::fidl::internal::MakeDecodeFn<bool, fidl::internal::WireCodingConstraintEmpty, IsRecursive>();
        break;
      default:
        decode_fn = nullptr;
        break;
    }
    ::fidl::internal::WireDecodeStrictEnvelope(decode_inline_size, decode_fn, decoder, position + sizeof(fidl_xunion_tag_t), inner_depth);
  }
};

// Top-level union.
template <bool IsRecursive>
struct ::fidl::internal::WireCodingTraits<::test_protocollayoutssamelibrary::wire::ComposedProtocolTwoWayAnonComposedWithErrorResponse, ::fidl::internal::WireCodingConstraintEmpty, IsRecursive>
  : public ::fidl::internal::WireCodingTraits<::test_protocollayoutssamelibrary::wire::ComposedProtocolTwoWayAnonComposedWithErrorResponse, ::fidl::internal::WireCodingConstraintUnion<false>, IsRecursive> {};


template <>
struct TypeTraits<::test_protocollayoutssamelibrary::wire::ComposedProtocolTwoWayAnonComposedWithErrorResult> {
  static constexpr uint32_t kMaxNumHandles = 0;
  static constexpr uint32_t kMaxDepth = 2;
  static constexpr uint32_t kPrimarySize = 16;
  [[maybe_unused]]
  static constexpr uint32_t kMaxOutOfLine = 16;
  static constexpr bool kHasFlexibleEnvelope = false;
  static constexpr bool kHasPointer = true;
};

template <>
struct IsFidlType<::test_protocollayoutssamelibrary::wire::ComposedProtocolTwoWayAnonComposedWithErrorResult> : public std::true_type {};
template <>
struct IsWire<::test_protocollayoutssamelibrary::wire::ComposedProtocolTwoWayAnonComposedWithErrorResult> : public std::true_type {};
template <>
struct IsUnion<::test_protocollayoutssamelibrary::wire::ComposedProtocolTwoWayAnonComposedWithErrorResult> : public std::true_type {};
static_assert(std::is_standard_layout_v<::test_protocollayoutssamelibrary::wire::ComposedProtocolTwoWayAnonComposedWithErrorResult>);

template <typename Constraint, bool IsRecursive>
struct ::fidl::internal::WireCodingTraits<::test_protocollayoutssamelibrary::wire::ComposedProtocolTwoWayAnonComposedWithErrorResult, Constraint, IsRecursive> {
  static constexpr size_t kInlineSize = 16;
  static constexpr bool kIsMemcpyCompatible = false;

  static void Encode(internal::WireEncoder* encoder, ::test_protocollayoutssamelibrary::wire::ComposedProtocolTwoWayAnonComposedWithErrorResult* value, ::fidl::internal::WirePosition position, RecursionDepth<IsRecursive> recursion_depth) {
    fidl_union_t* u = reinterpret_cast<fidl_union_t*>(value);

    if (unlikely(u->tag == 0)) {
      if constexpr (Constraint::is_optional) {
        *position.As<fidl_union_t>() = {};
        return;
      }
      encoder->SetError(kCodingErrorInvalidUnionTag);
      return;
    }

    RecursionDepth<IsRecursive> inner_depth = recursion_depth.Add(encoder, 1);
    if (!inner_depth.IsValid()) {
      return;
    }

    *position.As<fidl_xunion_tag_t>() = u->tag;

    
    size_t encode_inline_size;
    switch (u->tag) {
      case 1: // ::test_protocollayoutssamelibrary::wire::ComposedProtocolTwoWayAnonComposedWithErrorResult::Tag::kResponse
        encode_inline_size = ::fidl::internal::WireCodingTraits<::test_protocollayoutssamelibrary::wire::ComposedProtocolTwoWayAnonComposedWithErrorResponse, fidl::internal::WireCodingConstraintUnion<false>, IsRecursive>::kInlineSize;
        break;
      case 2: // ::test_protocollayoutssamelibrary::wire::ComposedProtocolTwoWayAnonComposedWithErrorResult::Tag::kErr
        encode_inline_size = ::fidl::internal::WireCodingTraits<uint32_t, fidl::internal::WireCodingConstraintEmpty, IsRecursive>::kInlineSize;
        break;
      default:
        encode_inline_size = 0;
        break;
    }
    ::fidl::internal::EncodeFn<IsRecursive> encode_fn;
    switch (u->tag) {
      case 1: // ::test_protocollayoutssamelibrary::wire::ComposedProtocolTwoWayAnonComposedWithErrorResult::Tag::kResponse
        encode_fn = ::fidl::internal::MakeEncodeFn<::test_protocollayoutssamelibrary::wire::ComposedProtocolTwoWayAnonComposedWithErrorResponse, fidl::internal::WireCodingConstraintUnion<false>, IsRecursive>();
        break;
      case 2: // ::test_protocollayoutssamelibrary::wire::ComposedProtocolTwoWayAnonComposedWithErrorResult::Tag::kErr
        encode_fn = ::fidl::internal::MakeEncodeFn<uint32_t, fidl::internal::WireCodingConstraintEmpty, IsRecursive>();
        break;
      default:
        encode_fn = nullptr;
        break;
    }
    WireEncodeEnvelope(encode_inline_size, encode_fn, encoder, &u->envelope, position + sizeof(fidl_xunion_tag_t), inner_depth);
  }

  static void Decode(internal::WireDecoder* decoder, ::fidl::internal::WirePosition position, RecursionDepth<IsRecursive> recursion_depth) {
    ::test_protocollayoutssamelibrary::wire::ComposedProtocolTwoWayAnonComposedWithErrorResult::Tag tag = *position.As<::test_protocollayoutssamelibrary::wire::ComposedProtocolTwoWayAnonComposedWithErrorResult::Tag>();
    if (unlikely(static_cast<uint64_t>(tag) == 0)) {
      if constexpr (!Constraint::is_optional) {
        decoder->SetError(kCodingErrorInvalidUnionTag);
        return;
      }
      static_assert(sizeof(fidl_envelope_t) == sizeof(uint64_t));
      if (*(position + sizeof(fidl_xunion_tag_t)).As<uint64_t>() != 0) {
        decoder->SetError(kCodingErrorZeroTagButNonZeroEnvelope);
      }
      return;
    }

    RecursionDepth<IsRecursive> inner_depth = recursion_depth.Add(decoder, 1);
    if (!inner_depth.IsValid()) {
      return;
    }

    
    size_t decode_inline_size;
    switch (tag) {
      case ::test_protocollayoutssamelibrary::wire::ComposedProtocolTwoWayAnonComposedWithErrorResult::Tag::kResponse:
        decode_inline_size = ::fidl::internal::WireCodingTraits<::test_protocollayoutssamelibrary::wire::ComposedProtocolTwoWayAnonComposedWithErrorResponse, fidl::internal::WireCodingConstraintUnion<false>, IsRecursive>::kInlineSize;
        break;
      case ::test_protocollayoutssamelibrary::wire::ComposedProtocolTwoWayAnonComposedWithErrorResult::Tag::kErr:
        decode_inline_size = ::fidl::internal::WireCodingTraits<uint32_t, fidl::internal::WireCodingConstraintEmpty, IsRecursive>::kInlineSize;
        break;
      default:
        decode_inline_size = 0;
        break;
    }
    DecodeFn<IsRecursive> decode_fn;
    switch(tag) {
      case ::test_protocollayoutssamelibrary::wire::ComposedProtocolTwoWayAnonComposedWithErrorResult::Tag::kResponse:
        decode_fn = ::fidl::internal::MakeDecodeFn<::test_protocollayoutssamelibrary::wire::ComposedProtocolTwoWayAnonComposedWithErrorResponse, fidl::internal::WireCodingConstraintUnion<false>, IsRecursive>();
        break;
      case ::test_protocollayoutssamelibrary::wire::ComposedProtocolTwoWayAnonComposedWithErrorResult::Tag::kErr:
        decode_fn = ::fidl::internal::MakeDecodeFn<uint32_t, fidl::internal::WireCodingConstraintEmpty, IsRecursive>();
        break;
      default:
        decode_fn = nullptr;
        break;
    }
    ::fidl::internal::WireDecodeStrictEnvelope(decode_inline_size, decode_fn, decoder, position + sizeof(fidl_xunion_tag_t), inner_depth);
  }
};

// Top-level union.
template <bool IsRecursive>
struct ::fidl::internal::WireCodingTraits<::test_protocollayoutssamelibrary::wire::ComposedProtocolTwoWayAnonComposedWithErrorResult, ::fidl::internal::WireCodingConstraintEmpty, IsRecursive>
  : public ::fidl::internal::WireCodingTraits<::test_protocollayoutssamelibrary::wire::ComposedProtocolTwoWayAnonComposedWithErrorResult, ::fidl::internal::WireCodingConstraintUnion<false>, IsRecursive> {};


template <>
struct TypeTraits<::test_protocollayoutssamelibrary::wire::ComposedProtocolOnAnonComposedRequest> {
  static constexpr uint32_t kMaxNumHandles = 0;
  static constexpr uint32_t kMaxDepth = 1;
  static constexpr uint32_t kPrimarySize = 16;
  [[maybe_unused]]
  static constexpr uint32_t kMaxOutOfLine = 0;
  static constexpr bool kHasFlexibleEnvelope = false;
  static constexpr bool kHasPointer = true;
};

template <>
struct IsFidlType<::test_protocollayoutssamelibrary::wire::ComposedProtocolOnAnonComposedRequest> : public std::true_type {};
template <>
struct IsWire<::test_protocollayoutssamelibrary::wire::ComposedProtocolOnAnonComposedRequest> : public std::true_type {};
template <>
struct IsUnion<::test_protocollayoutssamelibrary::wire::ComposedProtocolOnAnonComposedRequest> : public std::true_type {};
static_assert(std::is_standard_layout_v<::test_protocollayoutssamelibrary::wire::ComposedProtocolOnAnonComposedRequest>);

template <typename Constraint, bool IsRecursive>
struct ::fidl::internal::WireCodingTraits<::test_protocollayoutssamelibrary::wire::ComposedProtocolOnAnonComposedRequest, Constraint, IsRecursive> {
  static constexpr size_t kInlineSize = 16;
  static constexpr bool kIsMemcpyCompatible = false;

  static void Encode(internal::WireEncoder* encoder, ::test_protocollayoutssamelibrary::wire::ComposedProtocolOnAnonComposedRequest* value, ::fidl::internal::WirePosition position, RecursionDepth<IsRecursive> recursion_depth) {
    fidl_union_t* u = reinterpret_cast<fidl_union_t*>(value);

    if (unlikely(u->tag == 0)) {
      if constexpr (Constraint::is_optional) {
        *position.As<fidl_union_t>() = {};
        return;
      }
      encoder->SetError(kCodingErrorInvalidUnionTag);
      return;
    }

    RecursionDepth<IsRecursive> inner_depth = recursion_depth.Add(encoder, 1);
    if (!inner_depth.IsValid()) {
      return;
    }

    *position.As<fidl_xunion_tag_t>() = u->tag;

    
    size_t encode_inline_size;
    switch (u->tag) {
      case 1: // ::test_protocollayoutssamelibrary::wire::ComposedProtocolOnAnonComposedRequest::Tag::kB
        encode_inline_size = ::fidl::internal::WireCodingTraits<bool, fidl::internal::WireCodingConstraintEmpty, IsRecursive>::kInlineSize;
        break;
      default:
        encode_inline_size = 0;
        break;
    }
    ::fidl::internal::EncodeFn<IsRecursive> encode_fn;
    switch (u->tag) {
      case 1: // ::test_protocollayoutssamelibrary::wire::ComposedProtocolOnAnonComposedRequest::Tag::kB
        encode_fn = ::fidl::internal::MakeEncodeFn<bool, fidl::internal::WireCodingConstraintEmpty, IsRecursive>();
        break;
      default:
        encode_fn = nullptr;
        break;
    }
    WireEncodeEnvelope(encode_inline_size, encode_fn, encoder, &u->envelope, position + sizeof(fidl_xunion_tag_t), inner_depth);
  }

  static void Decode(internal::WireDecoder* decoder, ::fidl::internal::WirePosition position, RecursionDepth<IsRecursive> recursion_depth) {
    ::test_protocollayoutssamelibrary::wire::ComposedProtocolOnAnonComposedRequest::Tag tag = *position.As<::test_protocollayoutssamelibrary::wire::ComposedProtocolOnAnonComposedRequest::Tag>();
    if (unlikely(static_cast<uint64_t>(tag) == 0)) {
      if constexpr (!Constraint::is_optional) {
        decoder->SetError(kCodingErrorInvalidUnionTag);
        return;
      }
      static_assert(sizeof(fidl_envelope_t) == sizeof(uint64_t));
      if (*(position + sizeof(fidl_xunion_tag_t)).As<uint64_t>() != 0) {
        decoder->SetError(kCodingErrorZeroTagButNonZeroEnvelope);
      }
      return;
    }

    RecursionDepth<IsRecursive> inner_depth = recursion_depth.Add(decoder, 1);
    if (!inner_depth.IsValid()) {
      return;
    }

    
    size_t decode_inline_size;
    switch (tag) {
      case ::test_protocollayoutssamelibrary::wire::ComposedProtocolOnAnonComposedRequest::Tag::kB:
        decode_inline_size = ::fidl::internal::WireCodingTraits<bool, fidl::internal::WireCodingConstraintEmpty, IsRecursive>::kInlineSize;
        break;
      default:
        decode_inline_size = 0;
        break;
    }
    DecodeFn<IsRecursive> decode_fn;
    switch(tag) {
      case ::test_protocollayoutssamelibrary::wire::ComposedProtocolOnAnonComposedRequest::Tag::kB:
        decode_fn = ::fidl::internal::MakeDecodeFn<bool, fidl::internal::WireCodingConstraintEmpty, IsRecursive>();
        break;
      default:
        decode_fn = nullptr;
        break;
    }
    ::fidl::internal::WireDecodeStrictEnvelope(decode_inline_size, decode_fn, decoder, position + sizeof(fidl_xunion_tag_t), inner_depth);
  }
};

// Top-level union.
template <bool IsRecursive>
struct ::fidl::internal::WireCodingTraits<::test_protocollayoutssamelibrary::wire::ComposedProtocolOnAnonComposedRequest, ::fidl::internal::WireCodingConstraintEmpty, IsRecursive>
  : public ::fidl::internal::WireCodingTraits<::test_protocollayoutssamelibrary::wire::ComposedProtocolOnAnonComposedRequest, ::fidl::internal::WireCodingConstraintUnion<false>, IsRecursive> {};


template <>
struct TypeTraits<::test_protocollayoutssamelibrary::wire::ComposedProtocolTwoWayNamedComposedWithErrorResult> {
  static constexpr uint32_t kMaxNumHandles = 0;
  static constexpr uint32_t kMaxDepth = 2;
  static constexpr uint32_t kPrimarySize = 16;
  [[maybe_unused]]
  static constexpr uint32_t kMaxOutOfLine = 16;
  static constexpr bool kHasFlexibleEnvelope = false;
  static constexpr bool kHasPointer = true;
};

template <>
struct IsFidlType<::test_protocollayoutssamelibrary::wire::ComposedProtocolTwoWayNamedComposedWithErrorResult> : public std::true_type {};
template <>
struct IsWire<::test_protocollayoutssamelibrary::wire::ComposedProtocolTwoWayNamedComposedWithErrorResult> : public std::true_type {};
template <>
struct IsUnion<::test_protocollayoutssamelibrary::wire::ComposedProtocolTwoWayNamedComposedWithErrorResult> : public std::true_type {};
static_assert(std::is_standard_layout_v<::test_protocollayoutssamelibrary::wire::ComposedProtocolTwoWayNamedComposedWithErrorResult>);

template <typename Constraint, bool IsRecursive>
struct ::fidl::internal::WireCodingTraits<::test_protocollayoutssamelibrary::wire::ComposedProtocolTwoWayNamedComposedWithErrorResult, Constraint, IsRecursive> {
  static constexpr size_t kInlineSize = 16;
  static constexpr bool kIsMemcpyCompatible = false;

  static void Encode(internal::WireEncoder* encoder, ::test_protocollayoutssamelibrary::wire::ComposedProtocolTwoWayNamedComposedWithErrorResult* value, ::fidl::internal::WirePosition position, RecursionDepth<IsRecursive> recursion_depth) {
    fidl_union_t* u = reinterpret_cast<fidl_union_t*>(value);

    if (unlikely(u->tag == 0)) {
      if constexpr (Constraint::is_optional) {
        *position.As<fidl_union_t>() = {};
        return;
      }
      encoder->SetError(kCodingErrorInvalidUnionTag);
      return;
    }

    RecursionDepth<IsRecursive> inner_depth = recursion_depth.Add(encoder, 1);
    if (!inner_depth.IsValid()) {
      return;
    }

    *position.As<fidl_xunion_tag_t>() = u->tag;

    
    size_t encode_inline_size;
    switch (u->tag) {
      case 1: // ::test_protocollayoutssamelibrary::wire::ComposedProtocolTwoWayNamedComposedWithErrorResult::Tag::kResponse
        encode_inline_size = ::fidl::internal::WireCodingTraits<::test_protocollayoutssamelibrary::wire::UnionPayload, fidl::internal::WireCodingConstraintUnion<false>, IsRecursive>::kInlineSize;
        break;
      case 2: // ::test_protocollayoutssamelibrary::wire::ComposedProtocolTwoWayNamedComposedWithErrorResult::Tag::kErr
        encode_inline_size = ::fidl::internal::WireCodingTraits<uint32_t, fidl::internal::WireCodingConstraintEmpty, IsRecursive>::kInlineSize;
        break;
      default:
        encode_inline_size = 0;
        break;
    }
    ::fidl::internal::EncodeFn<IsRecursive> encode_fn;
    switch (u->tag) {
      case 1: // ::test_protocollayoutssamelibrary::wire::ComposedProtocolTwoWayNamedComposedWithErrorResult::Tag::kResponse
        encode_fn = ::fidl::internal::MakeEncodeFn<::test_protocollayoutssamelibrary::wire::UnionPayload, fidl::internal::WireCodingConstraintUnion<false>, IsRecursive>();
        break;
      case 2: // ::test_protocollayoutssamelibrary::wire::ComposedProtocolTwoWayNamedComposedWithErrorResult::Tag::kErr
        encode_fn = ::fidl::internal::MakeEncodeFn<uint32_t, fidl::internal::WireCodingConstraintEmpty, IsRecursive>();
        break;
      default:
        encode_fn = nullptr;
        break;
    }
    WireEncodeEnvelope(encode_inline_size, encode_fn, encoder, &u->envelope, position + sizeof(fidl_xunion_tag_t), inner_depth);
  }

  static void Decode(internal::WireDecoder* decoder, ::fidl::internal::WirePosition position, RecursionDepth<IsRecursive> recursion_depth) {
    ::test_protocollayoutssamelibrary::wire::ComposedProtocolTwoWayNamedComposedWithErrorResult::Tag tag = *position.As<::test_protocollayoutssamelibrary::wire::ComposedProtocolTwoWayNamedComposedWithErrorResult::Tag>();
    if (unlikely(static_cast<uint64_t>(tag) == 0)) {
      if constexpr (!Constraint::is_optional) {
        decoder->SetError(kCodingErrorInvalidUnionTag);
        return;
      }
      static_assert(sizeof(fidl_envelope_t) == sizeof(uint64_t));
      if (*(position + sizeof(fidl_xunion_tag_t)).As<uint64_t>() != 0) {
        decoder->SetError(kCodingErrorZeroTagButNonZeroEnvelope);
      }
      return;
    }

    RecursionDepth<IsRecursive> inner_depth = recursion_depth.Add(decoder, 1);
    if (!inner_depth.IsValid()) {
      return;
    }

    
    size_t decode_inline_size;
    switch (tag) {
      case ::test_protocollayoutssamelibrary::wire::ComposedProtocolTwoWayNamedComposedWithErrorResult::Tag::kResponse:
        decode_inline_size = ::fidl::internal::WireCodingTraits<::test_protocollayoutssamelibrary::wire::UnionPayload, fidl::internal::WireCodingConstraintUnion<false>, IsRecursive>::kInlineSize;
        break;
      case ::test_protocollayoutssamelibrary::wire::ComposedProtocolTwoWayNamedComposedWithErrorResult::Tag::kErr:
        decode_inline_size = ::fidl::internal::WireCodingTraits<uint32_t, fidl::internal::WireCodingConstraintEmpty, IsRecursive>::kInlineSize;
        break;
      default:
        decode_inline_size = 0;
        break;
    }
    DecodeFn<IsRecursive> decode_fn;
    switch(tag) {
      case ::test_protocollayoutssamelibrary::wire::ComposedProtocolTwoWayNamedComposedWithErrorResult::Tag::kResponse:
        decode_fn = ::fidl::internal::MakeDecodeFn<::test_protocollayoutssamelibrary::wire::UnionPayload, fidl::internal::WireCodingConstraintUnion<false>, IsRecursive>();
        break;
      case ::test_protocollayoutssamelibrary::wire::ComposedProtocolTwoWayNamedComposedWithErrorResult::Tag::kErr:
        decode_fn = ::fidl::internal::MakeDecodeFn<uint32_t, fidl::internal::WireCodingConstraintEmpty, IsRecursive>();
        break;
      default:
        decode_fn = nullptr;
        break;
    }
    ::fidl::internal::WireDecodeStrictEnvelope(decode_inline_size, decode_fn, decoder, position + sizeof(fidl_xunion_tag_t), inner_depth);
  }
};

// Top-level union.
template <bool IsRecursive>
struct ::fidl::internal::WireCodingTraits<::test_protocollayoutssamelibrary::wire::ComposedProtocolTwoWayNamedComposedWithErrorResult, ::fidl::internal::WireCodingConstraintEmpty, IsRecursive>
  : public ::fidl::internal::WireCodingTraits<::test_protocollayoutssamelibrary::wire::ComposedProtocolTwoWayNamedComposedWithErrorResult, ::fidl::internal::WireCodingConstraintUnion<false>, IsRecursive> {};


template <>
struct TypeTraits<::test_protocollayoutssamelibrary::wire::MainProtocolTwoWayLocalWithErrorResult> {
  static constexpr uint32_t kMaxNumHandles = 0;
  static constexpr uint32_t kMaxDepth = 2;
  static constexpr uint32_t kPrimarySize = 16;
  [[maybe_unused]]
  static constexpr uint32_t kMaxOutOfLine = 16;
  static constexpr bool kHasFlexibleEnvelope = false;
  static constexpr bool kHasPointer = true;
};

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

template <typename Constraint, bool IsRecursive>
struct ::fidl::internal::WireCodingTraits<::test_protocollayoutssamelibrary::wire::MainProtocolTwoWayLocalWithErrorResult, Constraint, IsRecursive> {
  static constexpr size_t kInlineSize = 16;
  static constexpr bool kIsMemcpyCompatible = false;

  static void Encode(internal::WireEncoder* encoder, ::test_protocollayoutssamelibrary::wire::MainProtocolTwoWayLocalWithErrorResult* value, ::fidl::internal::WirePosition position, RecursionDepth<IsRecursive> recursion_depth) {
    fidl_union_t* u = reinterpret_cast<fidl_union_t*>(value);

    if (unlikely(u->tag == 0)) {
      if constexpr (Constraint::is_optional) {
        *position.As<fidl_union_t>() = {};
        return;
      }
      encoder->SetError(kCodingErrorInvalidUnionTag);
      return;
    }

    RecursionDepth<IsRecursive> inner_depth = recursion_depth.Add(encoder, 1);
    if (!inner_depth.IsValid()) {
      return;
    }

    *position.As<fidl_xunion_tag_t>() = u->tag;

    
    size_t encode_inline_size;
    switch (u->tag) {
      case 1: // ::test_protocollayoutssamelibrary::wire::MainProtocolTwoWayLocalWithErrorResult::Tag::kResponse
        encode_inline_size = ::fidl::internal::WireCodingTraits<::test_protocollayoutssamelibrary::wire::UnionPayload, fidl::internal::WireCodingConstraintUnion<false>, IsRecursive>::kInlineSize;
        break;
      case 2: // ::test_protocollayoutssamelibrary::wire::MainProtocolTwoWayLocalWithErrorResult::Tag::kErr
        encode_inline_size = ::fidl::internal::WireCodingTraits<uint32_t, fidl::internal::WireCodingConstraintEmpty, IsRecursive>::kInlineSize;
        break;
      default:
        encode_inline_size = 0;
        break;
    }
    ::fidl::internal::EncodeFn<IsRecursive> encode_fn;
    switch (u->tag) {
      case 1: // ::test_protocollayoutssamelibrary::wire::MainProtocolTwoWayLocalWithErrorResult::Tag::kResponse
        encode_fn = ::fidl::internal::MakeEncodeFn<::test_protocollayoutssamelibrary::wire::UnionPayload, fidl::internal::WireCodingConstraintUnion<false>, IsRecursive>();
        break;
      case 2: // ::test_protocollayoutssamelibrary::wire::MainProtocolTwoWayLocalWithErrorResult::Tag::kErr
        encode_fn = ::fidl::internal::MakeEncodeFn<uint32_t, fidl::internal::WireCodingConstraintEmpty, IsRecursive>();
        break;
      default:
        encode_fn = nullptr;
        break;
    }
    WireEncodeEnvelope(encode_inline_size, encode_fn, encoder, &u->envelope, position + sizeof(fidl_xunion_tag_t), inner_depth);
  }

  static void Decode(internal::WireDecoder* decoder, ::fidl::internal::WirePosition position, RecursionDepth<IsRecursive> recursion_depth) {
    ::test_protocollayoutssamelibrary::wire::MainProtocolTwoWayLocalWithErrorResult::Tag tag = *position.As<::test_protocollayoutssamelibrary::wire::MainProtocolTwoWayLocalWithErrorResult::Tag>();
    if (unlikely(static_cast<uint64_t>(tag) == 0)) {
      if constexpr (!Constraint::is_optional) {
        decoder->SetError(kCodingErrorInvalidUnionTag);
        return;
      }
      static_assert(sizeof(fidl_envelope_t) == sizeof(uint64_t));
      if (*(position + sizeof(fidl_xunion_tag_t)).As<uint64_t>() != 0) {
        decoder->SetError(kCodingErrorZeroTagButNonZeroEnvelope);
      }
      return;
    }

    RecursionDepth<IsRecursive> inner_depth = recursion_depth.Add(decoder, 1);
    if (!inner_depth.IsValid()) {
      return;
    }

    
    size_t decode_inline_size;
    switch (tag) {
      case ::test_protocollayoutssamelibrary::wire::MainProtocolTwoWayLocalWithErrorResult::Tag::kResponse:
        decode_inline_size = ::fidl::internal::WireCodingTraits<::test_protocollayoutssamelibrary::wire::UnionPayload, fidl::internal::WireCodingConstraintUnion<false>, IsRecursive>::kInlineSize;
        break;
      case ::test_protocollayoutssamelibrary::wire::MainProtocolTwoWayLocalWithErrorResult::Tag::kErr:
        decode_inline_size = ::fidl::internal::WireCodingTraits<uint32_t, fidl::internal::WireCodingConstraintEmpty, IsRecursive>::kInlineSize;
        break;
      default:
        decode_inline_size = 0;
        break;
    }
    DecodeFn<IsRecursive> decode_fn;
    switch(tag) {
      case ::test_protocollayoutssamelibrary::wire::MainProtocolTwoWayLocalWithErrorResult::Tag::kResponse:
        decode_fn = ::fidl::internal::MakeDecodeFn<::test_protocollayoutssamelibrary::wire::UnionPayload, fidl::internal::WireCodingConstraintUnion<false>, IsRecursive>();
        break;
      case ::test_protocollayoutssamelibrary::wire::MainProtocolTwoWayLocalWithErrorResult::Tag::kErr:
        decode_fn = ::fidl::internal::MakeDecodeFn<uint32_t, fidl::internal::WireCodingConstraintEmpty, IsRecursive>();
        break;
      default:
        decode_fn = nullptr;
        break;
    }
    ::fidl::internal::WireDecodeStrictEnvelope(decode_inline_size, decode_fn, decoder, position + sizeof(fidl_xunion_tag_t), inner_depth);
  }
};

// Top-level union.
template <bool IsRecursive>
struct ::fidl::internal::WireCodingTraits<::test_protocollayoutssamelibrary::wire::MainProtocolTwoWayLocalWithErrorResult, ::fidl::internal::WireCodingConstraintEmpty, IsRecursive>
  : public ::fidl::internal::WireCodingTraits<::test_protocollayoutssamelibrary::wire::MainProtocolTwoWayLocalWithErrorResult, ::fidl::internal::WireCodingConstraintUnion<false>, IsRecursive> {};


template <>
struct TypeTraits<::test_protocollayoutssamelibrary::wire::MainProtocolTwoWayAnonRequest> {
  static constexpr uint32_t kMaxNumHandles = 0;
  static constexpr uint32_t kMaxDepth = 1;
  static constexpr uint32_t kPrimarySize = 16;
  [[maybe_unused]]
  static constexpr uint32_t kMaxOutOfLine = 0;
  static constexpr bool kHasFlexibleEnvelope = true;
  static constexpr bool kHasPointer = true;
};

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

template <typename Constraint, bool IsRecursive>
struct ::fidl::internal::WireCodingTraits<::test_protocollayoutssamelibrary::wire::MainProtocolTwoWayAnonRequest, Constraint, IsRecursive> {
  static constexpr size_t kInlineSize = 16;
  static constexpr bool kIsMemcpyCompatible = false;

  static void Encode(internal::WireEncoder* encoder, ::test_protocollayoutssamelibrary::wire::MainProtocolTwoWayAnonRequest* value, ::fidl::internal::WirePosition position, RecursionDepth<IsRecursive> recursion_depth) {
    fidl_union_t* u = reinterpret_cast<fidl_union_t*>(value);

    if (unlikely(u->tag == 0)) {
      if constexpr (Constraint::is_optional) {
        *position.As<fidl_union_t>() = {};
        return;
      }
      encoder->SetError(kCodingErrorInvalidUnionTag);
      return;
    }

    RecursionDepth<IsRecursive> inner_depth = recursion_depth.Add(encoder, 1);
    if (!inner_depth.IsValid()) {
      return;
    }

    *position.As<fidl_xunion_tag_t>() = u->tag;

    
    size_t encode_inline_size;
    switch (u->tag) {
      case 1: // ::test_protocollayoutssamelibrary::wire::MainProtocolTwoWayAnonRequest::Tag::kB
        encode_inline_size = ::fidl::internal::WireCodingTraits<bool, fidl::internal::WireCodingConstraintEmpty, IsRecursive>::kInlineSize;
        break;
      default:
        encode_inline_size = 0;
        break;
    }
    ::fidl::internal::EncodeFn<IsRecursive> encode_fn;
    switch (u->tag) {
      case 1: // ::test_protocollayoutssamelibrary::wire::MainProtocolTwoWayAnonRequest::Tag::kB
        encode_fn = ::fidl::internal::MakeEncodeFn<bool, fidl::internal::WireCodingConstraintEmpty, IsRecursive>();
        break;
      default:
        encode_fn = nullptr;
        break;
    }
    WireEncodeEnvelope(encode_inline_size, encode_fn, encoder, &u->envelope, position + sizeof(fidl_xunion_tag_t), inner_depth);
  }

  static void Decode(internal::WireDecoder* decoder, ::fidl::internal::WirePosition position, RecursionDepth<IsRecursive> recursion_depth) {
    ::test_protocollayoutssamelibrary::wire::MainProtocolTwoWayAnonRequest::Tag tag = *position.As<::test_protocollayoutssamelibrary::wire::MainProtocolTwoWayAnonRequest::Tag>();
    if (unlikely(static_cast<uint64_t>(tag) == 0)) {
      if constexpr (!Constraint::is_optional) {
        decoder->SetError(kCodingErrorInvalidUnionTag);
        return;
      }
      static_assert(sizeof(fidl_envelope_t) == sizeof(uint64_t));
      if (*(position + sizeof(fidl_xunion_tag_t)).As<uint64_t>() != 0) {
        decoder->SetError(kCodingErrorZeroTagButNonZeroEnvelope);
      }
      return;
    }

    RecursionDepth<IsRecursive> inner_depth = recursion_depth.Add(decoder, 1);
    if (!inner_depth.IsValid()) {
      return;
    }

    
    size_t decode_inline_size;
    switch (tag) {
      case ::test_protocollayoutssamelibrary::wire::MainProtocolTwoWayAnonRequest::Tag::kB:
        decode_inline_size = ::fidl::internal::WireCodingTraits<bool, fidl::internal::WireCodingConstraintEmpty, IsRecursive>::kInlineSize;
        break;
      default:
        decode_inline_size = 0;
        break;
    }
    DecodeFn<IsRecursive> decode_fn;
    switch(tag) {
      case ::test_protocollayoutssamelibrary::wire::MainProtocolTwoWayAnonRequest::Tag::kB:
        decode_fn = ::fidl::internal::MakeDecodeFn<bool, fidl::internal::WireCodingConstraintEmpty, IsRecursive>();
        break;
      default:
        decode_fn = nullptr;
        break;
    }
    ::fidl::internal::WireDecodeFlexibleEnvelope(decode_inline_size, decode_fn, decoder, position + sizeof(fidl_xunion_tag_t), inner_depth);
  }
};

// Top-level union.
template <bool IsRecursive>
struct ::fidl::internal::WireCodingTraits<::test_protocollayoutssamelibrary::wire::MainProtocolTwoWayAnonRequest, ::fidl::internal::WireCodingConstraintEmpty, IsRecursive>
  : public ::fidl::internal::WireCodingTraits<::test_protocollayoutssamelibrary::wire::MainProtocolTwoWayAnonRequest, ::fidl::internal::WireCodingConstraintUnion<false>, IsRecursive> {};


template <>
struct TypeTraits<::test_protocollayoutssamelibrary::wire::MainProtocolTwoWayAnonWithErrorResponse> {
  static constexpr uint32_t kMaxNumHandles = 0;
  static constexpr uint32_t kMaxDepth = 1;
  static constexpr uint32_t kPrimarySize = 16;
  [[maybe_unused]]
  static constexpr uint32_t kMaxOutOfLine = 0;
  static constexpr bool kHasFlexibleEnvelope = true;
  static constexpr bool kHasPointer = true;
};

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

template <typename Constraint, bool IsRecursive>
struct ::fidl::internal::WireCodingTraits<::test_protocollayoutssamelibrary::wire::MainProtocolTwoWayAnonWithErrorResponse, Constraint, IsRecursive> {
  static constexpr size_t kInlineSize = 16;
  static constexpr bool kIsMemcpyCompatible = false;

  static void Encode(internal::WireEncoder* encoder, ::test_protocollayoutssamelibrary::wire::MainProtocolTwoWayAnonWithErrorResponse* value, ::fidl::internal::WirePosition position, RecursionDepth<IsRecursive> recursion_depth) {
    fidl_union_t* u = reinterpret_cast<fidl_union_t*>(value);

    if (unlikely(u->tag == 0)) {
      if constexpr (Constraint::is_optional) {
        *position.As<fidl_union_t>() = {};
        return;
      }
      encoder->SetError(kCodingErrorInvalidUnionTag);
      return;
    }

    RecursionDepth<IsRecursive> inner_depth = recursion_depth.Add(encoder, 1);
    if (!inner_depth.IsValid()) {
      return;
    }

    *position.As<fidl_xunion_tag_t>() = u->tag;

    
    size_t encode_inline_size;
    switch (u->tag) {
      case 1: // ::test_protocollayoutssamelibrary::wire::MainProtocolTwoWayAnonWithErrorResponse::Tag::kB
        encode_inline_size = ::fidl::internal::WireCodingTraits<bool, fidl::internal::WireCodingConstraintEmpty, IsRecursive>::kInlineSize;
        break;
      default:
        encode_inline_size = 0;
        break;
    }
    ::fidl::internal::EncodeFn<IsRecursive> encode_fn;
    switch (u->tag) {
      case 1: // ::test_protocollayoutssamelibrary::wire::MainProtocolTwoWayAnonWithErrorResponse::Tag::kB
        encode_fn = ::fidl::internal::MakeEncodeFn<bool, fidl::internal::WireCodingConstraintEmpty, IsRecursive>();
        break;
      default:
        encode_fn = nullptr;
        break;
    }
    WireEncodeEnvelope(encode_inline_size, encode_fn, encoder, &u->envelope, position + sizeof(fidl_xunion_tag_t), inner_depth);
  }

  static void Decode(internal::WireDecoder* decoder, ::fidl::internal::WirePosition position, RecursionDepth<IsRecursive> recursion_depth) {
    ::test_protocollayoutssamelibrary::wire::MainProtocolTwoWayAnonWithErrorResponse::Tag tag = *position.As<::test_protocollayoutssamelibrary::wire::MainProtocolTwoWayAnonWithErrorResponse::Tag>();
    if (unlikely(static_cast<uint64_t>(tag) == 0)) {
      if constexpr (!Constraint::is_optional) {
        decoder->SetError(kCodingErrorInvalidUnionTag);
        return;
      }
      static_assert(sizeof(fidl_envelope_t) == sizeof(uint64_t));
      if (*(position + sizeof(fidl_xunion_tag_t)).As<uint64_t>() != 0) {
        decoder->SetError(kCodingErrorZeroTagButNonZeroEnvelope);
      }
      return;
    }

    RecursionDepth<IsRecursive> inner_depth = recursion_depth.Add(decoder, 1);
    if (!inner_depth.IsValid()) {
      return;
    }

    
    size_t decode_inline_size;
    switch (tag) {
      case ::test_protocollayoutssamelibrary::wire::MainProtocolTwoWayAnonWithErrorResponse::Tag::kB:
        decode_inline_size = ::fidl::internal::WireCodingTraits<bool, fidl::internal::WireCodingConstraintEmpty, IsRecursive>::kInlineSize;
        break;
      default:
        decode_inline_size = 0;
        break;
    }
    DecodeFn<IsRecursive> decode_fn;
    switch(tag) {
      case ::test_protocollayoutssamelibrary::wire::MainProtocolTwoWayAnonWithErrorResponse::Tag::kB:
        decode_fn = ::fidl::internal::MakeDecodeFn<bool, fidl::internal::WireCodingConstraintEmpty, IsRecursive>();
        break;
      default:
        decode_fn = nullptr;
        break;
    }
    ::fidl::internal::WireDecodeFlexibleEnvelope(decode_inline_size, decode_fn, decoder, position + sizeof(fidl_xunion_tag_t), inner_depth);
  }
};

// Top-level union.
template <bool IsRecursive>
struct ::fidl::internal::WireCodingTraits<::test_protocollayoutssamelibrary::wire::MainProtocolTwoWayAnonWithErrorResponse, ::fidl::internal::WireCodingConstraintEmpty, IsRecursive>
  : public ::fidl::internal::WireCodingTraits<::test_protocollayoutssamelibrary::wire::MainProtocolTwoWayAnonWithErrorResponse, ::fidl::internal::WireCodingConstraintUnion<false>, IsRecursive> {};


template <>
struct TypeTraits<::test_protocollayoutssamelibrary::wire::MainProtocolTwoWayAnonWithErrorResult> {
  static constexpr uint32_t kMaxNumHandles = 0;
  static constexpr uint32_t kMaxDepth = 2;
  static constexpr uint32_t kPrimarySize = 16;
  [[maybe_unused]]
  static constexpr uint32_t kMaxOutOfLine = 16;
  static constexpr bool kHasFlexibleEnvelope = true;
  static constexpr bool kHasPointer = true;
};

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

template <typename Constraint, bool IsRecursive>
struct ::fidl::internal::WireCodingTraits<::test_protocollayoutssamelibrary::wire::MainProtocolTwoWayAnonWithErrorResult, Constraint, IsRecursive> {
  static constexpr size_t kInlineSize = 16;
  static constexpr bool kIsMemcpyCompatible = false;

  static void Encode(internal::WireEncoder* encoder, ::test_protocollayoutssamelibrary::wire::MainProtocolTwoWayAnonWithErrorResult* value, ::fidl::internal::WirePosition position, RecursionDepth<IsRecursive> recursion_depth) {
    fidl_union_t* u = reinterpret_cast<fidl_union_t*>(value);

    if (unlikely(u->tag == 0)) {
      if constexpr (Constraint::is_optional) {
        *position.As<fidl_union_t>() = {};
        return;
      }
      encoder->SetError(kCodingErrorInvalidUnionTag);
      return;
    }

    RecursionDepth<IsRecursive> inner_depth = recursion_depth.Add(encoder, 1);
    if (!inner_depth.IsValid()) {
      return;
    }

    *position.As<fidl_xunion_tag_t>() = u->tag;

    
    size_t encode_inline_size;
    switch (u->tag) {
      case 1: // ::test_protocollayoutssamelibrary::wire::MainProtocolTwoWayAnonWithErrorResult::Tag::kResponse
        encode_inline_size = ::fidl::internal::WireCodingTraits<::test_protocollayoutssamelibrary::wire::MainProtocolTwoWayAnonWithErrorResponse, fidl::internal::WireCodingConstraintUnion<false>, IsRecursive>::kInlineSize;
        break;
      case 2: // ::test_protocollayoutssamelibrary::wire::MainProtocolTwoWayAnonWithErrorResult::Tag::kErr
        encode_inline_size = ::fidl::internal::WireCodingTraits<uint32_t, fidl::internal::WireCodingConstraintEmpty, IsRecursive>::kInlineSize;
        break;
      default:
        encode_inline_size = 0;
        break;
    }
    ::fidl::internal::EncodeFn<IsRecursive> encode_fn;
    switch (u->tag) {
      case 1: // ::test_protocollayoutssamelibrary::wire::MainProtocolTwoWayAnonWithErrorResult::Tag::kResponse
        encode_fn = ::fidl::internal::MakeEncodeFn<::test_protocollayoutssamelibrary::wire::MainProtocolTwoWayAnonWithErrorResponse, fidl::internal::WireCodingConstraintUnion<false>, IsRecursive>();
        break;
      case 2: // ::test_protocollayoutssamelibrary::wire::MainProtocolTwoWayAnonWithErrorResult::Tag::kErr
        encode_fn = ::fidl::internal::MakeEncodeFn<uint32_t, fidl::internal::WireCodingConstraintEmpty, IsRecursive>();
        break;
      default:
        encode_fn = nullptr;
        break;
    }
    WireEncodeEnvelope(encode_inline_size, encode_fn, encoder, &u->envelope, position + sizeof(fidl_xunion_tag_t), inner_depth);
  }

  static void Decode(internal::WireDecoder* decoder, ::fidl::internal::WirePosition position, RecursionDepth<IsRecursive> recursion_depth) {
    ::test_protocollayoutssamelibrary::wire::MainProtocolTwoWayAnonWithErrorResult::Tag tag = *position.As<::test_protocollayoutssamelibrary::wire::MainProtocolTwoWayAnonWithErrorResult::Tag>();
    if (unlikely(static_cast<uint64_t>(tag) == 0)) {
      if constexpr (!Constraint::is_optional) {
        decoder->SetError(kCodingErrorInvalidUnionTag);
        return;
      }
      static_assert(sizeof(fidl_envelope_t) == sizeof(uint64_t));
      if (*(position + sizeof(fidl_xunion_tag_t)).As<uint64_t>() != 0) {
        decoder->SetError(kCodingErrorZeroTagButNonZeroEnvelope);
      }
      return;
    }

    RecursionDepth<IsRecursive> inner_depth = recursion_depth.Add(decoder, 1);
    if (!inner_depth.IsValid()) {
      return;
    }

    
    size_t decode_inline_size;
    switch (tag) {
      case ::test_protocollayoutssamelibrary::wire::MainProtocolTwoWayAnonWithErrorResult::Tag::kResponse:
        decode_inline_size = ::fidl::internal::WireCodingTraits<::test_protocollayoutssamelibrary::wire::MainProtocolTwoWayAnonWithErrorResponse, fidl::internal::WireCodingConstraintUnion<false>, IsRecursive>::kInlineSize;
        break;
      case ::test_protocollayoutssamelibrary::wire::MainProtocolTwoWayAnonWithErrorResult::Tag::kErr:
        decode_inline_size = ::fidl::internal::WireCodingTraits<uint32_t, fidl::internal::WireCodingConstraintEmpty, IsRecursive>::kInlineSize;
        break;
      default:
        decode_inline_size = 0;
        break;
    }
    DecodeFn<IsRecursive> decode_fn;
    switch(tag) {
      case ::test_protocollayoutssamelibrary::wire::MainProtocolTwoWayAnonWithErrorResult::Tag::kResponse:
        decode_fn = ::fidl::internal::MakeDecodeFn<::test_protocollayoutssamelibrary::wire::MainProtocolTwoWayAnonWithErrorResponse, fidl::internal::WireCodingConstraintUnion<false>, IsRecursive>();
        break;
      case ::test_protocollayoutssamelibrary::wire::MainProtocolTwoWayAnonWithErrorResult::Tag::kErr:
        decode_fn = ::fidl::internal::MakeDecodeFn<uint32_t, fidl::internal::WireCodingConstraintEmpty, IsRecursive>();
        break;
      default:
        decode_fn = nullptr;
        break;
    }
    ::fidl::internal::WireDecodeStrictEnvelope(decode_inline_size, decode_fn, decoder, position + sizeof(fidl_xunion_tag_t), inner_depth);
  }
};

// Top-level union.
template <bool IsRecursive>
struct ::fidl::internal::WireCodingTraits<::test_protocollayoutssamelibrary::wire::MainProtocolTwoWayAnonWithErrorResult, ::fidl::internal::WireCodingConstraintEmpty, IsRecursive>
  : public ::fidl::internal::WireCodingTraits<::test_protocollayoutssamelibrary::wire::MainProtocolTwoWayAnonWithErrorResult, ::fidl::internal::WireCodingConstraintUnion<false>, IsRecursive> {};


template <>
struct TypeTraits<::test_protocollayoutssamelibrary::wire::MainProtocolOnAnonRequest> {
  static constexpr uint32_t kMaxNumHandles = 0;
  static constexpr uint32_t kMaxDepth = 1;
  static constexpr uint32_t kPrimarySize = 16;
  [[maybe_unused]]
  static constexpr uint32_t kMaxOutOfLine = 0;
  static constexpr bool kHasFlexibleEnvelope = true;
  static constexpr bool kHasPointer = true;
};

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

template <typename Constraint, bool IsRecursive>
struct ::fidl::internal::WireCodingTraits<::test_protocollayoutssamelibrary::wire::MainProtocolOnAnonRequest, Constraint, IsRecursive> {
  static constexpr size_t kInlineSize = 16;
  static constexpr bool kIsMemcpyCompatible = false;

  static void Encode(internal::WireEncoder* encoder, ::test_protocollayoutssamelibrary::wire::MainProtocolOnAnonRequest* value, ::fidl::internal::WirePosition position, RecursionDepth<IsRecursive> recursion_depth) {
    fidl_union_t* u = reinterpret_cast<fidl_union_t*>(value);

    if (unlikely(u->tag == 0)) {
      if constexpr (Constraint::is_optional) {
        *position.As<fidl_union_t>() = {};
        return;
      }
      encoder->SetError(kCodingErrorInvalidUnionTag);
      return;
    }

    RecursionDepth<IsRecursive> inner_depth = recursion_depth.Add(encoder, 1);
    if (!inner_depth.IsValid()) {
      return;
    }

    *position.As<fidl_xunion_tag_t>() = u->tag;

    
    size_t encode_inline_size;
    switch (u->tag) {
      case 1: // ::test_protocollayoutssamelibrary::wire::MainProtocolOnAnonRequest::Tag::kB
        encode_inline_size = ::fidl::internal::WireCodingTraits<bool, fidl::internal::WireCodingConstraintEmpty, IsRecursive>::kInlineSize;
        break;
      default:
        encode_inline_size = 0;
        break;
    }
    ::fidl::internal::EncodeFn<IsRecursive> encode_fn;
    switch (u->tag) {
      case 1: // ::test_protocollayoutssamelibrary::wire::MainProtocolOnAnonRequest::Tag::kB
        encode_fn = ::fidl::internal::MakeEncodeFn<bool, fidl::internal::WireCodingConstraintEmpty, IsRecursive>();
        break;
      default:
        encode_fn = nullptr;
        break;
    }
    WireEncodeEnvelope(encode_inline_size, encode_fn, encoder, &u->envelope, position + sizeof(fidl_xunion_tag_t), inner_depth);
  }

  static void Decode(internal::WireDecoder* decoder, ::fidl::internal::WirePosition position, RecursionDepth<IsRecursive> recursion_depth) {
    ::test_protocollayoutssamelibrary::wire::MainProtocolOnAnonRequest::Tag tag = *position.As<::test_protocollayoutssamelibrary::wire::MainProtocolOnAnonRequest::Tag>();
    if (unlikely(static_cast<uint64_t>(tag) == 0)) {
      if constexpr (!Constraint::is_optional) {
        decoder->SetError(kCodingErrorInvalidUnionTag);
        return;
      }
      static_assert(sizeof(fidl_envelope_t) == sizeof(uint64_t));
      if (*(position + sizeof(fidl_xunion_tag_t)).As<uint64_t>() != 0) {
        decoder->SetError(kCodingErrorZeroTagButNonZeroEnvelope);
      }
      return;
    }

    RecursionDepth<IsRecursive> inner_depth = recursion_depth.Add(decoder, 1);
    if (!inner_depth.IsValid()) {
      return;
    }

    
    size_t decode_inline_size;
    switch (tag) {
      case ::test_protocollayoutssamelibrary::wire::MainProtocolOnAnonRequest::Tag::kB:
        decode_inline_size = ::fidl::internal::WireCodingTraits<bool, fidl::internal::WireCodingConstraintEmpty, IsRecursive>::kInlineSize;
        break;
      default:
        decode_inline_size = 0;
        break;
    }
    DecodeFn<IsRecursive> decode_fn;
    switch(tag) {
      case ::test_protocollayoutssamelibrary::wire::MainProtocolOnAnonRequest::Tag::kB:
        decode_fn = ::fidl::internal::MakeDecodeFn<bool, fidl::internal::WireCodingConstraintEmpty, IsRecursive>();
        break;
      default:
        decode_fn = nullptr;
        break;
    }
    ::fidl::internal::WireDecodeFlexibleEnvelope(decode_inline_size, decode_fn, decoder, position + sizeof(fidl_xunion_tag_t), inner_depth);
  }
};

// Top-level union.
template <bool IsRecursive>
struct ::fidl::internal::WireCodingTraits<::test_protocollayoutssamelibrary::wire::MainProtocolOnAnonRequest, ::fidl::internal::WireCodingConstraintEmpty, IsRecursive>
  : public ::fidl::internal::WireCodingTraits<::test_protocollayoutssamelibrary::wire::MainProtocolOnAnonRequest, ::fidl::internal::WireCodingConstraintUnion<false>, IsRecursive> {};

  #pragma clang diagnostic pop

  }  // namespace fidl

