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

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

#include <memory>

void ::fidl_test_requestflexibleenvelope::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));
}
auto ::fidl_test_requestflexibleenvelope::wire::FlexibleFoo::which() const
    -> ::fidl_test_requestflexibleenvelope::wire::FlexibleFoo::Tag {
  ZX_ASSERT(!has_invalid_tag());
  switch (ordinal_) {
    case ::fidl_test_requestflexibleenvelope::wire::FlexibleFoo::Ordinal::kS:
    case ::fidl_test_requestflexibleenvelope::wire::FlexibleFoo::Ordinal::kI:
      return static_cast<
          ::fidl_test_requestflexibleenvelope::wire::FlexibleFoo::Tag>(
          ordinal_);
    default:
      return ::fidl_test_requestflexibleenvelope::wire::FlexibleFoo::Tag::
          kUnknown;
  }
}

void ::fidl_test_requestflexibleenvelope::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));
}

namespace fidl_test_requestflexibleenvelope {
[[maybe_unused]] constexpr uint64_t
    kProtocol_RequestStrictResponseFlexible_Ordinal = 4346871690266280218lu;

extern "C" const fidl_type_t
    fidl_test_requestflexibleenvelope_ProtocolRequestStrictResponseFlexibleRequestTable;

extern "C" const fidl_type_t
    fidl_test_requestflexibleenvelope_ProtocolRequestStrictResponseFlexibleResponseTable;

[[maybe_unused]] constexpr uint64_t
    kProtocol_RequestFlexibleResponseStrict_Ordinal = 4374294377437089654lu;

extern "C" const fidl_type_t
    fidl_test_requestflexibleenvelope_ProtocolRequestFlexibleResponseStrictRequestTable;

extern "C" const fidl_type_t
    fidl_test_requestflexibleenvelope_ProtocolRequestFlexibleResponseStrictResponseTable;
#ifdef __Fuchsia__
}  // namespace fidl_test_requestflexibleenvelope
::fidl::WireResult<::fidl_test_requestflexibleenvelope::Protocol::
                       RequestStrictResponseFlexible>::
    WireResult(
        ::fidl::UnownedClientEnd<::fidl_test_requestflexibleenvelope::Protocol>
            _client,
        ::fidl_test_requestflexibleenvelope::wire::StrictFoo s) {
  ::fidl::OwnedEncodedMessage<
      ::fidl::WireRequest<::fidl_test_requestflexibleenvelope::Protocol::
                              RequestStrictResponseFlexible>>
      _request(zx_txid_t(0), s);
  _request.GetOutgoingMessage()
      .Call<::fidl::WireResponse<::fidl_test_requestflexibleenvelope::Protocol::
                                     RequestStrictResponseFlexible>>(
          _client, bytes_.data(), bytes_.size());
  status_ = _request.status();
  error_ = _request.error();
}

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

#ifdef __Fuchsia__
}  // namespace fidl_test_requestflexibleenvelope
::fidl::WireUnownedResult<::fidl_test_requestflexibleenvelope::Protocol::
                              RequestStrictResponseFlexible>::
    WireUnownedResult(
        ::fidl::UnownedClientEnd<::fidl_test_requestflexibleenvelope::Protocol>
            _client,
        uint8_t* _request_bytes, uint32_t _request_byte_capacity,
        ::fidl_test_requestflexibleenvelope::wire::StrictFoo s,
        uint8_t* _response_bytes, uint32_t _response_byte_capacity)
    : bytes_(_response_bytes) {
  ::fidl::UnownedEncodedMessage<
      ::fidl::WireRequest<::fidl_test_requestflexibleenvelope::Protocol::
                              RequestStrictResponseFlexible>>
      _request(_request_bytes, _request_byte_capacity, 0, s);
  _request.GetOutgoingMessage()
      .Call<::fidl::WireResponse<::fidl_test_requestflexibleenvelope::Protocol::
                                     RequestStrictResponseFlexible>>(
          _client, _response_bytes, _response_byte_capacity);
  status_ = _request.status();
  error_ = _request.error();
}
namespace fidl_test_requestflexibleenvelope {
#endif  // __Fuchsia__

#ifdef __Fuchsia__
}  // namespace fidl_test_requestflexibleenvelope
::fidl::WireResult<::fidl_test_requestflexibleenvelope::Protocol::
                       RequestFlexibleResponseStrict>::
    WireResult(
        ::fidl::UnownedClientEnd<::fidl_test_requestflexibleenvelope::Protocol>
            _client,
        ::fidl_test_requestflexibleenvelope::wire::FlexibleFoo s) {
  ::fidl::OwnedEncodedMessage<
      ::fidl::WireRequest<::fidl_test_requestflexibleenvelope::Protocol::
                              RequestFlexibleResponseStrict>>
      _request(zx_txid_t(0), s);
  _request.GetOutgoingMessage()
      .Call<::fidl::WireResponse<::fidl_test_requestflexibleenvelope::Protocol::
                                     RequestFlexibleResponseStrict>>(
          _client, bytes_.data(), bytes_.size());
  status_ = _request.status();
  error_ = _request.error();
}

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

#ifdef __Fuchsia__
}  // namespace fidl_test_requestflexibleenvelope
::fidl::WireUnownedResult<::fidl_test_requestflexibleenvelope::Protocol::
                              RequestFlexibleResponseStrict>::
    WireUnownedResult(
        ::fidl::UnownedClientEnd<::fidl_test_requestflexibleenvelope::Protocol>
            _client,
        uint8_t* _request_bytes, uint32_t _request_byte_capacity,
        ::fidl_test_requestflexibleenvelope::wire::FlexibleFoo s,
        uint8_t* _response_bytes, uint32_t _response_byte_capacity)
    : bytes_(_response_bytes) {
  ::fidl::UnownedEncodedMessage<
      ::fidl::WireRequest<::fidl_test_requestflexibleenvelope::Protocol::
                              RequestFlexibleResponseStrict>>
      _request(_request_bytes, _request_byte_capacity, 0, s);
  _request.GetOutgoingMessage()
      .Call<::fidl::WireResponse<::fidl_test_requestflexibleenvelope::Protocol::
                                     RequestFlexibleResponseStrict>>(
          _client, _response_bytes, _response_byte_capacity);
  status_ = _request.status();
  error_ = _request.error();
}
namespace fidl_test_requestflexibleenvelope {
#endif  // __Fuchsia__

}  // namespace fidl_test_requestflexibleenvelope
#ifdef __Fuchsia__
::fidl::WireResult<::fidl_test_requestflexibleenvelope::Protocol::
                       RequestStrictResponseFlexible>
fidl::internal::WireClientImpl<::fidl_test_requestflexibleenvelope::Protocol>::
    RequestStrictResponseFlexible_Sync(
        ::fidl_test_requestflexibleenvelope::wire::StrictFoo s) {
  if (auto _channel = ::fidl::internal::ClientBase::GetChannel()) {
    return ::fidl::WireResult<::fidl_test_requestflexibleenvelope::Protocol::
                                  RequestStrictResponseFlexible>(
        ::fidl::UnownedClientEnd<::fidl_test_requestflexibleenvelope::Protocol>(
            _channel->handle()),
        s);
  }
  return ::fidl::WireResult<::fidl_test_requestflexibleenvelope::Protocol::
                                RequestStrictResponseFlexible>(
      ::fidl::Result(ZX_ERR_CANCELED, ::fidl::kErrorChannelUnbound));
}
#endif  // __Fuchsia__

#ifdef __Fuchsia__
::fidl::WireUnownedResult<::fidl_test_requestflexibleenvelope::Protocol::
                              RequestStrictResponseFlexible>
fidl::internal::WireClientImpl<::fidl_test_requestflexibleenvelope::Protocol>::
    RequestStrictResponseFlexible_Sync(
        ::fidl::BufferSpan _request_buffer,
        ::fidl_test_requestflexibleenvelope::wire::StrictFoo s,
        ::fidl::BufferSpan _response_buffer) {
  if (auto _channel = ::fidl::internal::ClientBase::GetChannel()) {
    return ::fidl::WireUnownedResult<
        ::fidl_test_requestflexibleenvelope::Protocol::
            RequestStrictResponseFlexible>(
        ::fidl::UnownedClientEnd<::fidl_test_requestflexibleenvelope::Protocol>(
            _channel->handle()),
        _request_buffer.data, _request_buffer.capacity, s,
        _response_buffer.data, _response_buffer.capacity);
  }
  return ::fidl::WireUnownedResult<::fidl_test_requestflexibleenvelope::
                                       Protocol::RequestStrictResponseFlexible>(
      ::fidl::Result(ZX_ERR_CANCELED, ::fidl::kErrorChannelUnbound));
}
#endif  // __Fuchsia__

#ifdef __Fuchsia__

::fidl::WireResponseContext<
    ::fidl_test_requestflexibleenvelope::Protocol::
        RequestStrictResponseFlexible>::WireResponseContext()
    : ::fidl::internal::ResponseContext(
          ::fidl::WireResponse<::fidl_test_requestflexibleenvelope::Protocol::
                                   RequestStrictResponseFlexible>::Type,
          ::fidl_test_requestflexibleenvelope::
              kProtocol_RequestStrictResponseFlexible_Ordinal) {}

void ::fidl::WireResponseContext<
    ::fidl_test_requestflexibleenvelope::Protocol::
        RequestStrictResponseFlexible>::OnReply(uint8_t* reply) {
  OnReply(reinterpret_cast<
          ::fidl::WireResponse<::fidl_test_requestflexibleenvelope::Protocol::
                                   RequestStrictResponseFlexible>*>(reply));
}
#endif  // __Fuchsia__

#ifdef __Fuchsia__
::fidl::Result
fidl::internal::WireClientImpl<::fidl_test_requestflexibleenvelope::Protocol>::
    RequestStrictResponseFlexible(
        ::fidl_test_requestflexibleenvelope::wire::StrictFoo s,
        ::fit::callback<void(
            ::fidl::WireResponse<::fidl_test_requestflexibleenvelope::Protocol::
                                     RequestStrictResponseFlexible>* response)>
            _cb) {
  class ResponseContext final
      : public ::fidl::WireResponseContext<
            ::fidl_test_requestflexibleenvelope::Protocol::
                RequestStrictResponseFlexible> {
   public:
    ResponseContext(
        ::fit::callback<void(
            ::fidl::WireResponse<::fidl_test_requestflexibleenvelope::Protocol::
                                     RequestStrictResponseFlexible>* response)>
            cb)
        : cb_(std::move(cb)) {}

    void OnReply(
        ::fidl::WireResponse<::fidl_test_requestflexibleenvelope::Protocol::
                                 RequestStrictResponseFlexible>* response)
        override {
      cb_(response);

      delete this;
    }

    void OnError() override { delete this; }

   private:
    ::fit::callback<void(
        ::fidl::WireResponse<::fidl_test_requestflexibleenvelope::Protocol::
                                 RequestStrictResponseFlexible>* response)>
        cb_;
  };

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

::fidl::Result
fidl::internal::WireClientImpl<::fidl_test_requestflexibleenvelope::Protocol>::
    RequestStrictResponseFlexible(
        ::fidl::BufferSpan _request_buffer,
        ::fidl_test_requestflexibleenvelope::wire::StrictFoo s,
        ::fidl::WireResponseContext<
            ::fidl_test_requestflexibleenvelope::Protocol::
                RequestStrictResponseFlexible>* _context) {
  ::fidl::internal::ClientBase::PrepareAsyncTxn(_context);

  ::fidl::WireRequest<::fidl_test_requestflexibleenvelope::Protocol::
                          RequestStrictResponseFlexible>::UnownedEncodedMessage
      _request(_request_buffer.data, _request_buffer.capacity, _context->Txid(),
               s);
  return _request.GetOutgoingMessage().Write(this, _context);
}
#endif  // __Fuchsia__

#ifdef __Fuchsia__
::fidl::WireResult<::fidl_test_requestflexibleenvelope::Protocol::
                       RequestFlexibleResponseStrict>
fidl::internal::WireClientImpl<::fidl_test_requestflexibleenvelope::Protocol>::
    RequestFlexibleResponseStrict_Sync(
        ::fidl_test_requestflexibleenvelope::wire::FlexibleFoo s) {
  if (auto _channel = ::fidl::internal::ClientBase::GetChannel()) {
    return ::fidl::WireResult<::fidl_test_requestflexibleenvelope::Protocol::
                                  RequestFlexibleResponseStrict>(
        ::fidl::UnownedClientEnd<::fidl_test_requestflexibleenvelope::Protocol>(
            _channel->handle()),
        s);
  }
  return ::fidl::WireResult<::fidl_test_requestflexibleenvelope::Protocol::
                                RequestFlexibleResponseStrict>(
      ::fidl::Result(ZX_ERR_CANCELED, ::fidl::kErrorChannelUnbound));
}
#endif  // __Fuchsia__

#ifdef __Fuchsia__
::fidl::WireUnownedResult<::fidl_test_requestflexibleenvelope::Protocol::
                              RequestFlexibleResponseStrict>
fidl::internal::WireClientImpl<::fidl_test_requestflexibleenvelope::Protocol>::
    RequestFlexibleResponseStrict_Sync(
        ::fidl::BufferSpan _request_buffer,
        ::fidl_test_requestflexibleenvelope::wire::FlexibleFoo s,
        ::fidl::BufferSpan _response_buffer) {
  if (auto _channel = ::fidl::internal::ClientBase::GetChannel()) {
    return ::fidl::WireUnownedResult<
        ::fidl_test_requestflexibleenvelope::Protocol::
            RequestFlexibleResponseStrict>(
        ::fidl::UnownedClientEnd<::fidl_test_requestflexibleenvelope::Protocol>(
            _channel->handle()),
        _request_buffer.data, _request_buffer.capacity, s,
        _response_buffer.data, _response_buffer.capacity);
  }
  return ::fidl::WireUnownedResult<::fidl_test_requestflexibleenvelope::
                                       Protocol::RequestFlexibleResponseStrict>(
      ::fidl::Result(ZX_ERR_CANCELED, ::fidl::kErrorChannelUnbound));
}
#endif  // __Fuchsia__

#ifdef __Fuchsia__

::fidl::WireResponseContext<
    ::fidl_test_requestflexibleenvelope::Protocol::
        RequestFlexibleResponseStrict>::WireResponseContext()
    : ::fidl::internal::ResponseContext(
          ::fidl::WireResponse<::fidl_test_requestflexibleenvelope::Protocol::
                                   RequestFlexibleResponseStrict>::Type,
          ::fidl_test_requestflexibleenvelope::
              kProtocol_RequestFlexibleResponseStrict_Ordinal) {}

void ::fidl::WireResponseContext<
    ::fidl_test_requestflexibleenvelope::Protocol::
        RequestFlexibleResponseStrict>::OnReply(uint8_t* reply) {
  OnReply(reinterpret_cast<
          ::fidl::WireResponse<::fidl_test_requestflexibleenvelope::Protocol::
                                   RequestFlexibleResponseStrict>*>(reply));
}
#endif  // __Fuchsia__

#ifdef __Fuchsia__
::fidl::Result
fidl::internal::WireClientImpl<::fidl_test_requestflexibleenvelope::Protocol>::
    RequestFlexibleResponseStrict(
        ::fidl_test_requestflexibleenvelope::wire::FlexibleFoo s,
        ::fit::callback<void(
            ::fidl::WireResponse<::fidl_test_requestflexibleenvelope::Protocol::
                                     RequestFlexibleResponseStrict>* response)>
            _cb) {
  class ResponseContext final
      : public ::fidl::WireResponseContext<
            ::fidl_test_requestflexibleenvelope::Protocol::
                RequestFlexibleResponseStrict> {
   public:
    ResponseContext(
        ::fit::callback<void(
            ::fidl::WireResponse<::fidl_test_requestflexibleenvelope::Protocol::
                                     RequestFlexibleResponseStrict>* response)>
            cb)
        : cb_(std::move(cb)) {}

    void OnReply(
        ::fidl::WireResponse<::fidl_test_requestflexibleenvelope::Protocol::
                                 RequestFlexibleResponseStrict>* response)
        override {
      cb_(response);

      delete this;
    }

    void OnError() override { delete this; }

   private:
    ::fit::callback<void(
        ::fidl::WireResponse<::fidl_test_requestflexibleenvelope::Protocol::
                                 RequestFlexibleResponseStrict>* response)>
        cb_;
  };

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

::fidl::Result
fidl::internal::WireClientImpl<::fidl_test_requestflexibleenvelope::Protocol>::
    RequestFlexibleResponseStrict(
        ::fidl::BufferSpan _request_buffer,
        ::fidl_test_requestflexibleenvelope::wire::FlexibleFoo s,
        ::fidl::WireResponseContext<
            ::fidl_test_requestflexibleenvelope::Protocol::
                RequestFlexibleResponseStrict>* _context) {
  ::fidl::internal::ClientBase::PrepareAsyncTxn(_context);

  ::fidl::WireRequest<::fidl_test_requestflexibleenvelope::Protocol::
                          RequestFlexibleResponseStrict>::UnownedEncodedMessage
      _request(_request_buffer.data, _request_buffer.capacity, _context->Txid(),
               s);
  return _request.GetOutgoingMessage().Write(this, _context);
}
#endif  // __Fuchsia__

#ifdef __Fuchsia__
std::optional<::fidl::UnbindInfo>
fidl::internal::WireClientImpl<::fidl_test_requestflexibleenvelope::Protocol>::
    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::WireServerDispatcher<
    ::fidl_test_requestflexibleenvelope::Protocol>::
    TryDispatch(
        ::fidl::WireServer<::fidl_test_requestflexibleenvelope::Protocol>* impl,
        fidl_incoming_msg_t* msg, ::fidl::Transaction* txn) {
  static const ::fidl::internal::MethodEntry entries[] = {
      {
          ::fidl_test_requestflexibleenvelope::
              kProtocol_RequestStrictResponseFlexible_Ordinal,
          ::fidl::WireRequest<::fidl_test_requestflexibleenvelope::Protocol::
                                  RequestStrictResponseFlexible>::Type,
          [](void* interface, void* bytes, ::fidl::Transaction* txn) {
            ::fidl::WireServer<::fidl_test_requestflexibleenvelope::Protocol>::
                RequestStrictResponseFlexibleCompleter::Sync completer(txn);
            reinterpret_cast<::fidl::WireServer<
                ::fidl_test_requestflexibleenvelope::Protocol>*>(interface)
                ->RequestStrictResponseFlexible(
                    reinterpret_cast<::fidl::WireRequest<
                        ::fidl_test_requestflexibleenvelope::Protocol::
                            RequestStrictResponseFlexible>*>(bytes),
                    completer);
          },
      },
      {
          ::fidl_test_requestflexibleenvelope::
              kProtocol_RequestFlexibleResponseStrict_Ordinal,
          ::fidl::WireRequest<::fidl_test_requestflexibleenvelope::Protocol::
                                  RequestFlexibleResponseStrict>::Type,
          [](void* interface, void* bytes, ::fidl::Transaction* txn) {
            ::fidl::WireServer<::fidl_test_requestflexibleenvelope::Protocol>::
                RequestFlexibleResponseStrictCompleter::Sync completer(txn);
            reinterpret_cast<::fidl::WireServer<
                ::fidl_test_requestflexibleenvelope::Protocol>*>(interface)
                ->RequestFlexibleResponseStrict(
                    reinterpret_cast<::fidl::WireRequest<
                        ::fidl_test_requestflexibleenvelope::Protocol::
                            RequestFlexibleResponseStrict>*>(bytes),
                    completer);
          },
      },
  };
  return ::fidl::internal::TryDispatch(
      impl, msg, txn, entries,
      entries + sizeof(entries) / sizeof(::fidl::internal::MethodEntry));
}

::fidl::DispatchResult fidl::internal::WireServerDispatcher<
    ::fidl_test_requestflexibleenvelope::Protocol>::
    Dispatch(
        ::fidl::WireServer<::fidl_test_requestflexibleenvelope::Protocol>* 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::
    WireServer<::fidl_test_requestflexibleenvelope::Protocol>::dispatch_message(
        fidl_incoming_msg_t* msg, ::fidl::Transaction* txn) {
  return ::fidl::internal::WireServerDispatcher<
      ::fidl_test_requestflexibleenvelope::Protocol>::Dispatch(this, msg, txn);
}

::fidl::DispatchResult fidl::internal::
    WireDispatcher<::fidl_test_requestflexibleenvelope::Protocol>::TryDispatch(
        ::fidl::WireInterface<::fidl_test_requestflexibleenvelope::Protocol>*
            impl,
        fidl_incoming_msg_t* msg, ::fidl::Transaction* txn) {
  static const ::fidl::internal::MethodEntry entries[] = {
      {
          ::fidl_test_requestflexibleenvelope::
              kProtocol_RequestStrictResponseFlexible_Ordinal,
          ::fidl::WireRequest<::fidl_test_requestflexibleenvelope::Protocol::
                                  RequestStrictResponseFlexible>::Type,
          [](void* interface, void* bytes, ::fidl::Transaction* txn) {
            auto message = reinterpret_cast<::fidl::WireRequest<
                ::fidl_test_requestflexibleenvelope::Protocol::
                    RequestStrictResponseFlexible>*>(bytes);
            ::fidl::WireServer<::fidl_test_requestflexibleenvelope::Protocol>::
                RequestStrictResponseFlexibleCompleter::Sync completer(txn);
            reinterpret_cast<::fidl::WireInterface<
                ::fidl_test_requestflexibleenvelope::Protocol>*>(interface)
                ->RequestStrictResponseFlexible(std::move(message->s),
                                                completer);
          },
      },
      {
          ::fidl_test_requestflexibleenvelope::
              kProtocol_RequestFlexibleResponseStrict_Ordinal,
          ::fidl::WireRequest<::fidl_test_requestflexibleenvelope::Protocol::
                                  RequestFlexibleResponseStrict>::Type,
          [](void* interface, void* bytes, ::fidl::Transaction* txn) {
            auto message = reinterpret_cast<::fidl::WireRequest<
                ::fidl_test_requestflexibleenvelope::Protocol::
                    RequestFlexibleResponseStrict>*>(bytes);
            ::fidl::WireServer<::fidl_test_requestflexibleenvelope::Protocol>::
                RequestFlexibleResponseStrictCompleter::Sync completer(txn);
            reinterpret_cast<::fidl::WireInterface<
                ::fidl_test_requestflexibleenvelope::Protocol>*>(interface)
                ->RequestFlexibleResponseStrict(std::move(message->s),
                                                completer);
          },
      },
  };
  return ::fidl::internal::TryDispatch(
      impl, msg, txn, entries,
      entries + sizeof(entries) / sizeof(::fidl::internal::MethodEntry));
}

::fidl::DispatchResult fidl::internal::
    WireDispatcher<::fidl_test_requestflexibleenvelope::Protocol>::Dispatch(
        ::fidl::WireInterface<::fidl_test_requestflexibleenvelope::Protocol>*
            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_requestflexibleenvelope::Protocol>::
    dispatch_message(fidl_incoming_msg_t* msg, ::fidl::Transaction* txn) {
  return ::fidl::internal::WireDispatcher<
      ::fidl_test_requestflexibleenvelope::Protocol>::Dispatch(this, msg, txn);
}
#endif  // __Fuchsia__

#ifdef __Fuchsia__
::fidl::Result fidl::WireServer<::fidl_test_requestflexibleenvelope::Protocol>::
    RequestStrictResponseFlexibleCompleterBase::Reply(
        ::fidl_test_requestflexibleenvelope::wire::FlexibleFoo f) {
  ::fidl::OwnedEncodedMessage<
      ::fidl::WireResponse<::fidl_test_requestflexibleenvelope::Protocol::
                               RequestStrictResponseFlexible>>
      _response{f};
  return ::fidl::WireServer<::fidl_test_requestflexibleenvelope::Protocol>::
      RequestStrictResponseFlexibleCompleterBase::SendReply(
          &_response.GetOutgoingMessage());
}
#endif  // __Fuchsia__

#ifdef __Fuchsia__
::fidl::Result fidl::WireServer<::fidl_test_requestflexibleenvelope::Protocol>::
    RequestStrictResponseFlexibleCompleterBase::Reply(
        ::fidl::BufferSpan _backing_buffer,
        ::fidl_test_requestflexibleenvelope::wire::FlexibleFoo f) {
  ::fidl::WireResponse<::fidl_test_requestflexibleenvelope::Protocol::
                           RequestStrictResponseFlexible>::UnownedEncodedMessage
      _response(_backing_buffer.data, _backing_buffer.capacity, f);
  return CompleterBase::SendReply(&_response.GetOutgoingMessage());
}
#endif  // __Fuchsia__

#ifdef __Fuchsia__
::fidl::Result fidl::WireServer<::fidl_test_requestflexibleenvelope::Protocol>::
    RequestFlexibleResponseStrictCompleterBase::Reply(
        ::fidl_test_requestflexibleenvelope::wire::StrictFoo f) {
  ::fidl::OwnedEncodedMessage<
      ::fidl::WireResponse<::fidl_test_requestflexibleenvelope::Protocol::
                               RequestFlexibleResponseStrict>>
      _response{f};
  return ::fidl::WireServer<::fidl_test_requestflexibleenvelope::Protocol>::
      RequestFlexibleResponseStrictCompleterBase::SendReply(
          &_response.GetOutgoingMessage());
}
#endif  // __Fuchsia__

#ifdef __Fuchsia__
::fidl::Result fidl::WireServer<::fidl_test_requestflexibleenvelope::Protocol>::
    RequestFlexibleResponseStrictCompleterBase::Reply(
        ::fidl::BufferSpan _backing_buffer,
        ::fidl_test_requestflexibleenvelope::wire::StrictFoo f) {
  ::fidl::WireResponse<::fidl_test_requestflexibleenvelope::Protocol::
                           RequestFlexibleResponseStrict>::UnownedEncodedMessage
      _response(_backing_buffer.data, _backing_buffer.capacity, f);
  return CompleterBase::SendReply(&_response.GetOutgoingMessage());
}
#endif  // __Fuchsia__

void ::fidl::WireRequest<
    ::fidl_test_requestflexibleenvelope::Protocol::
        RequestStrictResponseFlexible>::_InitHeader(zx_txid_t _txid) {
  fidl_init_txn_header(&_hdr, _txid,
                       ::fidl_test_requestflexibleenvelope::
                           kProtocol_RequestStrictResponseFlexible_Ordinal);
}

void ::fidl::WireResponse<::fidl_test_requestflexibleenvelope::Protocol::
                              RequestStrictResponseFlexible>::_InitHeader() {
  fidl_init_txn_header(&_hdr, 0,
                       ::fidl_test_requestflexibleenvelope::
                           kProtocol_RequestStrictResponseFlexible_Ordinal);
}

void ::fidl::WireRequest<
    ::fidl_test_requestflexibleenvelope::Protocol::
        RequestFlexibleResponseStrict>::_InitHeader(zx_txid_t _txid) {
  fidl_init_txn_header(&_hdr, _txid,
                       ::fidl_test_requestflexibleenvelope::
                           kProtocol_RequestFlexibleResponseStrict_Ordinal);
}

void ::fidl::WireResponse<::fidl_test_requestflexibleenvelope::Protocol::
                              RequestFlexibleResponseStrict>::_InitHeader() {
  fidl_init_txn_header(&_hdr, 0,
                       ::fidl_test_requestflexibleenvelope::
                           kProtocol_RequestFlexibleResponseStrict_Ordinal);
}

#ifdef __Fuchsia__

#endif  // __Fuchsia__
