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

#include <fidl/test/union/llcpp/fidl.h>

#include <memory>

void ::fidl_test_union::wire::Union::SizeAndOffsetAssertionHelper() {
  static_assert(sizeof(Union) == sizeof(fidl_xunion_t));
  static_assert(offsetof(Union, ordinal_) == offsetof(fidl_xunion_t, tag));
  static_assert(offsetof(Union, envelope_) ==
                offsetof(fidl_xunion_t, envelope));
}

void ::fidl_test_union::wire::StrictUnion::SizeAndOffsetAssertionHelper() {
  static_assert(sizeof(StrictUnion) == sizeof(fidl_xunion_t));
  static_assert(offsetof(StrictUnion, ordinal_) ==
                offsetof(fidl_xunion_t, tag));
  static_assert(offsetof(StrictUnion, envelope_) ==
                offsetof(fidl_xunion_t, envelope));
}

void ::fidl_test_union::wire::StrictSimpleXUnion::
    SizeAndOffsetAssertionHelper() {
  static_assert(sizeof(StrictSimpleXUnion) == sizeof(fidl_xunion_t));
  static_assert(offsetof(StrictSimpleXUnion, ordinal_) ==
                offsetof(fidl_xunion_t, tag));
  static_assert(offsetof(StrictSimpleXUnion, envelope_) ==
                offsetof(fidl_xunion_t, envelope));
}

void ::fidl_test_union::wire::StrictFoo::SizeAndOffsetAssertionHelper() {
  static_assert(sizeof(StrictFoo) == sizeof(fidl_xunion_t));
  static_assert(offsetof(StrictFoo, ordinal_) == offsetof(fidl_xunion_t, tag));
  static_assert(offsetof(StrictFoo, envelope_) ==
                offsetof(fidl_xunion_t, envelope));
}

void ::fidl_test_union::wire::StrictBoundedXUnion::
    SizeAndOffsetAssertionHelper() {
  static_assert(sizeof(StrictBoundedXUnion) == sizeof(fidl_xunion_t));
  static_assert(offsetof(StrictBoundedXUnion, ordinal_) ==
                offsetof(fidl_xunion_t, tag));
  static_assert(offsetof(StrictBoundedXUnion, envelope_) ==
                offsetof(fidl_xunion_t, envelope));
}

void ::fidl_test_union::wire::ReverseOrdinalUnion::
    SizeAndOffsetAssertionHelper() {
  static_assert(sizeof(ReverseOrdinalUnion) == sizeof(fidl_xunion_t));
  static_assert(offsetof(ReverseOrdinalUnion, ordinal_) ==
                offsetof(fidl_xunion_t, tag));
  static_assert(offsetof(ReverseOrdinalUnion, envelope_) ==
                offsetof(fidl_xunion_t, envelope));
}

void ::fidl_test_union::wire::StrictPizzaOrPasta::
    SizeAndOffsetAssertionHelper() {
  static_assert(sizeof(StrictPizzaOrPasta) == sizeof(fidl_xunion_t));
  static_assert(offsetof(StrictPizzaOrPasta, ordinal_) ==
                offsetof(fidl_xunion_t, tag));
  static_assert(offsetof(StrictPizzaOrPasta, envelope_) ==
                offsetof(fidl_xunion_t, envelope));
}

void ::fidl_test_union::wire::PizzaOrPasta::SizeAndOffsetAssertionHelper() {
  static_assert(sizeof(PizzaOrPasta) == sizeof(fidl_xunion_t));
  static_assert(offsetof(PizzaOrPasta, ordinal_) ==
                offsetof(fidl_xunion_t, tag));
  static_assert(offsetof(PizzaOrPasta, envelope_) ==
                offsetof(fidl_xunion_t, envelope));
}
auto ::fidl_test_union::wire::FlexiblePizzaOrPasta::which() const
    -> ::fidl_test_union::wire::FlexiblePizzaOrPasta::Tag {
  ZX_ASSERT(!has_invalid_tag());
  switch (ordinal_) {
    case ::fidl_test_union::wire::FlexiblePizzaOrPasta::Ordinal::kPizza:
    case ::fidl_test_union::wire::FlexiblePizzaOrPasta::Ordinal::kPasta:
      return static_cast<::fidl_test_union::wire::FlexiblePizzaOrPasta::Tag>(
          ordinal_);
    default:
      return ::fidl_test_union::wire::FlexiblePizzaOrPasta::Tag::kUnknown;
  }
}

void ::fidl_test_union::wire::FlexiblePizzaOrPasta::
    SizeAndOffsetAssertionHelper() {
  static_assert(sizeof(FlexiblePizzaOrPasta) == sizeof(fidl_xunion_t));
  static_assert(offsetof(FlexiblePizzaOrPasta, ordinal_) ==
                offsetof(fidl_xunion_t, tag));
  static_assert(offsetof(FlexiblePizzaOrPasta, envelope_) ==
                offsetof(fidl_xunion_t, envelope));
}

void ::fidl_test_union::wire::ExplicitPizzaOrPasta::
    SizeAndOffsetAssertionHelper() {
  static_assert(sizeof(ExplicitPizzaOrPasta) == sizeof(fidl_xunion_t));
  static_assert(offsetof(ExplicitPizzaOrPasta, ordinal_) ==
                offsetof(fidl_xunion_t, tag));
  static_assert(offsetof(ExplicitPizzaOrPasta, envelope_) ==
                offsetof(fidl_xunion_t, envelope));
}
auto ::fidl_test_union::wire::OlderSimpleUnion::which() const
    -> ::fidl_test_union::wire::OlderSimpleUnion::Tag {
  ZX_ASSERT(!has_invalid_tag());
  switch (ordinal_) {
    case ::fidl_test_union::wire::OlderSimpleUnion::Ordinal::kI:
    case ::fidl_test_union::wire::OlderSimpleUnion::Ordinal::kF:
      return static_cast<::fidl_test_union::wire::OlderSimpleUnion::Tag>(
          ordinal_);
    default:
      return ::fidl_test_union::wire::OlderSimpleUnion::Tag::kUnknown;
  }
}

void ::fidl_test_union::wire::OlderSimpleUnion::SizeAndOffsetAssertionHelper() {
  static_assert(sizeof(OlderSimpleUnion) == sizeof(fidl_xunion_t));
  static_assert(offsetof(OlderSimpleUnion, ordinal_) ==
                offsetof(fidl_xunion_t, tag));
  static_assert(offsetof(OlderSimpleUnion, envelope_) ==
                offsetof(fidl_xunion_t, envelope));
}

namespace fidl_test_union {
[[maybe_unused]] constexpr uint64_t
    kTestProtocol_StrictXUnionHenceResponseMayBeStackAllocated_Ordinal =
        8393311445612289086lu;

extern "C" const fidl_type_t
    fidl_test_union_TestProtocolStrictXUnionHenceResponseMayBeStackAllocatedRequestTable;

extern "C" const fidl_type_t
    fidl_test_union_TestProtocolStrictXUnionHenceResponseMayBeStackAllocatedResponseTable;

[[maybe_unused]] constexpr uint64_t
    kTestProtocol_FlexibleXUnionHenceResponseMustBeHeapAllocated_Ordinal =
        6296412872266712530lu;

extern "C" const fidl_type_t
    fidl_test_union_TestProtocolFlexibleXUnionHenceResponseMustBeHeapAllocatedRequestTable;

extern "C" const fidl_type_t
    fidl_test_union_TestProtocolFlexibleXUnionHenceResponseMustBeHeapAllocatedResponseTable;
#ifdef __Fuchsia__
}  // namespace fidl_test_union
::fidl::WireResult<::fidl_test_union::TestProtocol::
                       StrictXUnionHenceResponseMayBeStackAllocated>::
    WireResult(
        ::fidl::UnownedClientEnd<::fidl_test_union::TestProtocol> _client) {
  ::fidl::OwnedEncodedMessage<
      ::fidl::WireRequest<::fidl_test_union::TestProtocol::
                              StrictXUnionHenceResponseMayBeStackAllocated>>
      _request(zx_txid_t(0));
  _request.GetOutgoingMessage()
      .Call<::fidl::WireResponse<
          ::fidl_test_union::TestProtocol::
              StrictXUnionHenceResponseMayBeStackAllocated>>(
          _client, bytes_.data(), bytes_.size());
  status_ = _request.status();
  error_ = _request.error();
}

::fidl::WireResult<::fidl_test_union::TestProtocol::
                       StrictXUnionHenceResponseMayBeStackAllocated>::
    WireResult(
        ::fidl::UnownedClientEnd<::fidl_test_union::TestProtocol> _client,
        zx_time_t _deadline) {
  ::fidl::OwnedEncodedMessage<
      ::fidl::WireRequest<::fidl_test_union::TestProtocol::
                              StrictXUnionHenceResponseMayBeStackAllocated>>
      _request(zx_txid_t(0));
  _request.GetOutgoingMessage()
      .Call<::fidl::WireResponse<
          ::fidl_test_union::TestProtocol::
              StrictXUnionHenceResponseMayBeStackAllocated>>(
          _client, bytes_.data(), bytes_.size(), _deadline);
  status_ = _request.status();
  error_ = _request.error();
}
namespace fidl_test_union {
#endif  // __Fuchsia__

#ifdef __Fuchsia__
}  // namespace fidl_test_union
::fidl::WireUnownedResult<::fidl_test_union::TestProtocol::
                              StrictXUnionHenceResponseMayBeStackAllocated>::
    WireUnownedResult(
        ::fidl::UnownedClientEnd<::fidl_test_union::TestProtocol> _client,
        uint8_t* _response_bytes, uint32_t _response_byte_capacity)
    : bytes_(_response_bytes) {
  ::fidl::OwnedEncodedMessage<
      ::fidl::WireRequest<::fidl_test_union::TestProtocol::
                              StrictXUnionHenceResponseMayBeStackAllocated>>
      _request(zx_txid_t(0));
  _request.GetOutgoingMessage()
      .Call<::fidl::WireResponse<
          ::fidl_test_union::TestProtocol::
              StrictXUnionHenceResponseMayBeStackAllocated>>(
          _client, _response_bytes, _response_byte_capacity);
  status_ = _request.status();
  error_ = _request.error();
}
namespace fidl_test_union {
#endif  // __Fuchsia__

#ifdef __Fuchsia__
}  // namespace fidl_test_union
::fidl::WireResult<::fidl_test_union::TestProtocol::
                       FlexibleXUnionHenceResponseMustBeHeapAllocated>::
    WireResult(
        ::fidl::UnownedClientEnd<::fidl_test_union::TestProtocol> _client) {
  ::fidl::OwnedEncodedMessage<
      ::fidl::WireRequest<::fidl_test_union::TestProtocol::
                              FlexibleXUnionHenceResponseMustBeHeapAllocated>>
      _request(zx_txid_t(0));
  _request.GetOutgoingMessage()
      .Call<::fidl::WireResponse<
          ::fidl_test_union::TestProtocol::
              FlexibleXUnionHenceResponseMustBeHeapAllocated>>(
          _client, bytes_.data(), bytes_.size());
  status_ = _request.status();
  error_ = _request.error();
}

::fidl::WireResult<::fidl_test_union::TestProtocol::
                       FlexibleXUnionHenceResponseMustBeHeapAllocated>::
    WireResult(
        ::fidl::UnownedClientEnd<::fidl_test_union::TestProtocol> _client,
        zx_time_t _deadline) {
  ::fidl::OwnedEncodedMessage<
      ::fidl::WireRequest<::fidl_test_union::TestProtocol::
                              FlexibleXUnionHenceResponseMustBeHeapAllocated>>
      _request(zx_txid_t(0));
  _request.GetOutgoingMessage()
      .Call<::fidl::WireResponse<
          ::fidl_test_union::TestProtocol::
              FlexibleXUnionHenceResponseMustBeHeapAllocated>>(
          _client, bytes_.data(), bytes_.size(), _deadline);
  status_ = _request.status();
  error_ = _request.error();
}
namespace fidl_test_union {
#endif  // __Fuchsia__

#ifdef __Fuchsia__
}  // namespace fidl_test_union
::fidl::WireUnownedResult<::fidl_test_union::TestProtocol::
                              FlexibleXUnionHenceResponseMustBeHeapAllocated>::
    WireUnownedResult(
        ::fidl::UnownedClientEnd<::fidl_test_union::TestProtocol> _client,
        uint8_t* _response_bytes, uint32_t _response_byte_capacity)
    : bytes_(_response_bytes) {
  ::fidl::OwnedEncodedMessage<
      ::fidl::WireRequest<::fidl_test_union::TestProtocol::
                              FlexibleXUnionHenceResponseMustBeHeapAllocated>>
      _request(zx_txid_t(0));
  _request.GetOutgoingMessage()
      .Call<::fidl::WireResponse<
          ::fidl_test_union::TestProtocol::
              FlexibleXUnionHenceResponseMustBeHeapAllocated>>(
          _client, _response_bytes, _response_byte_capacity);
  status_ = _request.status();
  error_ = _request.error();
}
namespace fidl_test_union {
#endif  // __Fuchsia__

}  // namespace fidl_test_union
#ifdef __Fuchsia__
::fidl::WireResult<::fidl_test_union::TestProtocol::
                       StrictXUnionHenceResponseMayBeStackAllocated>
fidl::internal::WireClientImpl<::fidl_test_union::TestProtocol>::
    StrictXUnionHenceResponseMayBeStackAllocated_Sync() {
  if (auto _channel = ::fidl::internal::ClientBase::GetChannel()) {
    return ::fidl::WireResult<::fidl_test_union::TestProtocol::
                                  StrictXUnionHenceResponseMayBeStackAllocated>(
        ::fidl::UnownedClientEnd<::fidl_test_union::TestProtocol>(
            _channel->handle()));
  }
  return ::fidl::WireResult<::fidl_test_union::TestProtocol::
                                StrictXUnionHenceResponseMayBeStackAllocated>(
      ::fidl::Result(ZX_ERR_CANCELED, ::fidl::kErrorChannelUnbound));
}
#endif  // __Fuchsia__

#ifdef __Fuchsia__
::fidl::WireUnownedResult<::fidl_test_union::TestProtocol::
                              StrictXUnionHenceResponseMayBeStackAllocated>
fidl::internal::WireClientImpl<::fidl_test_union::TestProtocol>::
    StrictXUnionHenceResponseMayBeStackAllocated_Sync(
        ::fidl::BufferSpan _response_buffer) {
  if (auto _channel = ::fidl::internal::ClientBase::GetChannel()) {
    return ::fidl::WireUnownedResult<
        ::fidl_test_union::TestProtocol::
            StrictXUnionHenceResponseMayBeStackAllocated>(
        ::fidl::UnownedClientEnd<::fidl_test_union::TestProtocol>(
            _channel->handle()),
        _response_buffer.data, _response_buffer.capacity);
  }
  return ::fidl::WireUnownedResult<
      ::fidl_test_union::TestProtocol::
          StrictXUnionHenceResponseMayBeStackAllocated>(
      ::fidl::Result(ZX_ERR_CANCELED, ::fidl::kErrorChannelUnbound));
}
#endif  // __Fuchsia__

#ifdef __Fuchsia__

::fidl::WireResponseContext<
    ::fidl_test_union::TestProtocol::
        StrictXUnionHenceResponseMayBeStackAllocated>::WireResponseContext()
    : ::fidl::internal::ResponseContext(
          ::fidl::WireResponse<
              ::fidl_test_union::TestProtocol::
                  StrictXUnionHenceResponseMayBeStackAllocated>::Type,
          ::fidl_test_union::
              kTestProtocol_StrictXUnionHenceResponseMayBeStackAllocated_Ordinal) {
}

void ::fidl::WireResponseContext<
    ::fidl_test_union::TestProtocol::
        StrictXUnionHenceResponseMayBeStackAllocated>::OnReply(uint8_t* reply) {
  OnReply(reinterpret_cast<::fidl::WireResponse<
              ::fidl_test_union::TestProtocol::
                  StrictXUnionHenceResponseMayBeStackAllocated>*>(reply));
}
#endif  // __Fuchsia__

#ifdef __Fuchsia__
::fidl::Result fidl::internal::WireClientImpl<::fidl_test_union::TestProtocol>::
    StrictXUnionHenceResponseMayBeStackAllocated(
        ::fit::callback<
            void(::fidl::WireResponse<
                 ::fidl_test_union::TestProtocol::
                     StrictXUnionHenceResponseMayBeStackAllocated>* response)>
            _cb) {
  class ResponseContext final
      : public ::fidl::WireResponseContext<
            ::fidl_test_union::TestProtocol::
                StrictXUnionHenceResponseMayBeStackAllocated> {
   public:
    ResponseContext(
        ::fit::callback<
            void(::fidl::WireResponse<
                 ::fidl_test_union::TestProtocol::
                     StrictXUnionHenceResponseMayBeStackAllocated>* response)>
            cb)
        : cb_(std::move(cb)) {}

    void OnReply(
        ::fidl::WireResponse<::fidl_test_union::TestProtocol::
                                 StrictXUnionHenceResponseMayBeStackAllocated>*
            response) override {
      cb_(response);

      delete this;
    }

    void OnError() override { delete this; }

   private:
    ::fit::callback<void(
        ::fidl::WireResponse<::fidl_test_union::TestProtocol::
                                 StrictXUnionHenceResponseMayBeStackAllocated>*
            response)>
        cb_;
  };

  auto* _context = new ResponseContext(std::move(_cb));
  ::fidl::internal::ClientBase::PrepareAsyncTxn(_context);
  ::fidl::WireRequest<::fidl_test_union::TestProtocol::
                          StrictXUnionHenceResponseMayBeStackAllocated>::
      OwnedEncodedMessage _request(_context->Txid());
  return _request.GetOutgoingMessage().Write(this, _context);
}

::fidl::Result fidl::internal::WireClientImpl<::fidl_test_union::TestProtocol>::
    StrictXUnionHenceResponseMayBeStackAllocated(
        ::fidl::WireResponseContext<
            ::fidl_test_union::TestProtocol::
                StrictXUnionHenceResponseMayBeStackAllocated>* _context) {
  ::fidl::internal::ClientBase::PrepareAsyncTxn(_context);

  ::fidl::WireRequest<::fidl_test_union::TestProtocol::
                          StrictXUnionHenceResponseMayBeStackAllocated>::
      OwnedEncodedMessage _request(_context->Txid());
  return _request.GetOutgoingMessage().Write(this, _context);
}
#endif  // __Fuchsia__

#ifdef __Fuchsia__
::fidl::WireResult<::fidl_test_union::TestProtocol::
                       FlexibleXUnionHenceResponseMustBeHeapAllocated>
fidl::internal::WireClientImpl<::fidl_test_union::TestProtocol>::
    FlexibleXUnionHenceResponseMustBeHeapAllocated_Sync() {
  if (auto _channel = ::fidl::internal::ClientBase::GetChannel()) {
    return ::fidl::WireResult<
        ::fidl_test_union::TestProtocol::
            FlexibleXUnionHenceResponseMustBeHeapAllocated>(
        ::fidl::UnownedClientEnd<::fidl_test_union::TestProtocol>(
            _channel->handle()));
  }
  return ::fidl::WireResult<::fidl_test_union::TestProtocol::
                                FlexibleXUnionHenceResponseMustBeHeapAllocated>(
      ::fidl::Result(ZX_ERR_CANCELED, ::fidl::kErrorChannelUnbound));
}
#endif  // __Fuchsia__

#ifdef __Fuchsia__
::fidl::WireUnownedResult<::fidl_test_union::TestProtocol::
                              FlexibleXUnionHenceResponseMustBeHeapAllocated>
fidl::internal::WireClientImpl<::fidl_test_union::TestProtocol>::
    FlexibleXUnionHenceResponseMustBeHeapAllocated_Sync(
        ::fidl::BufferSpan _response_buffer) {
  if (auto _channel = ::fidl::internal::ClientBase::GetChannel()) {
    return ::fidl::WireUnownedResult<
        ::fidl_test_union::TestProtocol::
            FlexibleXUnionHenceResponseMustBeHeapAllocated>(
        ::fidl::UnownedClientEnd<::fidl_test_union::TestProtocol>(
            _channel->handle()),
        _response_buffer.data, _response_buffer.capacity);
  }
  return ::fidl::WireUnownedResult<
      ::fidl_test_union::TestProtocol::
          FlexibleXUnionHenceResponseMustBeHeapAllocated>(
      ::fidl::Result(ZX_ERR_CANCELED, ::fidl::kErrorChannelUnbound));
}
#endif  // __Fuchsia__

#ifdef __Fuchsia__

::fidl::WireResponseContext<
    ::fidl_test_union::TestProtocol::
        FlexibleXUnionHenceResponseMustBeHeapAllocated>::WireResponseContext()
    : ::fidl::internal::ResponseContext(
          ::fidl::WireResponse<
              ::fidl_test_union::TestProtocol::
                  FlexibleXUnionHenceResponseMustBeHeapAllocated>::Type,
          ::fidl_test_union::
              kTestProtocol_FlexibleXUnionHenceResponseMustBeHeapAllocated_Ordinal) {
}

void ::fidl::WireResponseContext<
    ::fidl_test_union::TestProtocol::
        FlexibleXUnionHenceResponseMustBeHeapAllocated>::OnReply(uint8_t*
                                                                     reply) {
  OnReply(reinterpret_cast<::fidl::WireResponse<
              ::fidl_test_union::TestProtocol::
                  FlexibleXUnionHenceResponseMustBeHeapAllocated>*>(reply));
}
#endif  // __Fuchsia__

#ifdef __Fuchsia__
::fidl::Result fidl::internal::WireClientImpl<::fidl_test_union::TestProtocol>::
    FlexibleXUnionHenceResponseMustBeHeapAllocated(
        ::fit::callback<
            void(::fidl::WireResponse<
                 ::fidl_test_union::TestProtocol::
                     FlexibleXUnionHenceResponseMustBeHeapAllocated>* response)>
            _cb) {
  class ResponseContext final
      : public ::fidl::WireResponseContext<
            ::fidl_test_union::TestProtocol::
                FlexibleXUnionHenceResponseMustBeHeapAllocated> {
   public:
    ResponseContext(
        ::fit::callback<
            void(::fidl::WireResponse<
                 ::fidl_test_union::TestProtocol::
                     FlexibleXUnionHenceResponseMustBeHeapAllocated>* response)>
            cb)
        : cb_(std::move(cb)) {}

    void OnReply(::fidl::WireResponse<
                 ::fidl_test_union::TestProtocol::
                     FlexibleXUnionHenceResponseMustBeHeapAllocated>* response)
        override {
      cb_(response);

      delete this;
    }

    void OnError() override { delete this; }

   private:
    ::fit::callback<void(
        ::fidl::WireResponse<
            ::fidl_test_union::TestProtocol::
                FlexibleXUnionHenceResponseMustBeHeapAllocated>* response)>
        cb_;
  };

  auto* _context = new ResponseContext(std::move(_cb));
  ::fidl::internal::ClientBase::PrepareAsyncTxn(_context);
  ::fidl::WireRequest<::fidl_test_union::TestProtocol::
                          FlexibleXUnionHenceResponseMustBeHeapAllocated>::
      OwnedEncodedMessage _request(_context->Txid());
  return _request.GetOutgoingMessage().Write(this, _context);
}

::fidl::Result fidl::internal::WireClientImpl<::fidl_test_union::TestProtocol>::
    FlexibleXUnionHenceResponseMustBeHeapAllocated(
        ::fidl::WireResponseContext<
            ::fidl_test_union::TestProtocol::
                FlexibleXUnionHenceResponseMustBeHeapAllocated>* _context) {
  ::fidl::internal::ClientBase::PrepareAsyncTxn(_context);

  ::fidl::WireRequest<::fidl_test_union::TestProtocol::
                          FlexibleXUnionHenceResponseMustBeHeapAllocated>::
      OwnedEncodedMessage _request(_context->Txid());
  return _request.GetOutgoingMessage().Write(this, _context);
}
#endif  // __Fuchsia__

#ifdef __Fuchsia__
std::optional<::fidl::UnbindInfo> fidl::internal::WireClientImpl<
    ::fidl_test_union::TestProtocol>::DispatchEvent(fidl_incoming_msg_t* msg) {
  FidlHandleInfoCloseMany(msg->handles, msg->num_handles);
  return ::fidl::UnbindInfo{::fidl::UnbindInfo::kUnexpectedMessage,
                            ZX_ERR_NOT_SUPPORTED};
}
#endif  // __Fuchsia__

#ifdef __Fuchsia__

::fidl::DispatchResult
fidl::internal::WireDispatcher<::fidl_test_union::TestProtocol>::TryDispatch(
    ::fidl::WireInterface<::fidl_test_union::TestProtocol>* impl,
    fidl_incoming_msg_t* msg, ::fidl::Transaction* txn) {
  static const ::fidl::internal::MethodEntry entries[] = {
      {
          ::fidl_test_union::
              kTestProtocol_StrictXUnionHenceResponseMayBeStackAllocated_Ordinal,
          ::fidl::WireRequest<
              ::fidl_test_union::TestProtocol::
                  StrictXUnionHenceResponseMayBeStackAllocated>::Type,
          [](void* interface, void* bytes, ::fidl::Transaction* txn) {
            ::fidl::WireInterface<::fidl_test_union::TestProtocol>::
                StrictXUnionHenceResponseMayBeStackAllocatedCompleter::Sync
                    completer(txn);
            reinterpret_cast<
                ::fidl::WireInterface<::fidl_test_union::TestProtocol>*>(
                interface)
                ->StrictXUnionHenceResponseMayBeStackAllocated(completer);
          },
      },
      {
          ::fidl_test_union::
              kTestProtocol_FlexibleXUnionHenceResponseMustBeHeapAllocated_Ordinal,
          ::fidl::WireRequest<
              ::fidl_test_union::TestProtocol::
                  FlexibleXUnionHenceResponseMustBeHeapAllocated>::Type,
          [](void* interface, void* bytes, ::fidl::Transaction* txn) {
            ::fidl::WireInterface<::fidl_test_union::TestProtocol>::
                FlexibleXUnionHenceResponseMustBeHeapAllocatedCompleter::Sync
                    completer(txn);
            reinterpret_cast<
                ::fidl::WireInterface<::fidl_test_union::TestProtocol>*>(
                interface)
                ->FlexibleXUnionHenceResponseMustBeHeapAllocated(completer);
          },
      },
  };
  return ::fidl::internal::TryDispatch(
      impl, msg, txn, entries,
      entries + sizeof(entries) / sizeof(::fidl::internal::MethodEntry));
}

::fidl::DispatchResult
fidl::internal::WireDispatcher<::fidl_test_union::TestProtocol>::Dispatch(
    ::fidl::WireInterface<::fidl_test_union::TestProtocol>* impl,
    fidl_incoming_msg_t* msg, ::fidl::Transaction* txn) {
  ::fidl::DispatchResult dispatch_result = TryDispatch(impl, msg, txn);
  if (dispatch_result == ::fidl::DispatchResult::kNotFound) {
    FidlHandleInfoCloseMany(msg->handles, msg->num_handles);
    txn->InternalError(
        {::fidl::UnbindInfo::kUnexpectedMessage, ZX_ERR_NOT_SUPPORTED});
  }
  return dispatch_result;
}
::fidl::DispatchResult
fidl::WireInterface<::fidl_test_union::TestProtocol>::dispatch_message(
    fidl_incoming_msg_t* msg, ::fidl::Transaction* txn) {
  return ::fidl::internal::WireDispatcher<
      ::fidl_test_union::TestProtocol>::Dispatch(this, msg, txn);
}
#endif  // __Fuchsia__

#ifdef __Fuchsia__
::fidl::Result fidl::WireInterface<::fidl_test_union::TestProtocol>::
    StrictXUnionHenceResponseMayBeStackAllocatedCompleterBase::Reply(
        ::fidl_test_union::wire::StrictBoundedXUnion xu) {
  ::fidl::OwnedEncodedMessage<
      ::fidl::WireResponse<::fidl_test_union::TestProtocol::
                               StrictXUnionHenceResponseMayBeStackAllocated>>
      _response{xu};
  return ::fidl::WireInterface<::fidl_test_union::TestProtocol>::
      StrictXUnionHenceResponseMayBeStackAllocatedCompleterBase::SendReply(
          &_response.GetOutgoingMessage());
}
#endif  // __Fuchsia__

#ifdef __Fuchsia__
::fidl::Result fidl::WireInterface<::fidl_test_union::TestProtocol>::
    StrictXUnionHenceResponseMayBeStackAllocatedCompleterBase::Reply(
        ::fidl::BufferSpan _buffer,
        ::fidl_test_union::wire::StrictBoundedXUnion xu) {
  ::fidl::WireResponse<::fidl_test_union::TestProtocol::
                           StrictXUnionHenceResponseMayBeStackAllocated>::
      UnownedEncodedMessage _response(_buffer.data, _buffer.capacity, xu);
  return CompleterBase::SendReply(&_response.GetOutgoingMessage());
}
#endif  // __Fuchsia__

#ifdef __Fuchsia__
::fidl::Result fidl::WireInterface<::fidl_test_union::TestProtocol>::
    FlexibleXUnionHenceResponseMustBeHeapAllocatedCompleterBase::Reply(
        ::fidl_test_union::wire::OlderSimpleUnion xu) {
  ::fidl::OwnedEncodedMessage<
      ::fidl::WireResponse<::fidl_test_union::TestProtocol::
                               FlexibleXUnionHenceResponseMustBeHeapAllocated>>
      _response{xu};
  return ::fidl::WireInterface<::fidl_test_union::TestProtocol>::
      FlexibleXUnionHenceResponseMustBeHeapAllocatedCompleterBase::SendReply(
          &_response.GetOutgoingMessage());
}
#endif  // __Fuchsia__

#ifdef __Fuchsia__
::fidl::Result fidl::WireInterface<::fidl_test_union::TestProtocol>::
    FlexibleXUnionHenceResponseMustBeHeapAllocatedCompleterBase::Reply(
        ::fidl::BufferSpan _buffer,
        ::fidl_test_union::wire::OlderSimpleUnion xu) {
  ::fidl::WireResponse<::fidl_test_union::TestProtocol::
                           FlexibleXUnionHenceResponseMustBeHeapAllocated>::
      UnownedEncodedMessage _response(_buffer.data, _buffer.capacity, xu);
  return CompleterBase::SendReply(&_response.GetOutgoingMessage());
}
#endif  // __Fuchsia__

void ::fidl::WireRequest<::fidl_test_union::TestProtocol::
                             StrictXUnionHenceResponseMayBeStackAllocated>::
    _InitHeader(zx_txid_t _txid) {
  fidl_init_txn_header(
      &_hdr, _txid,
      ::fidl_test_union::
          kTestProtocol_StrictXUnionHenceResponseMayBeStackAllocated_Ordinal);
}

void ::fidl::WireResponse<
    ::fidl_test_union::TestProtocol::
        StrictXUnionHenceResponseMayBeStackAllocated>::_InitHeader() {
  fidl_init_txn_header(
      &_hdr, 0,
      ::fidl_test_union::
          kTestProtocol_StrictXUnionHenceResponseMayBeStackAllocated_Ordinal);
}

void ::fidl::WireRequest<::fidl_test_union::TestProtocol::
                             FlexibleXUnionHenceResponseMustBeHeapAllocated>::
    _InitHeader(zx_txid_t _txid) {
  fidl_init_txn_header(
      &_hdr, _txid,
      ::fidl_test_union::
          kTestProtocol_FlexibleXUnionHenceResponseMustBeHeapAllocated_Ordinal);
}

void ::fidl::WireResponse<
    ::fidl_test_union::TestProtocol::
        FlexibleXUnionHenceResponseMustBeHeapAllocated>::_InitHeader() {
  fidl_init_txn_header(
      &_hdr, 0,
      ::fidl_test_union::
          kTestProtocol_FlexibleXUnionHenceResponseMustBeHeapAllocated_Ordinal);
}

#ifdef __Fuchsia__

#endif  // __Fuchsia__

auto ::fidl_test_union::wire::NewerSimpleUnion::which() const
    -> ::fidl_test_union::wire::NewerSimpleUnion::Tag {
  ZX_ASSERT(!has_invalid_tag());
  switch (ordinal_) {
    case ::fidl_test_union::wire::NewerSimpleUnion::Ordinal::kI:
    case ::fidl_test_union::wire::NewerSimpleUnion::Ordinal::kS:
    case ::fidl_test_union::wire::NewerSimpleUnion::Ordinal::kV:
      return static_cast<::fidl_test_union::wire::NewerSimpleUnion::Tag>(
          ordinal_);
    default:
      return ::fidl_test_union::wire::NewerSimpleUnion::Tag::kUnknown;
  }
}

void ::fidl_test_union::wire::NewerSimpleUnion::SizeAndOffsetAssertionHelper() {
  static_assert(sizeof(NewerSimpleUnion) == sizeof(fidl_xunion_t));
  static_assert(offsetof(NewerSimpleUnion, ordinal_) ==
                offsetof(fidl_xunion_t, tag));
  static_assert(offsetof(NewerSimpleUnion, envelope_) ==
                offsetof(fidl_xunion_t, envelope));
}
auto ::fidl_test_union::wire::FlexibleUnion::which() const
    -> ::fidl_test_union::wire::FlexibleUnion::Tag {
  ZX_ASSERT(!has_invalid_tag());
  switch (ordinal_) {
    case ::fidl_test_union::wire::FlexibleUnion::Ordinal::kPrimitive:
    case ::fidl_test_union::wire::FlexibleUnion::Ordinal::
        kStringNeedsConstructor:
    case ::fidl_test_union::wire::FlexibleUnion::Ordinal::
        kVectorStringAlsoNeedsConstructor:
      return static_cast<::fidl_test_union::wire::FlexibleUnion::Tag>(ordinal_);
    default:
      return ::fidl_test_union::wire::FlexibleUnion::Tag::kUnknown;
  }
}

void ::fidl_test_union::wire::FlexibleUnion::SizeAndOffsetAssertionHelper() {
  static_assert(sizeof(FlexibleUnion) == sizeof(fidl_xunion_t));
  static_assert(offsetof(FlexibleUnion, ordinal_) ==
                offsetof(fidl_xunion_t, tag));
  static_assert(offsetof(FlexibleUnion, envelope_) ==
                offsetof(fidl_xunion_t, envelope));
}
auto ::fidl_test_union::wire::FlexibleFoo::which() const
    -> ::fidl_test_union::wire::FlexibleFoo::Tag {
  ZX_ASSERT(!has_invalid_tag());
  switch (ordinal_) {
    case ::fidl_test_union::wire::FlexibleFoo::Ordinal::kS:
    case ::fidl_test_union::wire::FlexibleFoo::Ordinal::kI:
      return static_cast<::fidl_test_union::wire::FlexibleFoo::Tag>(ordinal_);
    default:
      return ::fidl_test_union::wire::FlexibleFoo::Tag::kUnknown;
  }
}

void ::fidl_test_union::wire::FlexibleFoo::SizeAndOffsetAssertionHelper() {
  static_assert(sizeof(FlexibleFoo) == sizeof(fidl_xunion_t));
  static_assert(offsetof(FlexibleFoo, ordinal_) ==
                offsetof(fidl_xunion_t, tag));
  static_assert(offsetof(FlexibleFoo, envelope_) ==
                offsetof(fidl_xunion_t, envelope));
}

void ::fidl_test_union::wire::FieldCollision::SizeAndOffsetAssertionHelper() {
  static_assert(sizeof(FieldCollision) == sizeof(fidl_xunion_t));
  static_assert(offsetof(FieldCollision, ordinal_) ==
                offsetof(fidl_xunion_t, tag));
  static_assert(offsetof(FieldCollision, envelope_) ==
                offsetof(fidl_xunion_t, envelope));
}
auto ::fidl_test_union::wire::ExplicitXUnion::which() const
    -> ::fidl_test_union::wire::ExplicitXUnion::Tag {
  ZX_ASSERT(!has_invalid_tag());
  switch (ordinal_) {
    case ::fidl_test_union::wire::ExplicitXUnion::Ordinal::kI:
    case ::fidl_test_union::wire::ExplicitXUnion::Ordinal::kF:
      return static_cast<::fidl_test_union::wire::ExplicitXUnion::Tag>(
          ordinal_);
    default:
      return ::fidl_test_union::wire::ExplicitXUnion::Tag::kUnknown;
  }
}

void ::fidl_test_union::wire::ExplicitXUnion::SizeAndOffsetAssertionHelper() {
  static_assert(sizeof(ExplicitXUnion) == sizeof(fidl_xunion_t));
  static_assert(offsetof(ExplicitXUnion, ordinal_) ==
                offsetof(fidl_xunion_t, tag));
  static_assert(offsetof(ExplicitXUnion, envelope_) ==
                offsetof(fidl_xunion_t, envelope));
}

void ::fidl_test_union::wire::ExplicitUnion::SizeAndOffsetAssertionHelper() {
  static_assert(sizeof(ExplicitUnion) == sizeof(fidl_xunion_t));
  static_assert(offsetof(ExplicitUnion, ordinal_) ==
                offsetof(fidl_xunion_t, tag));
  static_assert(offsetof(ExplicitUnion, envelope_) ==
                offsetof(fidl_xunion_t, envelope));
}

void ::fidl_test_union::wire::ExplicitStrictFoo::
    SizeAndOffsetAssertionHelper() {
  static_assert(sizeof(ExplicitStrictFoo) == sizeof(fidl_xunion_t));
  static_assert(offsetof(ExplicitStrictFoo, ordinal_) ==
                offsetof(fidl_xunion_t, tag));
  static_assert(offsetof(ExplicitStrictFoo, envelope_) ==
                offsetof(fidl_xunion_t, envelope));
}
auto ::fidl_test_union::wire::ExplicitFoo::which() const
    -> ::fidl_test_union::wire::ExplicitFoo::Tag {
  ZX_ASSERT(!has_invalid_tag());
  switch (ordinal_) {
    case ::fidl_test_union::wire::ExplicitFoo::Ordinal::kS:
    case ::fidl_test_union::wire::ExplicitFoo::Ordinal::kI:
      return static_cast<::fidl_test_union::wire::ExplicitFoo::Tag>(ordinal_);
    default:
      return ::fidl_test_union::wire::ExplicitFoo::Tag::kUnknown;
  }
}

void ::fidl_test_union::wire::ExplicitFoo::SizeAndOffsetAssertionHelper() {
  static_assert(sizeof(ExplicitFoo) == sizeof(fidl_xunion_t));
  static_assert(offsetof(ExplicitFoo, ordinal_) ==
                offsetof(fidl_xunion_t, tag));
  static_assert(offsetof(ExplicitFoo, envelope_) ==
                offsetof(fidl_xunion_t, envelope));
}

auto ::fidl_test_union::wire::XUnionContainingEmptyStruct::which() const
    -> ::fidl_test_union::wire::XUnionContainingEmptyStruct::Tag {
  ZX_ASSERT(!has_invalid_tag());
  switch (ordinal_) {
    case ::fidl_test_union::wire::XUnionContainingEmptyStruct::Ordinal::kEmpty:
      return static_cast<
          ::fidl_test_union::wire::XUnionContainingEmptyStruct::Tag>(ordinal_);
    default:
      return ::fidl_test_union::wire::XUnionContainingEmptyStruct::Tag::
          kUnknown;
  }
}

void ::fidl_test_union::wire::XUnionContainingEmptyStruct::
    SizeAndOffsetAssertionHelper() {
  static_assert(sizeof(XUnionContainingEmptyStruct) == sizeof(fidl_xunion_t));
  static_assert(offsetof(XUnionContainingEmptyStruct, ordinal_) ==
                offsetof(fidl_xunion_t, tag));
  static_assert(offsetof(XUnionContainingEmptyStruct, envelope_) ==
                offsetof(fidl_xunion_t, envelope));
}
