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

#include <fidl/test.protocolpayloads/cpp/wire_messaging.h>

#include <memory>

namespace test_protocolpayloads {
[[maybe_unused]] constexpr uint64_t kMainProtocol_OneWayComposed_Ordinal =
    2602591870026304272lu;

[[maybe_unused]] constexpr ::fidl::MessageDynamicFlags
    kMainProtocol_OneWayComposed_DynamicFlags =
        ::fidl::MessageDynamicFlags::kStrictMethod;

extern "C" const fidl_type_t
    test_protocolpayloads_imported_ImportStructPayloadTable;

[[maybe_unused]] constexpr uint64_t kMainProtocol_TwoWayComposed_Ordinal =
    2542459230546612144lu;

[[maybe_unused]] constexpr ::fidl::MessageDynamicFlags
    kMainProtocol_TwoWayComposed_DynamicFlags =
        ::fidl::MessageDynamicFlags::kStrictMethod;

extern "C" const fidl_type_t
    test_protocolpayloads_imported_ImportStructPayloadTable;

extern "C" const fidl_type_t
    test_protocolpayloads_imported_ImportStructPayloadTable;

[[maybe_unused]] constexpr uint64_t
    kMainProtocol_TwoWayComposedWithError_Ordinal = 7681984876526769495lu;

[[maybe_unused]] constexpr ::fidl::MessageDynamicFlags
    kMainProtocol_TwoWayComposedWithError_DynamicFlags =
        ::fidl::MessageDynamicFlags::kStrictMethod;

extern "C" const fidl_type_t
    test_protocolpayloads_imported_ImportStructPayloadTable;

extern "C" const fidl_type_t
    test_protocolpayloads_imported_ComposedProtocolTwoWayComposedWithErrorTopResponseTable;

[[maybe_unused]] constexpr uint64_t kMainProtocol_OnComposed_Ordinal =
    1872339328378152762lu;

[[maybe_unused]] constexpr ::fidl::MessageDynamicFlags
    kMainProtocol_OnComposed_DynamicFlags =
        ::fidl::MessageDynamicFlags::kStrictMethod;

extern "C" const fidl_type_t
    test_protocolpayloads_imported_ImportStructPayloadTable;

[[maybe_unused]] constexpr uint64_t kMainProtocol_OnComposedWithError_Ordinal =
    7167282778061495960lu;

[[maybe_unused]] constexpr ::fidl::MessageDynamicFlags
    kMainProtocol_OnComposedWithError_DynamicFlags =
        ::fidl::MessageDynamicFlags::kStrictMethod;

extern "C" const fidl_type_t
    test_protocolpayloads_imported_ComposedProtocolOnComposedWithErrorRequestTable;

[[maybe_unused]] constexpr uint64_t kMainProtocol_OneWayLocal_Ordinal =
    7755175439334311701lu;

[[maybe_unused]] constexpr ::fidl::MessageDynamicFlags
    kMainProtocol_OneWayLocal_DynamicFlags =
        ::fidl::MessageDynamicFlags::kStrictMethod;

extern "C" const fidl_type_t test_protocolpayloads_LocalStructPayloadTable;

[[maybe_unused]] constexpr uint64_t kMainProtocol_TwoWayLocal_Ordinal =
    8374292137648566031lu;

[[maybe_unused]] constexpr ::fidl::MessageDynamicFlags
    kMainProtocol_TwoWayLocal_DynamicFlags =
        ::fidl::MessageDynamicFlags::kStrictMethod;

extern "C" const fidl_type_t test_protocolpayloads_LocalStructPayloadTable;

extern "C" const fidl_type_t test_protocolpayloads_LocalStructPayloadTable;

[[maybe_unused]] constexpr uint64_t kMainProtocol_TwoWayLocalWithError_Ordinal =
    2898559119954589948lu;

[[maybe_unused]] constexpr ::fidl::MessageDynamicFlags
    kMainProtocol_TwoWayLocalWithError_DynamicFlags =
        ::fidl::MessageDynamicFlags::kStrictMethod;

extern "C" const fidl_type_t test_protocolpayloads_LocalStructPayloadTable;

extern "C" const fidl_type_t
    test_protocolpayloads_MainProtocolTwoWayLocalWithErrorTopResponseTable;

[[maybe_unused]] constexpr uint64_t kMainProtocol_OnLocal_Ordinal =
    5135782819583756313lu;

[[maybe_unused]] constexpr ::fidl::MessageDynamicFlags
    kMainProtocol_OnLocal_DynamicFlags =
        ::fidl::MessageDynamicFlags::kStrictMethod;

extern "C" const fidl_type_t test_protocolpayloads_LocalStructPayloadTable;

[[maybe_unused]] constexpr uint64_t kMainProtocol_OnLocalWithError_Ordinal =
    5678277415565140399lu;

[[maybe_unused]] constexpr ::fidl::MessageDynamicFlags
    kMainProtocol_OnLocalWithError_DynamicFlags =
        ::fidl::MessageDynamicFlags::kStrictMethod;

extern "C" const fidl_type_t
    test_protocolpayloads_MainProtocolOnLocalWithErrorRequestTable;

[[maybe_unused]] constexpr uint64_t kMainProtocol_OneWayImport_Ordinal =
    3344777159365288972lu;

[[maybe_unused]] constexpr ::fidl::MessageDynamicFlags
    kMainProtocol_OneWayImport_DynamicFlags =
        ::fidl::MessageDynamicFlags::kStrictMethod;

extern "C" const fidl_type_t
    test_protocolpayloads_imported_ImportStructPayloadTable;

[[maybe_unused]] constexpr uint64_t kMainProtocol_TwoWayImport_Ordinal =
    2374708679656510579lu;

[[maybe_unused]] constexpr ::fidl::MessageDynamicFlags
    kMainProtocol_TwoWayImport_DynamicFlags =
        ::fidl::MessageDynamicFlags::kStrictMethod;

extern "C" const fidl_type_t
    test_protocolpayloads_imported_ImportStructPayloadTable;

extern "C" const fidl_type_t
    test_protocolpayloads_imported_ImportStructPayloadTable;

[[maybe_unused]] constexpr uint64_t
    kMainProtocol_TwoWayImportWithError_Ordinal = 4286143084949642173lu;

[[maybe_unused]] constexpr ::fidl::MessageDynamicFlags
    kMainProtocol_TwoWayImportWithError_DynamicFlags =
        ::fidl::MessageDynamicFlags::kStrictMethod;

extern "C" const fidl_type_t
    test_protocolpayloads_imported_ImportStructPayloadTable;

extern "C" const fidl_type_t
    test_protocolpayloads_MainProtocolTwoWayImportWithErrorTopResponseTable;

[[maybe_unused]] constexpr uint64_t kMainProtocol_OnImport_Ordinal =
    1996489653379631369lu;

[[maybe_unused]] constexpr ::fidl::MessageDynamicFlags
    kMainProtocol_OnImport_DynamicFlags =
        ::fidl::MessageDynamicFlags::kStrictMethod;

extern "C" const fidl_type_t
    test_protocolpayloads_imported_ImportStructPayloadTable;

[[maybe_unused]] constexpr uint64_t kMainProtocol_OnImportWithError_Ordinal =
    7102941407914553861lu;

[[maybe_unused]] constexpr ::fidl::MessageDynamicFlags
    kMainProtocol_OnImportWithError_DynamicFlags =
        ::fidl::MessageDynamicFlags::kStrictMethod;

extern "C" const fidl_type_t
    test_protocolpayloads_MainProtocolOnImportWithErrorRequestTable;

[[maybe_unused]] constexpr uint64_t kMainProtocol_OneWayAnon_Ordinal =
    811587311021806764lu;

[[maybe_unused]] constexpr ::fidl::MessageDynamicFlags
    kMainProtocol_OneWayAnon_DynamicFlags =
        ::fidl::MessageDynamicFlags::kStrictMethod;

extern "C" const fidl_type_t
    test_protocolpayloads_MainProtocolOneWayAnonRequestTable;

[[maybe_unused]] constexpr uint64_t kMainProtocol_TwoWayAnon_Ordinal =
    629880979996923737lu;

[[maybe_unused]] constexpr ::fidl::MessageDynamicFlags
    kMainProtocol_TwoWayAnon_DynamicFlags =
        ::fidl::MessageDynamicFlags::kStrictMethod;

extern "C" const fidl_type_t
    test_protocolpayloads_MainProtocolTwoWayAnonRequestTable;

extern "C" const fidl_type_t
    test_protocolpayloads_MainProtocolTwoWayAnonTopResponseTable;

[[maybe_unused]] constexpr uint64_t kMainProtocol_TwoWayAnonWithError_Ordinal =
    6368863385719175734lu;

[[maybe_unused]] constexpr ::fidl::MessageDynamicFlags
    kMainProtocol_TwoWayAnonWithError_DynamicFlags =
        ::fidl::MessageDynamicFlags::kStrictMethod;

extern "C" const fidl_type_t
    test_protocolpayloads_MainProtocolTwoWayAnonWithErrorRequestTable;

extern "C" const fidl_type_t
    test_protocolpayloads_MainProtocolTwoWayAnonWithErrorTopResponseTable;

[[maybe_unused]] constexpr uint64_t kMainProtocol_OnAnon_Ordinal =
    4815229650203439104lu;

[[maybe_unused]] constexpr ::fidl::MessageDynamicFlags
    kMainProtocol_OnAnon_DynamicFlags =
        ::fidl::MessageDynamicFlags::kStrictMethod;

extern "C" const fidl_type_t
    test_protocolpayloads_MainProtocolOnAnonRequestTable;

[[maybe_unused]] constexpr uint64_t kMainProtocol_OnAnonWithError_Ordinal =
    5024931894357412354lu;

[[maybe_unused]] constexpr ::fidl::MessageDynamicFlags
    kMainProtocol_OnAnonWithError_DynamicFlags =
        ::fidl::MessageDynamicFlags::kStrictMethod;

extern "C" const fidl_type_t
    test_protocolpayloads_MainProtocolOnAnonWithErrorRequestTable;
#ifdef __Fuchsia__
}  // namespace test_protocolpayloads
::fidl::WireResult<::test_protocolpayloads::MainProtocol::OneWayComposed>::
    WireResult(
        ::fidl::UnownedClientEnd<::test_protocolpayloads::MainProtocol> client,
        ::fidl::internal::TransactionalRequest<
            ::test_protocolpayloads::MainProtocol::OneWayComposed>* request) {
  FIDL_INTERNAL_DISABLE_AUTO_VAR_INIT
  ::fidl::unstable::OwnedEncodedMessage<
      ::fidl::internal::TransactionalRequest<
          ::test_protocolpayloads::MainProtocol::OneWayComposed>,
      ::fidl::internal::ChannelTransport>
      request_message(::fidl::internal::AllowUnownedInputRef{}, request);
  auto& outgoing = request_message.GetOutgoingMessage();
  outgoing.Write(client.handle());
  SetStatus(outgoing);
}
namespace test_protocolpayloads {
#endif  // __Fuchsia__

#ifdef __Fuchsia__
}  // namespace test_protocolpayloads
::fidl::WireUnownedResult<
    ::test_protocolpayloads::MainProtocol::OneWayComposed>::
    WireUnownedResult(
        ::fidl::UnownedClientEnd<::test_protocolpayloads::MainProtocol>
            client_end,
        ::fidl::internal::AnyBufferAllocator& allocator,
        ::fidl::internal::TransactionalRequest<
            ::test_protocolpayloads::MainProtocol::OneWayComposed>* request) {
  constexpr uint32_t buffer_size = ::fidl::SyncClientMethodBufferSizeInChannel<
      ::test_protocolpayloads::MainProtocol::OneWayComposed>();
  ::fitx::result<::fidl::Error, ::fidl::BufferSpan> allocation =
      allocator.TryAllocate(buffer_size);
  if (!allocation.is_ok()) {
    ::fidl::Status::operator=(allocation.error_value());
    return;
  }
  uint8_t* buffer = allocation->data;
  uint32_t request_byte_capacity = buffer_size;
  uint8_t* request_bytes = buffer;

  ::fidl::unstable::UnownedEncodedMessage<
      ::fidl::internal::TransactionalRequest<
          ::test_protocolpayloads::MainProtocol::OneWayComposed>>
      request_message(request_bytes, request_byte_capacity, request);
  auto& outgoing = request_message.GetOutgoingMessage();
  outgoing.Write(client_end.handle());
  ::fidl::Status::operator=(outgoing);
}
namespace test_protocolpayloads {
#endif  // __Fuchsia__

#ifdef __Fuchsia__
}  // namespace test_protocolpayloads
::fidl::WireResult<::test_protocolpayloads::MainProtocol::TwoWayComposed>::
    WireResult(
        ::fidl::UnownedClientEnd<::test_protocolpayloads::MainProtocol> client,
        ::fidl::internal::TransactionalRequest<
            ::test_protocolpayloads::MainProtocol::TwoWayComposed>* request) {
  FIDL_INTERNAL_DISABLE_AUTO_VAR_INIT
  ::fidl::unstable::OwnedEncodedMessage<
      ::fidl::internal::TransactionalRequest<
          ::test_protocolpayloads::MainProtocol::TwoWayComposed>,
      ::fidl::internal::ChannelTransport>
      request_message(::fidl::internal::AllowUnownedInputRef{}, request);
  auto& outgoing = request_message.GetOutgoingMessage();
  outgoing.Call<::fidl::internal::TransactionalResponse<
      ::test_protocolpayloads::MainProtocol::TwoWayComposed>>(
      client.handle(), bytes_.data(), static_cast<uint32_t>(bytes_.size()));
  SetStatus(outgoing);
}

::fidl::WireResult<::test_protocolpayloads::MainProtocol::TwoWayComposed>::
    WireResult(
        ::fidl::UnownedClientEnd<::test_protocolpayloads::MainProtocol> client,
        ::fidl::internal::TransactionalRequest<
            ::test_protocolpayloads::MainProtocol::TwoWayComposed>* request,
        zx_time_t deadline) {
  FIDL_INTERNAL_DISABLE_AUTO_VAR_INIT
  ::fidl::unstable::OwnedEncodedMessage<
      ::fidl::internal::TransactionalRequest<
          ::test_protocolpayloads::MainProtocol::TwoWayComposed>,
      ::fidl::internal::ChannelTransport>
      request_message(::fidl::internal::AllowUnownedInputRef{}, request);
  auto& outgoing = request_message.GetOutgoingMessage();
  outgoing.Call<::fidl::internal::TransactionalResponse<
      ::test_protocolpayloads::MainProtocol::TwoWayComposed>>(
      client.handle(), bytes_.data(), static_cast<uint32_t>(bytes_.size()),
      fidl::CallOptions{.deadline = deadline});
  SetStatus(outgoing);
}
namespace test_protocolpayloads {
#endif  // __Fuchsia__

#ifdef __Fuchsia__
}  // namespace test_protocolpayloads
::fidl::WireUnownedResult<
    ::test_protocolpayloads::MainProtocol::TwoWayComposed>::
    WireUnownedResult(
        ::fidl::UnownedClientEnd<::test_protocolpayloads::MainProtocol>
            client_end,
        ::fidl::internal::AnyBufferAllocator& allocator,
        ::fidl::internal::TransactionalRequest<
            ::test_protocolpayloads::MainProtocol::TwoWayComposed>* request) {
  constexpr uint32_t buffer_size = ::fidl::SyncClientMethodBufferSizeInChannel<
      ::test_protocolpayloads::MainProtocol::TwoWayComposed>();
  ::fitx::result<::fidl::Error, ::fidl::BufferSpan> allocation =
      allocator.TryAllocate(buffer_size);
  if (!allocation.is_ok()) {
    ::fidl::Status::operator=(allocation.error_value());
    return;
  }
  uint8_t* buffer = allocation->data;
  constexpr uint32_t request_byte_capacity = ::fidl::MaxSizeInChannel<
      ::fidl::internal::TransactionalRequest<
          ::test_protocolpayloads::MainProtocol::TwoWayComposed>,
      ::fidl::MessageDirection::kSending>();
  uint8_t* request_bytes = buffer;
  static_assert(buffer_size > request_byte_capacity);
  uint32_t response_byte_capacity = buffer_size - request_byte_capacity;
  uint8_t* response_bytes = &buffer[request_byte_capacity];

  ::fidl::unstable::UnownedEncodedMessage<
      ::fidl::internal::TransactionalRequest<
          ::test_protocolpayloads::MainProtocol::TwoWayComposed>>
      request_message(request_bytes, request_byte_capacity, request);
  auto& outgoing = request_message.GetOutgoingMessage();
  outgoing.Call<::fidl::internal::TransactionalResponse<
      ::test_protocolpayloads::MainProtocol::TwoWayComposed>>(
      client_end.handle(), response_bytes, response_byte_capacity);
  bytes_ = response_bytes;
  ::fidl::Status::operator=(outgoing);
}
namespace test_protocolpayloads {
#endif  // __Fuchsia__

#ifdef __Fuchsia__
}  // namespace test_protocolpayloads
::fidl::WireResult<
    ::test_protocolpayloads::MainProtocol::TwoWayComposedWithError>::
    WireResult(
        ::fidl::UnownedClientEnd<::test_protocolpayloads::MainProtocol> client,
        ::fidl::internal::TransactionalRequest<
            ::test_protocolpayloads::MainProtocol::TwoWayComposedWithError>*
            request) {
  FIDL_INTERNAL_DISABLE_AUTO_VAR_INIT
  ::fidl::unstable::OwnedEncodedMessage<
      ::fidl::internal::TransactionalRequest<
          ::test_protocolpayloads::MainProtocol::TwoWayComposedWithError>,
      ::fidl::internal::ChannelTransport>
      request_message(::fidl::internal::AllowUnownedInputRef{}, request);
  auto& outgoing = request_message.GetOutgoingMessage();
  outgoing.Call<::fidl::internal::TransactionalResponse<
      ::test_protocolpayloads::MainProtocol::TwoWayComposedWithError>>(
      client.handle(), bytes_.data(), static_cast<uint32_t>(bytes_.size()));
  SetStatus(outgoing);
  if (ok()) {
    auto* raw_response = reinterpret_cast<::fidl::WireResponse<
        ::test_protocolpayloads::MainProtocol::TwoWayComposedWithError>*>(
        bytes_.data() + sizeof(fidl_message_header_t));
    if (raw_response->result.is_err()) {
      result_ = fitx::error(raw_response->result.err());
    } else if (raw_response->result.is_response()) {
      result_ = fitx::ok(&(raw_response->result.response()));
    }
  }
}

::fidl::WireResult<
    ::test_protocolpayloads::MainProtocol::TwoWayComposedWithError>::
    WireResult(
        ::fidl::UnownedClientEnd<::test_protocolpayloads::MainProtocol> client,
        ::fidl::internal::TransactionalRequest<
            ::test_protocolpayloads::MainProtocol::TwoWayComposedWithError>*
            request,
        zx_time_t deadline) {
  FIDL_INTERNAL_DISABLE_AUTO_VAR_INIT
  ::fidl::unstable::OwnedEncodedMessage<
      ::fidl::internal::TransactionalRequest<
          ::test_protocolpayloads::MainProtocol::TwoWayComposedWithError>,
      ::fidl::internal::ChannelTransport>
      request_message(::fidl::internal::AllowUnownedInputRef{}, request);
  auto& outgoing = request_message.GetOutgoingMessage();
  outgoing.Call<::fidl::internal::TransactionalResponse<
      ::test_protocolpayloads::MainProtocol::TwoWayComposedWithError>>(
      client.handle(), bytes_.data(), static_cast<uint32_t>(bytes_.size()),
      fidl::CallOptions{.deadline = deadline});
  SetStatus(outgoing);
  if (ok()) {
    auto* raw_response = reinterpret_cast<::fidl::WireResponse<
        ::test_protocolpayloads::MainProtocol::TwoWayComposedWithError>*>(
        bytes_.data() + sizeof(fidl_message_header_t));
    if (raw_response->result.is_err()) {
      result_ = fitx::error(raw_response->result.err());
    } else if (raw_response->result.is_response()) {
      result_ = fitx::ok(&(raw_response->result.response()));
    }
  }
}
namespace test_protocolpayloads {
#endif  // __Fuchsia__

#ifdef __Fuchsia__
}  // namespace test_protocolpayloads
::fidl::WireUnownedResult<
    ::test_protocolpayloads::MainProtocol::TwoWayComposedWithError>::
    WireUnownedResult(
        ::fidl::UnownedClientEnd<::test_protocolpayloads::MainProtocol>
            client_end,
        ::fidl::internal::AnyBufferAllocator& allocator,
        ::fidl::internal::TransactionalRequest<
            ::test_protocolpayloads::MainProtocol::TwoWayComposedWithError>*
            request) {
  constexpr uint32_t buffer_size = ::fidl::SyncClientMethodBufferSizeInChannel<
      ::test_protocolpayloads::MainProtocol::TwoWayComposedWithError>();
  ::fitx::result<::fidl::Error, ::fidl::BufferSpan> allocation =
      allocator.TryAllocate(buffer_size);
  if (!allocation.is_ok()) {
    ::fidl::Status::operator=(allocation.error_value());
    return;
  }
  uint8_t* buffer = allocation->data;
  constexpr uint32_t request_byte_capacity = ::fidl::MaxSizeInChannel<
      ::fidl::internal::TransactionalRequest<
          ::test_protocolpayloads::MainProtocol::TwoWayComposedWithError>,
      ::fidl::MessageDirection::kSending>();
  uint8_t* request_bytes = buffer;
  static_assert(buffer_size > request_byte_capacity);
  uint32_t response_byte_capacity = buffer_size - request_byte_capacity;
  uint8_t* response_bytes = &buffer[request_byte_capacity];

  ::fidl::unstable::UnownedEncodedMessage<
      ::fidl::internal::TransactionalRequest<
          ::test_protocolpayloads::MainProtocol::TwoWayComposedWithError>>
      request_message(request_bytes, request_byte_capacity, request);
  auto& outgoing = request_message.GetOutgoingMessage();
  outgoing.Call<::fidl::internal::TransactionalResponse<
      ::test_protocolpayloads::MainProtocol::TwoWayComposedWithError>>(
      client_end.handle(), response_bytes, response_byte_capacity);
  bytes_ = response_bytes;
  if (outgoing.ok()) {
    auto* raw_response = reinterpret_cast<::fidl::WireResponse<
        ::test_protocolpayloads::MainProtocol::TwoWayComposedWithError>*>(
        bytes_ + sizeof(fidl_message_header_t));
    if (raw_response->result.is_err()) {
      result_ = fitx::error(raw_response->result.err());
    } else if (raw_response->result.is_response()) {
      result_ = fitx::ok(&(raw_response->result.response()));
    }
  }
  ::fidl::Status::operator=(outgoing);
}
namespace test_protocolpayloads {
#endif  // __Fuchsia__

#ifdef __Fuchsia__
}  // namespace test_protocolpayloads
::fidl::WireResult<::test_protocolpayloads::MainProtocol::OneWayLocal>::
    WireResult(
        ::fidl::UnownedClientEnd<::test_protocolpayloads::MainProtocol> client,
        ::fidl::internal::TransactionalRequest<
            ::test_protocolpayloads::MainProtocol::OneWayLocal>* request) {
  FIDL_INTERNAL_DISABLE_AUTO_VAR_INIT
  ::fidl::unstable::OwnedEncodedMessage<
      ::fidl::internal::TransactionalRequest<
          ::test_protocolpayloads::MainProtocol::OneWayLocal>,
      ::fidl::internal::ChannelTransport>
      request_message(::fidl::internal::AllowUnownedInputRef{}, request);
  auto& outgoing = request_message.GetOutgoingMessage();
  outgoing.Write(client.handle());
  SetStatus(outgoing);
}
namespace test_protocolpayloads {
#endif  // __Fuchsia__

#ifdef __Fuchsia__
}  // namespace test_protocolpayloads
::fidl::WireUnownedResult<::test_protocolpayloads::MainProtocol::OneWayLocal>::
    WireUnownedResult(
        ::fidl::UnownedClientEnd<::test_protocolpayloads::MainProtocol>
            client_end,
        ::fidl::internal::AnyBufferAllocator& allocator,
        ::fidl::internal::TransactionalRequest<
            ::test_protocolpayloads::MainProtocol::OneWayLocal>* request) {
  constexpr uint32_t buffer_size = ::fidl::SyncClientMethodBufferSizeInChannel<
      ::test_protocolpayloads::MainProtocol::OneWayLocal>();
  ::fitx::result<::fidl::Error, ::fidl::BufferSpan> allocation =
      allocator.TryAllocate(buffer_size);
  if (!allocation.is_ok()) {
    ::fidl::Status::operator=(allocation.error_value());
    return;
  }
  uint8_t* buffer = allocation->data;
  uint32_t request_byte_capacity = buffer_size;
  uint8_t* request_bytes = buffer;

  ::fidl::unstable::UnownedEncodedMessage<
      ::fidl::internal::TransactionalRequest<
          ::test_protocolpayloads::MainProtocol::OneWayLocal>>
      request_message(request_bytes, request_byte_capacity, request);
  auto& outgoing = request_message.GetOutgoingMessage();
  outgoing.Write(client_end.handle());
  ::fidl::Status::operator=(outgoing);
}
namespace test_protocolpayloads {
#endif  // __Fuchsia__

#ifdef __Fuchsia__
}  // namespace test_protocolpayloads
::fidl::WireResult<::test_protocolpayloads::MainProtocol::TwoWayLocal>::
    WireResult(
        ::fidl::UnownedClientEnd<::test_protocolpayloads::MainProtocol> client,
        ::fidl::internal::TransactionalRequest<
            ::test_protocolpayloads::MainProtocol::TwoWayLocal>* request) {
  FIDL_INTERNAL_DISABLE_AUTO_VAR_INIT
  ::fidl::unstable::OwnedEncodedMessage<
      ::fidl::internal::TransactionalRequest<
          ::test_protocolpayloads::MainProtocol::TwoWayLocal>,
      ::fidl::internal::ChannelTransport>
      request_message(::fidl::internal::AllowUnownedInputRef{}, request);
  auto& outgoing = request_message.GetOutgoingMessage();
  outgoing.Call<::fidl::internal::TransactionalResponse<
      ::test_protocolpayloads::MainProtocol::TwoWayLocal>>(
      client.handle(), bytes_.data(), static_cast<uint32_t>(bytes_.size()));
  SetStatus(outgoing);
}

::fidl::WireResult<::test_protocolpayloads::MainProtocol::TwoWayLocal>::
    WireResult(
        ::fidl::UnownedClientEnd<::test_protocolpayloads::MainProtocol> client,
        ::fidl::internal::TransactionalRequest<
            ::test_protocolpayloads::MainProtocol::TwoWayLocal>* request,
        zx_time_t deadline) {
  FIDL_INTERNAL_DISABLE_AUTO_VAR_INIT
  ::fidl::unstable::OwnedEncodedMessage<
      ::fidl::internal::TransactionalRequest<
          ::test_protocolpayloads::MainProtocol::TwoWayLocal>,
      ::fidl::internal::ChannelTransport>
      request_message(::fidl::internal::AllowUnownedInputRef{}, request);
  auto& outgoing = request_message.GetOutgoingMessage();
  outgoing.Call<::fidl::internal::TransactionalResponse<
      ::test_protocolpayloads::MainProtocol::TwoWayLocal>>(
      client.handle(), bytes_.data(), static_cast<uint32_t>(bytes_.size()),
      fidl::CallOptions{.deadline = deadline});
  SetStatus(outgoing);
}
namespace test_protocolpayloads {
#endif  // __Fuchsia__

#ifdef __Fuchsia__
}  // namespace test_protocolpayloads
::fidl::WireUnownedResult<::test_protocolpayloads::MainProtocol::TwoWayLocal>::
    WireUnownedResult(
        ::fidl::UnownedClientEnd<::test_protocolpayloads::MainProtocol>
            client_end,
        ::fidl::internal::AnyBufferAllocator& allocator,
        ::fidl::internal::TransactionalRequest<
            ::test_protocolpayloads::MainProtocol::TwoWayLocal>* request) {
  constexpr uint32_t buffer_size = ::fidl::SyncClientMethodBufferSizeInChannel<
      ::test_protocolpayloads::MainProtocol::TwoWayLocal>();
  ::fitx::result<::fidl::Error, ::fidl::BufferSpan> allocation =
      allocator.TryAllocate(buffer_size);
  if (!allocation.is_ok()) {
    ::fidl::Status::operator=(allocation.error_value());
    return;
  }
  uint8_t* buffer = allocation->data;
  constexpr uint32_t request_byte_capacity = ::fidl::MaxSizeInChannel<
      ::fidl::internal::TransactionalRequest<
          ::test_protocolpayloads::MainProtocol::TwoWayLocal>,
      ::fidl::MessageDirection::kSending>();
  uint8_t* request_bytes = buffer;
  static_assert(buffer_size > request_byte_capacity);
  uint32_t response_byte_capacity = buffer_size - request_byte_capacity;
  uint8_t* response_bytes = &buffer[request_byte_capacity];

  ::fidl::unstable::UnownedEncodedMessage<
      ::fidl::internal::TransactionalRequest<
          ::test_protocolpayloads::MainProtocol::TwoWayLocal>>
      request_message(request_bytes, request_byte_capacity, request);
  auto& outgoing = request_message.GetOutgoingMessage();
  outgoing.Call<::fidl::internal::TransactionalResponse<
      ::test_protocolpayloads::MainProtocol::TwoWayLocal>>(
      client_end.handle(), response_bytes, response_byte_capacity);
  bytes_ = response_bytes;
  ::fidl::Status::operator=(outgoing);
}
namespace test_protocolpayloads {
#endif  // __Fuchsia__

#ifdef __Fuchsia__
}  // namespace test_protocolpayloads
::fidl::WireResult<
    ::test_protocolpayloads::MainProtocol::TwoWayLocalWithError>::
    WireResult(
        ::fidl::UnownedClientEnd<::test_protocolpayloads::MainProtocol> client,
        ::fidl::internal::TransactionalRequest<
            ::test_protocolpayloads::MainProtocol::TwoWayLocalWithError>*
            request) {
  FIDL_INTERNAL_DISABLE_AUTO_VAR_INIT
  ::fidl::unstable::OwnedEncodedMessage<
      ::fidl::internal::TransactionalRequest<
          ::test_protocolpayloads::MainProtocol::TwoWayLocalWithError>,
      ::fidl::internal::ChannelTransport>
      request_message(::fidl::internal::AllowUnownedInputRef{}, request);
  auto& outgoing = request_message.GetOutgoingMessage();
  outgoing.Call<::fidl::internal::TransactionalResponse<
      ::test_protocolpayloads::MainProtocol::TwoWayLocalWithError>>(
      client.handle(), bytes_.data(), static_cast<uint32_t>(bytes_.size()));
  SetStatus(outgoing);
  if (ok()) {
    auto* raw_response = reinterpret_cast<::fidl::WireResponse<
        ::test_protocolpayloads::MainProtocol::TwoWayLocalWithError>*>(
        bytes_.data() + sizeof(fidl_message_header_t));
    if (raw_response->result.is_err()) {
      result_ = fitx::error(raw_response->result.err());
    } else if (raw_response->result.is_response()) {
      result_ = fitx::ok(&(raw_response->result.response()));
    }
  }
}

::fidl::WireResult<
    ::test_protocolpayloads::MainProtocol::TwoWayLocalWithError>::
    WireResult(
        ::fidl::UnownedClientEnd<::test_protocolpayloads::MainProtocol> client,
        ::fidl::internal::TransactionalRequest<
            ::test_protocolpayloads::MainProtocol::TwoWayLocalWithError>*
            request,
        zx_time_t deadline) {
  FIDL_INTERNAL_DISABLE_AUTO_VAR_INIT
  ::fidl::unstable::OwnedEncodedMessage<
      ::fidl::internal::TransactionalRequest<
          ::test_protocolpayloads::MainProtocol::TwoWayLocalWithError>,
      ::fidl::internal::ChannelTransport>
      request_message(::fidl::internal::AllowUnownedInputRef{}, request);
  auto& outgoing = request_message.GetOutgoingMessage();
  outgoing.Call<::fidl::internal::TransactionalResponse<
      ::test_protocolpayloads::MainProtocol::TwoWayLocalWithError>>(
      client.handle(), bytes_.data(), static_cast<uint32_t>(bytes_.size()),
      fidl::CallOptions{.deadline = deadline});
  SetStatus(outgoing);
  if (ok()) {
    auto* raw_response = reinterpret_cast<::fidl::WireResponse<
        ::test_protocolpayloads::MainProtocol::TwoWayLocalWithError>*>(
        bytes_.data() + sizeof(fidl_message_header_t));
    if (raw_response->result.is_err()) {
      result_ = fitx::error(raw_response->result.err());
    } else if (raw_response->result.is_response()) {
      result_ = fitx::ok(&(raw_response->result.response()));
    }
  }
}
namespace test_protocolpayloads {
#endif  // __Fuchsia__

#ifdef __Fuchsia__
}  // namespace test_protocolpayloads
::fidl::WireUnownedResult<
    ::test_protocolpayloads::MainProtocol::TwoWayLocalWithError>::
    WireUnownedResult(
        ::fidl::UnownedClientEnd<::test_protocolpayloads::MainProtocol>
            client_end,
        ::fidl::internal::AnyBufferAllocator& allocator,
        ::fidl::internal::TransactionalRequest<
            ::test_protocolpayloads::MainProtocol::TwoWayLocalWithError>*
            request) {
  constexpr uint32_t buffer_size = ::fidl::SyncClientMethodBufferSizeInChannel<
      ::test_protocolpayloads::MainProtocol::TwoWayLocalWithError>();
  ::fitx::result<::fidl::Error, ::fidl::BufferSpan> allocation =
      allocator.TryAllocate(buffer_size);
  if (!allocation.is_ok()) {
    ::fidl::Status::operator=(allocation.error_value());
    return;
  }
  uint8_t* buffer = allocation->data;
  constexpr uint32_t request_byte_capacity = ::fidl::MaxSizeInChannel<
      ::fidl::internal::TransactionalRequest<
          ::test_protocolpayloads::MainProtocol::TwoWayLocalWithError>,
      ::fidl::MessageDirection::kSending>();
  uint8_t* request_bytes = buffer;
  static_assert(buffer_size > request_byte_capacity);
  uint32_t response_byte_capacity = buffer_size - request_byte_capacity;
  uint8_t* response_bytes = &buffer[request_byte_capacity];

  ::fidl::unstable::UnownedEncodedMessage<
      ::fidl::internal::TransactionalRequest<
          ::test_protocolpayloads::MainProtocol::TwoWayLocalWithError>>
      request_message(request_bytes, request_byte_capacity, request);
  auto& outgoing = request_message.GetOutgoingMessage();
  outgoing.Call<::fidl::internal::TransactionalResponse<
      ::test_protocolpayloads::MainProtocol::TwoWayLocalWithError>>(
      client_end.handle(), response_bytes, response_byte_capacity);
  bytes_ = response_bytes;
  if (outgoing.ok()) {
    auto* raw_response = reinterpret_cast<::fidl::WireResponse<
        ::test_protocolpayloads::MainProtocol::TwoWayLocalWithError>*>(
        bytes_ + sizeof(fidl_message_header_t));
    if (raw_response->result.is_err()) {
      result_ = fitx::error(raw_response->result.err());
    } else if (raw_response->result.is_response()) {
      result_ = fitx::ok(&(raw_response->result.response()));
    }
  }
  ::fidl::Status::operator=(outgoing);
}
namespace test_protocolpayloads {
#endif  // __Fuchsia__

#ifdef __Fuchsia__
}  // namespace test_protocolpayloads
::fidl::WireResult<::test_protocolpayloads::MainProtocol::OneWayImport>::
    WireResult(
        ::fidl::UnownedClientEnd<::test_protocolpayloads::MainProtocol> client,
        ::fidl::internal::TransactionalRequest<
            ::test_protocolpayloads::MainProtocol::OneWayImport>* request) {
  FIDL_INTERNAL_DISABLE_AUTO_VAR_INIT
  ::fidl::unstable::OwnedEncodedMessage<
      ::fidl::internal::TransactionalRequest<
          ::test_protocolpayloads::MainProtocol::OneWayImport>,
      ::fidl::internal::ChannelTransport>
      request_message(::fidl::internal::AllowUnownedInputRef{}, request);
  auto& outgoing = request_message.GetOutgoingMessage();
  outgoing.Write(client.handle());
  SetStatus(outgoing);
}
namespace test_protocolpayloads {
#endif  // __Fuchsia__

#ifdef __Fuchsia__
}  // namespace test_protocolpayloads
::fidl::WireUnownedResult<::test_protocolpayloads::MainProtocol::OneWayImport>::
    WireUnownedResult(
        ::fidl::UnownedClientEnd<::test_protocolpayloads::MainProtocol>
            client_end,
        ::fidl::internal::AnyBufferAllocator& allocator,
        ::fidl::internal::TransactionalRequest<
            ::test_protocolpayloads::MainProtocol::OneWayImport>* request) {
  constexpr uint32_t buffer_size = ::fidl::SyncClientMethodBufferSizeInChannel<
      ::test_protocolpayloads::MainProtocol::OneWayImport>();
  ::fitx::result<::fidl::Error, ::fidl::BufferSpan> allocation =
      allocator.TryAllocate(buffer_size);
  if (!allocation.is_ok()) {
    ::fidl::Status::operator=(allocation.error_value());
    return;
  }
  uint8_t* buffer = allocation->data;
  uint32_t request_byte_capacity = buffer_size;
  uint8_t* request_bytes = buffer;

  ::fidl::unstable::UnownedEncodedMessage<
      ::fidl::internal::TransactionalRequest<
          ::test_protocolpayloads::MainProtocol::OneWayImport>>
      request_message(request_bytes, request_byte_capacity, request);
  auto& outgoing = request_message.GetOutgoingMessage();
  outgoing.Write(client_end.handle());
  ::fidl::Status::operator=(outgoing);
}
namespace test_protocolpayloads {
#endif  // __Fuchsia__

#ifdef __Fuchsia__
}  // namespace test_protocolpayloads
::fidl::WireResult<::test_protocolpayloads::MainProtocol::TwoWayImport>::
    WireResult(
        ::fidl::UnownedClientEnd<::test_protocolpayloads::MainProtocol> client,
        ::fidl::internal::TransactionalRequest<
            ::test_protocolpayloads::MainProtocol::TwoWayImport>* request) {
  FIDL_INTERNAL_DISABLE_AUTO_VAR_INIT
  ::fidl::unstable::OwnedEncodedMessage<
      ::fidl::internal::TransactionalRequest<
          ::test_protocolpayloads::MainProtocol::TwoWayImport>,
      ::fidl::internal::ChannelTransport>
      request_message(::fidl::internal::AllowUnownedInputRef{}, request);
  auto& outgoing = request_message.GetOutgoingMessage();
  outgoing.Call<::fidl::internal::TransactionalResponse<
      ::test_protocolpayloads::MainProtocol::TwoWayImport>>(
      client.handle(), bytes_.data(), static_cast<uint32_t>(bytes_.size()));
  SetStatus(outgoing);
}

::fidl::WireResult<::test_protocolpayloads::MainProtocol::TwoWayImport>::
    WireResult(
        ::fidl::UnownedClientEnd<::test_protocolpayloads::MainProtocol> client,
        ::fidl::internal::TransactionalRequest<
            ::test_protocolpayloads::MainProtocol::TwoWayImport>* request,
        zx_time_t deadline) {
  FIDL_INTERNAL_DISABLE_AUTO_VAR_INIT
  ::fidl::unstable::OwnedEncodedMessage<
      ::fidl::internal::TransactionalRequest<
          ::test_protocolpayloads::MainProtocol::TwoWayImport>,
      ::fidl::internal::ChannelTransport>
      request_message(::fidl::internal::AllowUnownedInputRef{}, request);
  auto& outgoing = request_message.GetOutgoingMessage();
  outgoing.Call<::fidl::internal::TransactionalResponse<
      ::test_protocolpayloads::MainProtocol::TwoWayImport>>(
      client.handle(), bytes_.data(), static_cast<uint32_t>(bytes_.size()),
      fidl::CallOptions{.deadline = deadline});
  SetStatus(outgoing);
}
namespace test_protocolpayloads {
#endif  // __Fuchsia__

#ifdef __Fuchsia__
}  // namespace test_protocolpayloads
::fidl::WireUnownedResult<::test_protocolpayloads::MainProtocol::TwoWayImport>::
    WireUnownedResult(
        ::fidl::UnownedClientEnd<::test_protocolpayloads::MainProtocol>
            client_end,
        ::fidl::internal::AnyBufferAllocator& allocator,
        ::fidl::internal::TransactionalRequest<
            ::test_protocolpayloads::MainProtocol::TwoWayImport>* request) {
  constexpr uint32_t buffer_size = ::fidl::SyncClientMethodBufferSizeInChannel<
      ::test_protocolpayloads::MainProtocol::TwoWayImport>();
  ::fitx::result<::fidl::Error, ::fidl::BufferSpan> allocation =
      allocator.TryAllocate(buffer_size);
  if (!allocation.is_ok()) {
    ::fidl::Status::operator=(allocation.error_value());
    return;
  }
  uint8_t* buffer = allocation->data;
  constexpr uint32_t request_byte_capacity = ::fidl::MaxSizeInChannel<
      ::fidl::internal::TransactionalRequest<
          ::test_protocolpayloads::MainProtocol::TwoWayImport>,
      ::fidl::MessageDirection::kSending>();
  uint8_t* request_bytes = buffer;
  static_assert(buffer_size > request_byte_capacity);
  uint32_t response_byte_capacity = buffer_size - request_byte_capacity;
  uint8_t* response_bytes = &buffer[request_byte_capacity];

  ::fidl::unstable::UnownedEncodedMessage<
      ::fidl::internal::TransactionalRequest<
          ::test_protocolpayloads::MainProtocol::TwoWayImport>>
      request_message(request_bytes, request_byte_capacity, request);
  auto& outgoing = request_message.GetOutgoingMessage();
  outgoing.Call<::fidl::internal::TransactionalResponse<
      ::test_protocolpayloads::MainProtocol::TwoWayImport>>(
      client_end.handle(), response_bytes, response_byte_capacity);
  bytes_ = response_bytes;
  ::fidl::Status::operator=(outgoing);
}
namespace test_protocolpayloads {
#endif  // __Fuchsia__

#ifdef __Fuchsia__
}  // namespace test_protocolpayloads
::fidl::WireResult<
    ::test_protocolpayloads::MainProtocol::TwoWayImportWithError>::
    WireResult(
        ::fidl::UnownedClientEnd<::test_protocolpayloads::MainProtocol> client,
        ::fidl::internal::TransactionalRequest<
            ::test_protocolpayloads::MainProtocol::TwoWayImportWithError>*
            request) {
  FIDL_INTERNAL_DISABLE_AUTO_VAR_INIT
  ::fidl::unstable::OwnedEncodedMessage<
      ::fidl::internal::TransactionalRequest<
          ::test_protocolpayloads::MainProtocol::TwoWayImportWithError>,
      ::fidl::internal::ChannelTransport>
      request_message(::fidl::internal::AllowUnownedInputRef{}, request);
  auto& outgoing = request_message.GetOutgoingMessage();
  outgoing.Call<::fidl::internal::TransactionalResponse<
      ::test_protocolpayloads::MainProtocol::TwoWayImportWithError>>(
      client.handle(), bytes_.data(), static_cast<uint32_t>(bytes_.size()));
  SetStatus(outgoing);
  if (ok()) {
    auto* raw_response = reinterpret_cast<::fidl::WireResponse<
        ::test_protocolpayloads::MainProtocol::TwoWayImportWithError>*>(
        bytes_.data() + sizeof(fidl_message_header_t));
    if (raw_response->result.is_err()) {
      result_ = fitx::error(raw_response->result.err());
    } else if (raw_response->result.is_response()) {
      result_ = fitx::ok(&(raw_response->result.response()));
    }
  }
}

::fidl::WireResult<
    ::test_protocolpayloads::MainProtocol::TwoWayImportWithError>::
    WireResult(
        ::fidl::UnownedClientEnd<::test_protocolpayloads::MainProtocol> client,
        ::fidl::internal::TransactionalRequest<
            ::test_protocolpayloads::MainProtocol::TwoWayImportWithError>*
            request,
        zx_time_t deadline) {
  FIDL_INTERNAL_DISABLE_AUTO_VAR_INIT
  ::fidl::unstable::OwnedEncodedMessage<
      ::fidl::internal::TransactionalRequest<
          ::test_protocolpayloads::MainProtocol::TwoWayImportWithError>,
      ::fidl::internal::ChannelTransport>
      request_message(::fidl::internal::AllowUnownedInputRef{}, request);
  auto& outgoing = request_message.GetOutgoingMessage();
  outgoing.Call<::fidl::internal::TransactionalResponse<
      ::test_protocolpayloads::MainProtocol::TwoWayImportWithError>>(
      client.handle(), bytes_.data(), static_cast<uint32_t>(bytes_.size()),
      fidl::CallOptions{.deadline = deadline});
  SetStatus(outgoing);
  if (ok()) {
    auto* raw_response = reinterpret_cast<::fidl::WireResponse<
        ::test_protocolpayloads::MainProtocol::TwoWayImportWithError>*>(
        bytes_.data() + sizeof(fidl_message_header_t));
    if (raw_response->result.is_err()) {
      result_ = fitx::error(raw_response->result.err());
    } else if (raw_response->result.is_response()) {
      result_ = fitx::ok(&(raw_response->result.response()));
    }
  }
}
namespace test_protocolpayloads {
#endif  // __Fuchsia__

#ifdef __Fuchsia__
}  // namespace test_protocolpayloads
::fidl::WireUnownedResult<
    ::test_protocolpayloads::MainProtocol::TwoWayImportWithError>::
    WireUnownedResult(
        ::fidl::UnownedClientEnd<::test_protocolpayloads::MainProtocol>
            client_end,
        ::fidl::internal::AnyBufferAllocator& allocator,
        ::fidl::internal::TransactionalRequest<
            ::test_protocolpayloads::MainProtocol::TwoWayImportWithError>*
            request) {
  constexpr uint32_t buffer_size = ::fidl::SyncClientMethodBufferSizeInChannel<
      ::test_protocolpayloads::MainProtocol::TwoWayImportWithError>();
  ::fitx::result<::fidl::Error, ::fidl::BufferSpan> allocation =
      allocator.TryAllocate(buffer_size);
  if (!allocation.is_ok()) {
    ::fidl::Status::operator=(allocation.error_value());
    return;
  }
  uint8_t* buffer = allocation->data;
  constexpr uint32_t request_byte_capacity = ::fidl::MaxSizeInChannel<
      ::fidl::internal::TransactionalRequest<
          ::test_protocolpayloads::MainProtocol::TwoWayImportWithError>,
      ::fidl::MessageDirection::kSending>();
  uint8_t* request_bytes = buffer;
  static_assert(buffer_size > request_byte_capacity);
  uint32_t response_byte_capacity = buffer_size - request_byte_capacity;
  uint8_t* response_bytes = &buffer[request_byte_capacity];

  ::fidl::unstable::UnownedEncodedMessage<
      ::fidl::internal::TransactionalRequest<
          ::test_protocolpayloads::MainProtocol::TwoWayImportWithError>>
      request_message(request_bytes, request_byte_capacity, request);
  auto& outgoing = request_message.GetOutgoingMessage();
  outgoing.Call<::fidl::internal::TransactionalResponse<
      ::test_protocolpayloads::MainProtocol::TwoWayImportWithError>>(
      client_end.handle(), response_bytes, response_byte_capacity);
  bytes_ = response_bytes;
  if (outgoing.ok()) {
    auto* raw_response = reinterpret_cast<::fidl::WireResponse<
        ::test_protocolpayloads::MainProtocol::TwoWayImportWithError>*>(
        bytes_ + sizeof(fidl_message_header_t));
    if (raw_response->result.is_err()) {
      result_ = fitx::error(raw_response->result.err());
    } else if (raw_response->result.is_response()) {
      result_ = fitx::ok(&(raw_response->result.response()));
    }
  }
  ::fidl::Status::operator=(outgoing);
}
namespace test_protocolpayloads {
#endif  // __Fuchsia__

#ifdef __Fuchsia__
}  // namespace test_protocolpayloads
::fidl::WireResult<::test_protocolpayloads::MainProtocol::OneWayAnon>::
    WireResult(
        ::fidl::UnownedClientEnd<::test_protocolpayloads::MainProtocol> client,
        ::fidl::internal::TransactionalRequest<
            ::test_protocolpayloads::MainProtocol::OneWayAnon>* request) {
  FIDL_INTERNAL_DISABLE_AUTO_VAR_INIT
  ::fidl::unstable::OwnedEncodedMessage<
      ::fidl::internal::TransactionalRequest<
          ::test_protocolpayloads::MainProtocol::OneWayAnon>,
      ::fidl::internal::ChannelTransport>
      request_message(::fidl::internal::AllowUnownedInputRef{}, request);
  auto& outgoing = request_message.GetOutgoingMessage();
  outgoing.Write(client.handle());
  SetStatus(outgoing);
}
namespace test_protocolpayloads {
#endif  // __Fuchsia__

#ifdef __Fuchsia__
}  // namespace test_protocolpayloads
::fidl::WireUnownedResult<::test_protocolpayloads::MainProtocol::OneWayAnon>::
    WireUnownedResult(
        ::fidl::UnownedClientEnd<::test_protocolpayloads::MainProtocol>
            client_end,
        ::fidl::internal::AnyBufferAllocator& allocator,
        ::fidl::internal::TransactionalRequest<
            ::test_protocolpayloads::MainProtocol::OneWayAnon>* request) {
  constexpr uint32_t buffer_size = ::fidl::SyncClientMethodBufferSizeInChannel<
      ::test_protocolpayloads::MainProtocol::OneWayAnon>();
  ::fitx::result<::fidl::Error, ::fidl::BufferSpan> allocation =
      allocator.TryAllocate(buffer_size);
  if (!allocation.is_ok()) {
    ::fidl::Status::operator=(allocation.error_value());
    return;
  }
  uint8_t* buffer = allocation->data;
  uint32_t request_byte_capacity = buffer_size;
  uint8_t* request_bytes = buffer;

  ::fidl::unstable::UnownedEncodedMessage<
      ::fidl::internal::TransactionalRequest<
          ::test_protocolpayloads::MainProtocol::OneWayAnon>>
      request_message(request_bytes, request_byte_capacity, request);
  auto& outgoing = request_message.GetOutgoingMessage();
  outgoing.Write(client_end.handle());
  ::fidl::Status::operator=(outgoing);
}
namespace test_protocolpayloads {
#endif  // __Fuchsia__

#ifdef __Fuchsia__
}  // namespace test_protocolpayloads
::fidl::WireResult<::test_protocolpayloads::MainProtocol::TwoWayAnon>::
    WireResult(
        ::fidl::UnownedClientEnd<::test_protocolpayloads::MainProtocol> client,
        ::fidl::internal::TransactionalRequest<
            ::test_protocolpayloads::MainProtocol::TwoWayAnon>* request) {
  FIDL_INTERNAL_DISABLE_AUTO_VAR_INIT
  ::fidl::unstable::OwnedEncodedMessage<
      ::fidl::internal::TransactionalRequest<
          ::test_protocolpayloads::MainProtocol::TwoWayAnon>,
      ::fidl::internal::ChannelTransport>
      request_message(::fidl::internal::AllowUnownedInputRef{}, request);
  auto& outgoing = request_message.GetOutgoingMessage();
  outgoing.Call<::fidl::internal::TransactionalResponse<
      ::test_protocolpayloads::MainProtocol::TwoWayAnon>>(
      client.handle(), bytes_.data(), static_cast<uint32_t>(bytes_.size()));
  SetStatus(outgoing);
}

::fidl::WireResult<::test_protocolpayloads::MainProtocol::TwoWayAnon>::
    WireResult(
        ::fidl::UnownedClientEnd<::test_protocolpayloads::MainProtocol> client,
        ::fidl::internal::TransactionalRequest<
            ::test_protocolpayloads::MainProtocol::TwoWayAnon>* request,
        zx_time_t deadline) {
  FIDL_INTERNAL_DISABLE_AUTO_VAR_INIT
  ::fidl::unstable::OwnedEncodedMessage<
      ::fidl::internal::TransactionalRequest<
          ::test_protocolpayloads::MainProtocol::TwoWayAnon>,
      ::fidl::internal::ChannelTransport>
      request_message(::fidl::internal::AllowUnownedInputRef{}, request);
  auto& outgoing = request_message.GetOutgoingMessage();
  outgoing.Call<::fidl::internal::TransactionalResponse<
      ::test_protocolpayloads::MainProtocol::TwoWayAnon>>(
      client.handle(), bytes_.data(), static_cast<uint32_t>(bytes_.size()),
      fidl::CallOptions{.deadline = deadline});
  SetStatus(outgoing);
}
namespace test_protocolpayloads {
#endif  // __Fuchsia__

#ifdef __Fuchsia__
}  // namespace test_protocolpayloads
::fidl::WireUnownedResult<::test_protocolpayloads::MainProtocol::TwoWayAnon>::
    WireUnownedResult(
        ::fidl::UnownedClientEnd<::test_protocolpayloads::MainProtocol>
            client_end,
        ::fidl::internal::AnyBufferAllocator& allocator,
        ::fidl::internal::TransactionalRequest<
            ::test_protocolpayloads::MainProtocol::TwoWayAnon>* request) {
  constexpr uint32_t buffer_size = ::fidl::SyncClientMethodBufferSizeInChannel<
      ::test_protocolpayloads::MainProtocol::TwoWayAnon>();
  ::fitx::result<::fidl::Error, ::fidl::BufferSpan> allocation =
      allocator.TryAllocate(buffer_size);
  if (!allocation.is_ok()) {
    ::fidl::Status::operator=(allocation.error_value());
    return;
  }
  uint8_t* buffer = allocation->data;
  constexpr uint32_t request_byte_capacity = ::fidl::MaxSizeInChannel<
      ::fidl::internal::TransactionalRequest<
          ::test_protocolpayloads::MainProtocol::TwoWayAnon>,
      ::fidl::MessageDirection::kSending>();
  uint8_t* request_bytes = buffer;
  static_assert(buffer_size > request_byte_capacity);
  uint32_t response_byte_capacity = buffer_size - request_byte_capacity;
  uint8_t* response_bytes = &buffer[request_byte_capacity];

  ::fidl::unstable::UnownedEncodedMessage<
      ::fidl::internal::TransactionalRequest<
          ::test_protocolpayloads::MainProtocol::TwoWayAnon>>
      request_message(request_bytes, request_byte_capacity, request);
  auto& outgoing = request_message.GetOutgoingMessage();
  outgoing.Call<::fidl::internal::TransactionalResponse<
      ::test_protocolpayloads::MainProtocol::TwoWayAnon>>(
      client_end.handle(), response_bytes, response_byte_capacity);
  bytes_ = response_bytes;
  ::fidl::Status::operator=(outgoing);
}
namespace test_protocolpayloads {
#endif  // __Fuchsia__

#ifdef __Fuchsia__
}  // namespace test_protocolpayloads
::fidl::WireResult<::test_protocolpayloads::MainProtocol::TwoWayAnonWithError>::
    WireResult(
        ::fidl::UnownedClientEnd<::test_protocolpayloads::MainProtocol> client,
        ::fidl::internal::TransactionalRequest<
            ::test_protocolpayloads::MainProtocol::TwoWayAnonWithError>*
            request) {
  FIDL_INTERNAL_DISABLE_AUTO_VAR_INIT
  ::fidl::unstable::OwnedEncodedMessage<
      ::fidl::internal::TransactionalRequest<
          ::test_protocolpayloads::MainProtocol::TwoWayAnonWithError>,
      ::fidl::internal::ChannelTransport>
      request_message(::fidl::internal::AllowUnownedInputRef{}, request);
  auto& outgoing = request_message.GetOutgoingMessage();
  outgoing.Call<::fidl::internal::TransactionalResponse<
      ::test_protocolpayloads::MainProtocol::TwoWayAnonWithError>>(
      client.handle(), bytes_.data(), static_cast<uint32_t>(bytes_.size()));
  SetStatus(outgoing);
  if (ok()) {
    auto* raw_response = reinterpret_cast<::fidl::WireResponse<
        ::test_protocolpayloads::MainProtocol::TwoWayAnonWithError>*>(
        bytes_.data() + sizeof(fidl_message_header_t));
    if (raw_response->result.is_err()) {
      result_ = fitx::error(raw_response->result.err());
    } else if (raw_response->result.is_response()) {
      result_ = fitx::ok(&(raw_response->result.response()));
    }
  }
}

::fidl::WireResult<::test_protocolpayloads::MainProtocol::TwoWayAnonWithError>::
    WireResult(
        ::fidl::UnownedClientEnd<::test_protocolpayloads::MainProtocol> client,
        ::fidl::internal::TransactionalRequest<
            ::test_protocolpayloads::MainProtocol::TwoWayAnonWithError>*
            request,
        zx_time_t deadline) {
  FIDL_INTERNAL_DISABLE_AUTO_VAR_INIT
  ::fidl::unstable::OwnedEncodedMessage<
      ::fidl::internal::TransactionalRequest<
          ::test_protocolpayloads::MainProtocol::TwoWayAnonWithError>,
      ::fidl::internal::ChannelTransport>
      request_message(::fidl::internal::AllowUnownedInputRef{}, request);
  auto& outgoing = request_message.GetOutgoingMessage();
  outgoing.Call<::fidl::internal::TransactionalResponse<
      ::test_protocolpayloads::MainProtocol::TwoWayAnonWithError>>(
      client.handle(), bytes_.data(), static_cast<uint32_t>(bytes_.size()),
      fidl::CallOptions{.deadline = deadline});
  SetStatus(outgoing);
  if (ok()) {
    auto* raw_response = reinterpret_cast<::fidl::WireResponse<
        ::test_protocolpayloads::MainProtocol::TwoWayAnonWithError>*>(
        bytes_.data() + sizeof(fidl_message_header_t));
    if (raw_response->result.is_err()) {
      result_ = fitx::error(raw_response->result.err());
    } else if (raw_response->result.is_response()) {
      result_ = fitx::ok(&(raw_response->result.response()));
    }
  }
}
namespace test_protocolpayloads {
#endif  // __Fuchsia__

#ifdef __Fuchsia__
}  // namespace test_protocolpayloads
::fidl::WireUnownedResult<
    ::test_protocolpayloads::MainProtocol::TwoWayAnonWithError>::
    WireUnownedResult(
        ::fidl::UnownedClientEnd<::test_protocolpayloads::MainProtocol>
            client_end,
        ::fidl::internal::AnyBufferAllocator& allocator,
        ::fidl::internal::TransactionalRequest<
            ::test_protocolpayloads::MainProtocol::TwoWayAnonWithError>*
            request) {
  constexpr uint32_t buffer_size = ::fidl::SyncClientMethodBufferSizeInChannel<
      ::test_protocolpayloads::MainProtocol::TwoWayAnonWithError>();
  ::fitx::result<::fidl::Error, ::fidl::BufferSpan> allocation =
      allocator.TryAllocate(buffer_size);
  if (!allocation.is_ok()) {
    ::fidl::Status::operator=(allocation.error_value());
    return;
  }
  uint8_t* buffer = allocation->data;
  constexpr uint32_t request_byte_capacity = ::fidl::MaxSizeInChannel<
      ::fidl::internal::TransactionalRequest<
          ::test_protocolpayloads::MainProtocol::TwoWayAnonWithError>,
      ::fidl::MessageDirection::kSending>();
  uint8_t* request_bytes = buffer;
  static_assert(buffer_size > request_byte_capacity);
  uint32_t response_byte_capacity = buffer_size - request_byte_capacity;
  uint8_t* response_bytes = &buffer[request_byte_capacity];

  ::fidl::unstable::UnownedEncodedMessage<
      ::fidl::internal::TransactionalRequest<
          ::test_protocolpayloads::MainProtocol::TwoWayAnonWithError>>
      request_message(request_bytes, request_byte_capacity, request);
  auto& outgoing = request_message.GetOutgoingMessage();
  outgoing.Call<::fidl::internal::TransactionalResponse<
      ::test_protocolpayloads::MainProtocol::TwoWayAnonWithError>>(
      client_end.handle(), response_bytes, response_byte_capacity);
  bytes_ = response_bytes;
  if (outgoing.ok()) {
    auto* raw_response = reinterpret_cast<::fidl::WireResponse<
        ::test_protocolpayloads::MainProtocol::TwoWayAnonWithError>*>(
        bytes_ + sizeof(fidl_message_header_t));
    if (raw_response->result.is_err()) {
      result_ = fitx::error(raw_response->result.err());
    } else if (raw_response->result.is_response()) {
      result_ = fitx::ok(&(raw_response->result.response()));
    }
  }
  ::fidl::Status::operator=(outgoing);
}
namespace test_protocolpayloads {
#endif  // __Fuchsia__

}  // namespace test_protocolpayloads
#ifdef __Fuchsia__

::fidl::Status fidl::internal::WireWeakOnewayClientImpl<
    ::test_protocolpayloads::MainProtocol>::OneWayComposed(int32_t a) {
  FIDL_INTERNAL_DISABLE_AUTO_VAR_INIT
  ::fidl::internal::TransactionalRequest<
      ::test_protocolpayloads::MainProtocol::OneWayComposed>
      _request_object{a};
  ::fidl::unstable::OwnedEncodedMessage<
      ::fidl::internal::TransactionalRequest<
          ::test_protocolpayloads::MainProtocol::OneWayComposed>,
      ::fidl::internal::ChannelTransport>
      _request_message(::fidl::internal::AllowUnownedInputRef{},
                       &_request_object);
  return _client_base()->SendOneWay(_request_message.GetOutgoingMessage());
}
::fidl::Status fidl::internal::WireWeakOnewayClientImpl<
    ::test_protocolpayloads::MainProtocol>::OneWayLocal(uint32_t a,
                                                        uint32_t b) {
  FIDL_INTERNAL_DISABLE_AUTO_VAR_INIT
  ::fidl::internal::TransactionalRequest<
      ::test_protocolpayloads::MainProtocol::OneWayLocal>
      _request_object{a, b};
  ::fidl::unstable::OwnedEncodedMessage<
      ::fidl::internal::TransactionalRequest<
          ::test_protocolpayloads::MainProtocol::OneWayLocal>,
      ::fidl::internal::ChannelTransport>
      _request_message(::fidl::internal::AllowUnownedInputRef{},
                       &_request_object);
  return _client_base()->SendOneWay(_request_message.GetOutgoingMessage());
}
::fidl::Status fidl::internal::WireWeakOnewayClientImpl<
    ::test_protocolpayloads::MainProtocol>::OneWayImport(int32_t a) {
  FIDL_INTERNAL_DISABLE_AUTO_VAR_INIT
  ::fidl::internal::TransactionalRequest<
      ::test_protocolpayloads::MainProtocol::OneWayImport>
      _request_object{a};
  ::fidl::unstable::OwnedEncodedMessage<
      ::fidl::internal::TransactionalRequest<
          ::test_protocolpayloads::MainProtocol::OneWayImport>,
      ::fidl::internal::ChannelTransport>
      _request_message(::fidl::internal::AllowUnownedInputRef{},
                       &_request_object);
  return _client_base()->SendOneWay(_request_message.GetOutgoingMessage());
}
::fidl::Status fidl::internal::WireWeakOnewayClientImpl<
    ::test_protocolpayloads::MainProtocol>::OneWayAnon(uint32_t a, uint32_t b) {
  FIDL_INTERNAL_DISABLE_AUTO_VAR_INIT
  ::fidl::internal::TransactionalRequest<
      ::test_protocolpayloads::MainProtocol::OneWayAnon>
      _request_object{a, b};
  ::fidl::unstable::OwnedEncodedMessage<
      ::fidl::internal::TransactionalRequest<
          ::test_protocolpayloads::MainProtocol::OneWayAnon>,
      ::fidl::internal::ChannelTransport>
      _request_message(::fidl::internal::AllowUnownedInputRef{},
                       &_request_object);
  return _client_base()->SendOneWay(_request_message.GetOutgoingMessage());
}

::fidl::internal::WireThenable<
    ::test_protocolpayloads::MainProtocol::TwoWayComposed>
fidl::internal::WireWeakAsyncClientImpl<
    ::test_protocolpayloads::MainProtocol>::TwoWayComposed(int32_t a) {
  ::fidl::internal::TransactionalRequest<
      ::test_protocolpayloads::MainProtocol::TwoWayComposed>
      _request{a};
  return ::fidl::internal::WireThenable<
      ::test_protocolpayloads::MainProtocol::TwoWayComposed>{
      _client_base(), ::fidl::WriteOptions{},
      ::fidl::internal::AllowUnownedInputRef{}, &_request};
}

::fidl::internal::WireThenable<
    ::test_protocolpayloads::MainProtocol::TwoWayComposedWithError>
fidl::internal::WireWeakAsyncClientImpl<
    ::test_protocolpayloads::MainProtocol>::TwoWayComposedWithError(int32_t a) {
  ::fidl::internal::TransactionalRequest<
      ::test_protocolpayloads::MainProtocol::TwoWayComposedWithError>
      _request{a};
  return ::fidl::internal::WireThenable<
      ::test_protocolpayloads::MainProtocol::TwoWayComposedWithError>{
      _client_base(), ::fidl::WriteOptions{},
      ::fidl::internal::AllowUnownedInputRef{}, &_request};
}

::fidl::internal::WireThenable<
    ::test_protocolpayloads::MainProtocol::TwoWayLocal>
fidl::internal::WireWeakAsyncClientImpl<
    ::test_protocolpayloads::MainProtocol>::TwoWayLocal(uint32_t a,
                                                        uint32_t b) {
  ::fidl::internal::TransactionalRequest<
      ::test_protocolpayloads::MainProtocol::TwoWayLocal>
      _request{a, b};
  return ::fidl::internal::WireThenable<
      ::test_protocolpayloads::MainProtocol::TwoWayLocal>{
      _client_base(), ::fidl::WriteOptions{},
      ::fidl::internal::AllowUnownedInputRef{}, &_request};
}

::fidl::internal::WireThenable<
    ::test_protocolpayloads::MainProtocol::TwoWayLocalWithError>
fidl::internal::WireWeakAsyncClientImpl<
    ::test_protocolpayloads::MainProtocol>::TwoWayLocalWithError(uint32_t a,
                                                                 uint32_t b) {
  ::fidl::internal::TransactionalRequest<
      ::test_protocolpayloads::MainProtocol::TwoWayLocalWithError>
      _request{a, b};
  return ::fidl::internal::WireThenable<
      ::test_protocolpayloads::MainProtocol::TwoWayLocalWithError>{
      _client_base(), ::fidl::WriteOptions{},
      ::fidl::internal::AllowUnownedInputRef{}, &_request};
}

::fidl::internal::WireThenable<
    ::test_protocolpayloads::MainProtocol::TwoWayImport>
fidl::internal::WireWeakAsyncClientImpl<
    ::test_protocolpayloads::MainProtocol>::TwoWayImport(int32_t a) {
  ::fidl::internal::TransactionalRequest<
      ::test_protocolpayloads::MainProtocol::TwoWayImport>
      _request{a};
  return ::fidl::internal::WireThenable<
      ::test_protocolpayloads::MainProtocol::TwoWayImport>{
      _client_base(), ::fidl::WriteOptions{},
      ::fidl::internal::AllowUnownedInputRef{}, &_request};
}

::fidl::internal::WireThenable<
    ::test_protocolpayloads::MainProtocol::TwoWayImportWithError>
fidl::internal::WireWeakAsyncClientImpl<
    ::test_protocolpayloads::MainProtocol>::TwoWayImportWithError(int32_t a) {
  ::fidl::internal::TransactionalRequest<
      ::test_protocolpayloads::MainProtocol::TwoWayImportWithError>
      _request{a};
  return ::fidl::internal::WireThenable<
      ::test_protocolpayloads::MainProtocol::TwoWayImportWithError>{
      _client_base(), ::fidl::WriteOptions{},
      ::fidl::internal::AllowUnownedInputRef{}, &_request};
}

::fidl::internal::WireThenable<
    ::test_protocolpayloads::MainProtocol::TwoWayAnon>
fidl::internal::WireWeakAsyncClientImpl<
    ::test_protocolpayloads::MainProtocol>::TwoWayAnon(uint32_t a, uint32_t b) {
  ::fidl::internal::TransactionalRequest<
      ::test_protocolpayloads::MainProtocol::TwoWayAnon>
      _request{a, b};
  return ::fidl::internal::WireThenable<
      ::test_protocolpayloads::MainProtocol::TwoWayAnon>{
      _client_base(), ::fidl::WriteOptions{},
      ::fidl::internal::AllowUnownedInputRef{}, &_request};
}

::fidl::internal::WireThenable<
    ::test_protocolpayloads::MainProtocol::TwoWayAnonWithError>
fidl::internal::WireWeakAsyncClientImpl<
    ::test_protocolpayloads::MainProtocol>::TwoWayAnonWithError(uint32_t a,
                                                                uint32_t b) {
  ::fidl::internal::TransactionalRequest<
      ::test_protocolpayloads::MainProtocol::TwoWayAnonWithError>
      _request{a, b};
  return ::fidl::internal::WireThenable<
      ::test_protocolpayloads::MainProtocol::TwoWayAnonWithError>{
      _client_base(), ::fidl::WriteOptions{},
      ::fidl::internal::AllowUnownedInputRef{}, &_request};
}
::fidl::Status fidl::internal::WireWeakOnewayBufferClientImpl<
    ::test_protocolpayloads::MainProtocol>::OneWayComposed(int32_t a) {
  constexpr uint32_t _buffer_size =
      ::fidl::AsyncClientMethodBufferSizeInChannel<
          ::test_protocolpayloads::MainProtocol::OneWayComposed>();
  ::fitx::result<::fidl::Error, ::fidl::BufferSpan> _allocation =
      _allocator().TryAllocate(_buffer_size);
  if (!_allocation.is_ok()) {
    return _allocation.error_value();
  }

  ::fidl::internal::TransactionalRequest<
      ::test_protocolpayloads::MainProtocol::OneWayComposed>
      _request{a};
  ::fidl::unstable::UnownedEncodedMessage<
      ::fidl::internal::TransactionalRequest<
          ::test_protocolpayloads::MainProtocol::OneWayComposed>>
      _request_message(_allocation->data, _buffer_size, &_request);
  return _client_base()->SendOneWay(_request_message.GetOutgoingMessage());
}
::fidl::Status fidl::internal::WireWeakOnewayBufferClientImpl<
    ::test_protocolpayloads::MainProtocol>::OneWayLocal(uint32_t a,
                                                        uint32_t b) {
  constexpr uint32_t _buffer_size =
      ::fidl::AsyncClientMethodBufferSizeInChannel<
          ::test_protocolpayloads::MainProtocol::OneWayLocal>();
  ::fitx::result<::fidl::Error, ::fidl::BufferSpan> _allocation =
      _allocator().TryAllocate(_buffer_size);
  if (!_allocation.is_ok()) {
    return _allocation.error_value();
  }

  ::fidl::internal::TransactionalRequest<
      ::test_protocolpayloads::MainProtocol::OneWayLocal>
      _request{a, b};
  ::fidl::unstable::UnownedEncodedMessage<
      ::fidl::internal::TransactionalRequest<
          ::test_protocolpayloads::MainProtocol::OneWayLocal>>
      _request_message(_allocation->data, _buffer_size, &_request);
  return _client_base()->SendOneWay(_request_message.GetOutgoingMessage());
}
::fidl::Status fidl::internal::WireWeakOnewayBufferClientImpl<
    ::test_protocolpayloads::MainProtocol>::OneWayImport(int32_t a) {
  constexpr uint32_t _buffer_size =
      ::fidl::AsyncClientMethodBufferSizeInChannel<
          ::test_protocolpayloads::MainProtocol::OneWayImport>();
  ::fitx::result<::fidl::Error, ::fidl::BufferSpan> _allocation =
      _allocator().TryAllocate(_buffer_size);
  if (!_allocation.is_ok()) {
    return _allocation.error_value();
  }

  ::fidl::internal::TransactionalRequest<
      ::test_protocolpayloads::MainProtocol::OneWayImport>
      _request{a};
  ::fidl::unstable::UnownedEncodedMessage<
      ::fidl::internal::TransactionalRequest<
          ::test_protocolpayloads::MainProtocol::OneWayImport>>
      _request_message(_allocation->data, _buffer_size, &_request);
  return _client_base()->SendOneWay(_request_message.GetOutgoingMessage());
}
::fidl::Status fidl::internal::WireWeakOnewayBufferClientImpl<
    ::test_protocolpayloads::MainProtocol>::OneWayAnon(uint32_t a, uint32_t b) {
  constexpr uint32_t _buffer_size =
      ::fidl::AsyncClientMethodBufferSizeInChannel<
          ::test_protocolpayloads::MainProtocol::OneWayAnon>();
  ::fitx::result<::fidl::Error, ::fidl::BufferSpan> _allocation =
      _allocator().TryAllocate(_buffer_size);
  if (!_allocation.is_ok()) {
    return _allocation.error_value();
  }

  ::fidl::internal::TransactionalRequest<
      ::test_protocolpayloads::MainProtocol::OneWayAnon>
      _request{a, b};
  ::fidl::unstable::UnownedEncodedMessage<
      ::fidl::internal::TransactionalRequest<
          ::test_protocolpayloads::MainProtocol::OneWayAnon>>
      _request_message(_allocation->data, _buffer_size, &_request);
  return _client_base()->SendOneWay(_request_message.GetOutgoingMessage());
}
::fidl::internal::WireBufferThenable<
    ::test_protocolpayloads::MainProtocol::TwoWayComposed>
fidl::internal::WireWeakAsyncBufferClientImpl<
    ::test_protocolpayloads::MainProtocol>::TwoWayComposed(int32_t a) {
  constexpr uint32_t _buffer_size =
      ::fidl::AsyncClientMethodBufferSizeInChannel<
          ::test_protocolpayloads::MainProtocol::TwoWayComposed>();
  ::fidl::internal::TransactionalRequest<
      ::test_protocolpayloads::MainProtocol::TwoWayComposed>
      _request{a};
  return ::fidl::internal::WireBufferThenable<
      ::test_protocolpayloads::MainProtocol::TwoWayComposed>{
      _client_base(), ::fidl::WriteOptions{}, _allocator(), _buffer_size,
      &_request};
}
::fidl::internal::WireBufferThenable<
    ::test_protocolpayloads::MainProtocol::TwoWayComposedWithError>
fidl::internal::WireWeakAsyncBufferClientImpl<
    ::test_protocolpayloads::MainProtocol>::TwoWayComposedWithError(int32_t a) {
  constexpr uint32_t _buffer_size =
      ::fidl::AsyncClientMethodBufferSizeInChannel<
          ::test_protocolpayloads::MainProtocol::TwoWayComposedWithError>();
  ::fidl::internal::TransactionalRequest<
      ::test_protocolpayloads::MainProtocol::TwoWayComposedWithError>
      _request{a};
  return ::fidl::internal::WireBufferThenable<
      ::test_protocolpayloads::MainProtocol::TwoWayComposedWithError>{
      _client_base(), ::fidl::WriteOptions{}, _allocator(), _buffer_size,
      &_request};
}
::fidl::internal::WireBufferThenable<
    ::test_protocolpayloads::MainProtocol::TwoWayLocal>
fidl::internal::WireWeakAsyncBufferClientImpl<
    ::test_protocolpayloads::MainProtocol>::TwoWayLocal(uint32_t a,
                                                        uint32_t b) {
  constexpr uint32_t _buffer_size =
      ::fidl::AsyncClientMethodBufferSizeInChannel<
          ::test_protocolpayloads::MainProtocol::TwoWayLocal>();
  ::fidl::internal::TransactionalRequest<
      ::test_protocolpayloads::MainProtocol::TwoWayLocal>
      _request{a, b};
  return ::fidl::internal::WireBufferThenable<
      ::test_protocolpayloads::MainProtocol::TwoWayLocal>{
      _client_base(), ::fidl::WriteOptions{}, _allocator(), _buffer_size,
      &_request};
}
::fidl::internal::WireBufferThenable<
    ::test_protocolpayloads::MainProtocol::TwoWayLocalWithError>
fidl::internal::WireWeakAsyncBufferClientImpl<
    ::test_protocolpayloads::MainProtocol>::TwoWayLocalWithError(uint32_t a,
                                                                 uint32_t b) {
  constexpr uint32_t _buffer_size =
      ::fidl::AsyncClientMethodBufferSizeInChannel<
          ::test_protocolpayloads::MainProtocol::TwoWayLocalWithError>();
  ::fidl::internal::TransactionalRequest<
      ::test_protocolpayloads::MainProtocol::TwoWayLocalWithError>
      _request{a, b};
  return ::fidl::internal::WireBufferThenable<
      ::test_protocolpayloads::MainProtocol::TwoWayLocalWithError>{
      _client_base(), ::fidl::WriteOptions{}, _allocator(), _buffer_size,
      &_request};
}
::fidl::internal::WireBufferThenable<
    ::test_protocolpayloads::MainProtocol::TwoWayImport>
fidl::internal::WireWeakAsyncBufferClientImpl<
    ::test_protocolpayloads::MainProtocol>::TwoWayImport(int32_t a) {
  constexpr uint32_t _buffer_size =
      ::fidl::AsyncClientMethodBufferSizeInChannel<
          ::test_protocolpayloads::MainProtocol::TwoWayImport>();
  ::fidl::internal::TransactionalRequest<
      ::test_protocolpayloads::MainProtocol::TwoWayImport>
      _request{a};
  return ::fidl::internal::WireBufferThenable<
      ::test_protocolpayloads::MainProtocol::TwoWayImport>{
      _client_base(), ::fidl::WriteOptions{}, _allocator(), _buffer_size,
      &_request};
}
::fidl::internal::WireBufferThenable<
    ::test_protocolpayloads::MainProtocol::TwoWayImportWithError>
fidl::internal::WireWeakAsyncBufferClientImpl<
    ::test_protocolpayloads::MainProtocol>::TwoWayImportWithError(int32_t a) {
  constexpr uint32_t _buffer_size =
      ::fidl::AsyncClientMethodBufferSizeInChannel<
          ::test_protocolpayloads::MainProtocol::TwoWayImportWithError>();
  ::fidl::internal::TransactionalRequest<
      ::test_protocolpayloads::MainProtocol::TwoWayImportWithError>
      _request{a};
  return ::fidl::internal::WireBufferThenable<
      ::test_protocolpayloads::MainProtocol::TwoWayImportWithError>{
      _client_base(), ::fidl::WriteOptions{}, _allocator(), _buffer_size,
      &_request};
}
::fidl::internal::WireBufferThenable<
    ::test_protocolpayloads::MainProtocol::TwoWayAnon>
fidl::internal::WireWeakAsyncBufferClientImpl<
    ::test_protocolpayloads::MainProtocol>::TwoWayAnon(uint32_t a, uint32_t b) {
  constexpr uint32_t _buffer_size =
      ::fidl::AsyncClientMethodBufferSizeInChannel<
          ::test_protocolpayloads::MainProtocol::TwoWayAnon>();
  ::fidl::internal::TransactionalRequest<
      ::test_protocolpayloads::MainProtocol::TwoWayAnon>
      _request{a, b};
  return ::fidl::internal::WireBufferThenable<
      ::test_protocolpayloads::MainProtocol::TwoWayAnon>{
      _client_base(), ::fidl::WriteOptions{}, _allocator(), _buffer_size,
      &_request};
}
::fidl::internal::WireBufferThenable<
    ::test_protocolpayloads::MainProtocol::TwoWayAnonWithError>
fidl::internal::WireWeakAsyncBufferClientImpl<
    ::test_protocolpayloads::MainProtocol>::TwoWayAnonWithError(uint32_t a,
                                                                uint32_t b) {
  constexpr uint32_t _buffer_size =
      ::fidl::AsyncClientMethodBufferSizeInChannel<
          ::test_protocolpayloads::MainProtocol::TwoWayAnonWithError>();
  ::fidl::internal::TransactionalRequest<
      ::test_protocolpayloads::MainProtocol::TwoWayAnonWithError>
      _request{a, b};
  return ::fidl::internal::WireBufferThenable<
      ::test_protocolpayloads::MainProtocol::TwoWayAnonWithError>{
      _client_base(), ::fidl::WriteOptions{}, _allocator(), _buffer_size,
      &_request};
}

::fidl::WireResult<::test_protocolpayloads::MainProtocol::TwoWayComposed>
fidl::internal::WireWeakSyncClientImpl<
    ::test_protocolpayloads::MainProtocol>::TwoWayComposed(int32_t a) {
  return _client_base()->MakeSyncCallWith(
      [&](std::shared_ptr<::fidl::internal::AnyTransport> _transport) {
        ::fidl::internal::TransactionalRequest<
            ::test_protocolpayloads::MainProtocol::TwoWayComposed>
            _request{a};
        return ::fidl::WireResult<
            ::test_protocolpayloads::MainProtocol::TwoWayComposed>(
            ::fidl::UnownedClientEnd<::test_protocolpayloads::MainProtocol>(
                _transport->get<::fidl::internal::ChannelTransport>()),
            &_request);
      });
}

::fidl::WireResult<
    ::test_protocolpayloads::MainProtocol::TwoWayComposedWithError>
fidl::internal::WireWeakSyncClientImpl<
    ::test_protocolpayloads::MainProtocol>::TwoWayComposedWithError(int32_t a) {
  return _client_base()->MakeSyncCallWith(
      [&](std::shared_ptr<::fidl::internal::AnyTransport> _transport) {
        ::fidl::internal::TransactionalRequest<
            ::test_protocolpayloads::MainProtocol::TwoWayComposedWithError>
            _request{a};
        return ::fidl::WireResult<
            ::test_protocolpayloads::MainProtocol::TwoWayComposedWithError>(
            ::fidl::UnownedClientEnd<::test_protocolpayloads::MainProtocol>(
                _transport->get<::fidl::internal::ChannelTransport>()),
            &_request);
      });
}

::fidl::WireResult<::test_protocolpayloads::MainProtocol::TwoWayLocal>
fidl::internal::WireWeakSyncClientImpl<
    ::test_protocolpayloads::MainProtocol>::TwoWayLocal(uint32_t a,
                                                        uint32_t b) {
  return _client_base()->MakeSyncCallWith(
      [&](std::shared_ptr<::fidl::internal::AnyTransport> _transport) {
        ::fidl::internal::TransactionalRequest<
            ::test_protocolpayloads::MainProtocol::TwoWayLocal>
            _request{a, b};
        return ::fidl::WireResult<
            ::test_protocolpayloads::MainProtocol::TwoWayLocal>(
            ::fidl::UnownedClientEnd<::test_protocolpayloads::MainProtocol>(
                _transport->get<::fidl::internal::ChannelTransport>()),
            &_request);
      });
}

::fidl::WireResult<::test_protocolpayloads::MainProtocol::TwoWayLocalWithError>
fidl::internal::WireWeakSyncClientImpl<
    ::test_protocolpayloads::MainProtocol>::TwoWayLocalWithError(uint32_t a,
                                                                 uint32_t b) {
  return _client_base()->MakeSyncCallWith(
      [&](std::shared_ptr<::fidl::internal::AnyTransport> _transport) {
        ::fidl::internal::TransactionalRequest<
            ::test_protocolpayloads::MainProtocol::TwoWayLocalWithError>
            _request{a, b};
        return ::fidl::WireResult<
            ::test_protocolpayloads::MainProtocol::TwoWayLocalWithError>(
            ::fidl::UnownedClientEnd<::test_protocolpayloads::MainProtocol>(
                _transport->get<::fidl::internal::ChannelTransport>()),
            &_request);
      });
}

::fidl::WireResult<::test_protocolpayloads::MainProtocol::TwoWayImport>
fidl::internal::WireWeakSyncClientImpl<
    ::test_protocolpayloads::MainProtocol>::TwoWayImport(int32_t a) {
  return _client_base()->MakeSyncCallWith(
      [&](std::shared_ptr<::fidl::internal::AnyTransport> _transport) {
        ::fidl::internal::TransactionalRequest<
            ::test_protocolpayloads::MainProtocol::TwoWayImport>
            _request{a};
        return ::fidl::WireResult<
            ::test_protocolpayloads::MainProtocol::TwoWayImport>(
            ::fidl::UnownedClientEnd<::test_protocolpayloads::MainProtocol>(
                _transport->get<::fidl::internal::ChannelTransport>()),
            &_request);
      });
}

::fidl::WireResult<::test_protocolpayloads::MainProtocol::TwoWayImportWithError>
fidl::internal::WireWeakSyncClientImpl<
    ::test_protocolpayloads::MainProtocol>::TwoWayImportWithError(int32_t a) {
  return _client_base()->MakeSyncCallWith(
      [&](std::shared_ptr<::fidl::internal::AnyTransport> _transport) {
        ::fidl::internal::TransactionalRequest<
            ::test_protocolpayloads::MainProtocol::TwoWayImportWithError>
            _request{a};
        return ::fidl::WireResult<
            ::test_protocolpayloads::MainProtocol::TwoWayImportWithError>(
            ::fidl::UnownedClientEnd<::test_protocolpayloads::MainProtocol>(
                _transport->get<::fidl::internal::ChannelTransport>()),
            &_request);
      });
}

::fidl::WireResult<::test_protocolpayloads::MainProtocol::TwoWayAnon>
fidl::internal::WireWeakSyncClientImpl<
    ::test_protocolpayloads::MainProtocol>::TwoWayAnon(uint32_t a, uint32_t b) {
  return _client_base()->MakeSyncCallWith(
      [&](std::shared_ptr<::fidl::internal::AnyTransport> _transport) {
        ::fidl::internal::TransactionalRequest<
            ::test_protocolpayloads::MainProtocol::TwoWayAnon>
            _request{a, b};
        return ::fidl::WireResult<
            ::test_protocolpayloads::MainProtocol::TwoWayAnon>(
            ::fidl::UnownedClientEnd<::test_protocolpayloads::MainProtocol>(
                _transport->get<::fidl::internal::ChannelTransport>()),
            &_request);
      });
}

::fidl::WireResult<::test_protocolpayloads::MainProtocol::TwoWayAnonWithError>
fidl::internal::WireWeakSyncClientImpl<
    ::test_protocolpayloads::MainProtocol>::TwoWayAnonWithError(uint32_t a,
                                                                uint32_t b) {
  return _client_base()->MakeSyncCallWith(
      [&](std::shared_ptr<::fidl::internal::AnyTransport> _transport) {
        ::fidl::internal::TransactionalRequest<
            ::test_protocolpayloads::MainProtocol::TwoWayAnonWithError>
            _request{a, b};
        return ::fidl::WireResult<
            ::test_protocolpayloads::MainProtocol::TwoWayAnonWithError>(
            ::fidl::UnownedClientEnd<::test_protocolpayloads::MainProtocol>(
                _transport->get<::fidl::internal::ChannelTransport>()),
            &_request);
      });
}
#endif  // __Fuchsia__

#ifdef __Fuchsia__

::fidl::Status fidl::
    WireSyncEventHandler<::test_protocolpayloads::MainProtocol>::HandleOneEvent(
        ::fidl::UnownedClientEnd<::test_protocolpayloads::MainProtocol>
            client_end) {
  zx_status_t status = client_end.channel()->wait_one(
      ZX_CHANNEL_READABLE | ZX_CHANNEL_PEER_CLOSED, ::zx::time::infinite(),
      nullptr);
  if (status != ZX_OK) {
    return ::fidl::Status::TransportError(
        status, ::fidl::internal::kErrorWaitOneFailed);
  }
  constexpr uint32_t kHandleAllocSize = ([]() constexpr {
    uint32_t x = 0;
    if (::fidl::TypeTraits<::fidl::internal::TransactionalEvent<
            ::test_protocolpayloads::MainProtocol::OnComposed>>::
            kMaxNumHandles >= x) {
      x = ::fidl::TypeTraits<::fidl::internal::TransactionalEvent<
          ::test_protocolpayloads::MainProtocol::OnComposed>>::kMaxNumHandles;
    }
    if (::fidl::TypeTraits<::fidl::internal::TransactionalEvent<
            ::test_protocolpayloads::MainProtocol::OnComposedWithError>>::
            kMaxNumHandles >= x) {
      x = ::fidl::TypeTraits<::fidl::internal::TransactionalEvent<
          ::test_protocolpayloads::MainProtocol::OnComposedWithError>>::
          kMaxNumHandles;
    }
    if (::fidl::TypeTraits<::fidl::internal::TransactionalEvent<
            ::test_protocolpayloads::MainProtocol::OnLocal>>::kMaxNumHandles >=
        x) {
      x = ::fidl::TypeTraits<::fidl::internal::TransactionalEvent<
          ::test_protocolpayloads::MainProtocol::OnLocal>>::kMaxNumHandles;
    }
    if (::fidl::TypeTraits<::fidl::internal::TransactionalEvent<
            ::test_protocolpayloads::MainProtocol::OnLocalWithError>>::
            kMaxNumHandles >= x) {
      x = ::fidl::TypeTraits<::fidl::internal::TransactionalEvent<
          ::test_protocolpayloads::MainProtocol::OnLocalWithError>>::
          kMaxNumHandles;
    }
    if (::fidl::TypeTraits<::fidl::internal::TransactionalEvent<
            ::test_protocolpayloads::MainProtocol::OnImport>>::kMaxNumHandles >=
        x) {
      x = ::fidl::TypeTraits<::fidl::internal::TransactionalEvent<
          ::test_protocolpayloads::MainProtocol::OnImport>>::kMaxNumHandles;
    }
    if (::fidl::TypeTraits<::fidl::internal::TransactionalEvent<
            ::test_protocolpayloads::MainProtocol::OnImportWithError>>::
            kMaxNumHandles >= x) {
      x = ::fidl::TypeTraits<::fidl::internal::TransactionalEvent<
          ::test_protocolpayloads::MainProtocol::OnImportWithError>>::
          kMaxNumHandles;
    }
    if (::fidl::TypeTraits<::fidl::internal::TransactionalEvent<
            ::test_protocolpayloads::MainProtocol::OnAnon>>::kMaxNumHandles >=
        x) {
      x = ::fidl::TypeTraits<::fidl::internal::TransactionalEvent<
          ::test_protocolpayloads::MainProtocol::OnAnon>>::kMaxNumHandles;
    }
    if (::fidl::TypeTraits<::fidl::internal::TransactionalEvent<
            ::test_protocolpayloads::MainProtocol::OnAnonWithError>>::
            kMaxNumHandles >= x) {
      x = ::fidl::TypeTraits<::fidl::internal::TransactionalEvent<
          ::test_protocolpayloads::MainProtocol::OnAnonWithError>>::
          kMaxNumHandles;
    }
    if (x > ZX_CHANNEL_MAX_MSG_HANDLES) {
      x = ZX_CHANNEL_MAX_MSG_HANDLES;
    }
    return x;
  })();
  static_assert(kHandleAllocSize <= ZX_CHANNEL_MAX_MSG_HANDLES);
  ::fidl::internal::InlineMessageBuffer<48> read_storage;
  std::array<zx_handle_t, kHandleAllocSize> read_handles;
  // TODO(fxbug.dev/85734) Remove this channel-specific allocation.
  std::array<fidl_channel_handle_metadata_t, kHandleAllocSize>
      read_handle_metadata;
  ::fidl::IncomingMessage msg = ::fidl::MessageRead(
      zx::unowned_channel(client_end.handle()), read_storage.view(),
      read_handles.data(), read_handle_metadata.data(), kHandleAllocSize,
      ReadOptions{.discardable = true});
  if (msg.status() == ZX_ERR_BUFFER_TOO_SMALL) {
    // Message size is unexpectedly larger than calculated.
    // This can only be due to a newer version of the protocol defining a new
    // event, whose size exceeds the maximum of known events in the current
    // protocol.
    return ::fidl::Status::UnexpectedMessage(
        ZX_ERR_BUFFER_TOO_SMALL,
        ::fidl::internal::kErrorSyncEventBufferTooSmall);
  }
  if (!msg.ok()) {
    return msg;
  }
  fidl_message_header_t* hdr = msg.header();
  switch (hdr->ordinal) {
    case ::test_protocolpayloads::kMainProtocol_OnComposed_Ordinal: {
      ::fidl::unstable::DecodedMessage<::fidl::internal::TransactionalEvent<
          ::test_protocolpayloads::MainProtocol::OnComposed>>
          decoded{::std::move(msg)};
      if (!decoded.ok()) {
        return ::fidl::Status(decoded);
      }
      auto* primary = &decoded.PrimaryObject()->body;
      got_transitional_ = false;
      OnComposed(primary);
      if (got_transitional_) {
        return ::fidl::Status::UnexpectedMessage(
            ZX_ERR_NOT_SUPPORTED,
            ::fidl::internal::kErrorSyncEventUnhandledTransitionalEvent);
      }
      return ::fidl::Status::Ok();
    }
    case ::test_protocolpayloads::kMainProtocol_OnComposedWithError_Ordinal: {
      ::fidl::unstable::DecodedMessage<::fidl::internal::TransactionalEvent<
          ::test_protocolpayloads::MainProtocol::OnComposedWithError>>
          decoded{::std::move(msg)};
      if (!decoded.ok()) {
        return ::fidl::Status(decoded);
      }
      auto* primary = &decoded.PrimaryObject()->body;
      got_transitional_ = false;
      OnComposedWithError(primary);
      if (got_transitional_) {
        return ::fidl::Status::UnexpectedMessage(
            ZX_ERR_NOT_SUPPORTED,
            ::fidl::internal::kErrorSyncEventUnhandledTransitionalEvent);
      }
      return ::fidl::Status::Ok();
    }
    case ::test_protocolpayloads::kMainProtocol_OnLocal_Ordinal: {
      ::fidl::unstable::DecodedMessage<::fidl::internal::TransactionalEvent<
          ::test_protocolpayloads::MainProtocol::OnLocal>>
          decoded{::std::move(msg)};
      if (!decoded.ok()) {
        return ::fidl::Status(decoded);
      }
      auto* primary = &decoded.PrimaryObject()->body;
      got_transitional_ = false;
      OnLocal(primary);
      if (got_transitional_) {
        return ::fidl::Status::UnexpectedMessage(
            ZX_ERR_NOT_SUPPORTED,
            ::fidl::internal::kErrorSyncEventUnhandledTransitionalEvent);
      }
      return ::fidl::Status::Ok();
    }
    case ::test_protocolpayloads::kMainProtocol_OnLocalWithError_Ordinal: {
      ::fidl::unstable::DecodedMessage<::fidl::internal::TransactionalEvent<
          ::test_protocolpayloads::MainProtocol::OnLocalWithError>>
          decoded{::std::move(msg)};
      if (!decoded.ok()) {
        return ::fidl::Status(decoded);
      }
      auto* primary = &decoded.PrimaryObject()->body;
      got_transitional_ = false;
      OnLocalWithError(primary);
      if (got_transitional_) {
        return ::fidl::Status::UnexpectedMessage(
            ZX_ERR_NOT_SUPPORTED,
            ::fidl::internal::kErrorSyncEventUnhandledTransitionalEvent);
      }
      return ::fidl::Status::Ok();
    }
    case ::test_protocolpayloads::kMainProtocol_OnImport_Ordinal: {
      ::fidl::unstable::DecodedMessage<::fidl::internal::TransactionalEvent<
          ::test_protocolpayloads::MainProtocol::OnImport>>
          decoded{::std::move(msg)};
      if (!decoded.ok()) {
        return ::fidl::Status(decoded);
      }
      auto* primary = &decoded.PrimaryObject()->body;
      got_transitional_ = false;
      OnImport(primary);
      if (got_transitional_) {
        return ::fidl::Status::UnexpectedMessage(
            ZX_ERR_NOT_SUPPORTED,
            ::fidl::internal::kErrorSyncEventUnhandledTransitionalEvent);
      }
      return ::fidl::Status::Ok();
    }
    case ::test_protocolpayloads::kMainProtocol_OnImportWithError_Ordinal: {
      ::fidl::unstable::DecodedMessage<::fidl::internal::TransactionalEvent<
          ::test_protocolpayloads::MainProtocol::OnImportWithError>>
          decoded{::std::move(msg)};
      if (!decoded.ok()) {
        return ::fidl::Status(decoded);
      }
      auto* primary = &decoded.PrimaryObject()->body;
      got_transitional_ = false;
      OnImportWithError(primary);
      if (got_transitional_) {
        return ::fidl::Status::UnexpectedMessage(
            ZX_ERR_NOT_SUPPORTED,
            ::fidl::internal::kErrorSyncEventUnhandledTransitionalEvent);
      }
      return ::fidl::Status::Ok();
    }
    case ::test_protocolpayloads::kMainProtocol_OnAnon_Ordinal: {
      ::fidl::unstable::DecodedMessage<::fidl::internal::TransactionalEvent<
          ::test_protocolpayloads::MainProtocol::OnAnon>>
          decoded{::std::move(msg)};
      if (!decoded.ok()) {
        return ::fidl::Status(decoded);
      }
      auto* primary = &decoded.PrimaryObject()->body;
      got_transitional_ = false;
      OnAnon(primary);
      if (got_transitional_) {
        return ::fidl::Status::UnexpectedMessage(
            ZX_ERR_NOT_SUPPORTED,
            ::fidl::internal::kErrorSyncEventUnhandledTransitionalEvent);
      }
      return ::fidl::Status::Ok();
    }
    case ::test_protocolpayloads::kMainProtocol_OnAnonWithError_Ordinal: {
      ::fidl::unstable::DecodedMessage<::fidl::internal::TransactionalEvent<
          ::test_protocolpayloads::MainProtocol::OnAnonWithError>>
          decoded{::std::move(msg)};
      if (!decoded.ok()) {
        return ::fidl::Status(decoded);
      }
      auto* primary = &decoded.PrimaryObject()->body;
      got_transitional_ = false;
      OnAnonWithError(primary);
      if (got_transitional_) {
        return ::fidl::Status::UnexpectedMessage(
            ZX_ERR_NOT_SUPPORTED,
            ::fidl::internal::kErrorSyncEventUnhandledTransitionalEvent);
      }
      return ::fidl::Status::Ok();
    }
    default: {
      return ::fidl::Status::UnknownOrdinal();
    }
  }
}

std::optional<::fidl::UnbindInfo> fidl::internal::
    WireEventDispatcher<::test_protocolpayloads::MainProtocol>::DispatchEvent(
        ::fidl::IncomingMessage& msg,
        ::fidl::internal::IncomingTransportContext transport_context) {
  switch (msg.header()->ordinal) {
    case ::test_protocolpayloads::kMainProtocol_OnComposed_Ordinal: {
      ::fidl::unstable::DecodedMessage<::fidl::internal::TransactionalEvent<
          ::test_protocolpayloads::MainProtocol::OnComposed>>
          decoded{std::move(msg)};
      if (!decoded.ok()) {
        return ::fidl::UnbindInfo{decoded};
      }
      if (event_handler()) {
        auto* primary = &decoded.PrimaryObject()->body;
        event_handler()->OnComposed(primary);
      }
      return std::nullopt;
    }
    case ::test_protocolpayloads::kMainProtocol_OnComposedWithError_Ordinal: {
      ::fidl::unstable::DecodedMessage<::fidl::internal::TransactionalEvent<
          ::test_protocolpayloads::MainProtocol::OnComposedWithError>>
          decoded{std::move(msg)};
      if (!decoded.ok()) {
        return ::fidl::UnbindInfo{decoded};
      }
      if (event_handler()) {
        auto* primary = &decoded.PrimaryObject()->body;
        event_handler()->OnComposedWithError(primary);
      }
      return std::nullopt;
    }
    case ::test_protocolpayloads::kMainProtocol_OnLocal_Ordinal: {
      ::fidl::unstable::DecodedMessage<::fidl::internal::TransactionalEvent<
          ::test_protocolpayloads::MainProtocol::OnLocal>>
          decoded{std::move(msg)};
      if (!decoded.ok()) {
        return ::fidl::UnbindInfo{decoded};
      }
      if (event_handler()) {
        auto* primary = &decoded.PrimaryObject()->body;
        event_handler()->OnLocal(primary);
      }
      return std::nullopt;
    }
    case ::test_protocolpayloads::kMainProtocol_OnLocalWithError_Ordinal: {
      ::fidl::unstable::DecodedMessage<::fidl::internal::TransactionalEvent<
          ::test_protocolpayloads::MainProtocol::OnLocalWithError>>
          decoded{std::move(msg)};
      if (!decoded.ok()) {
        return ::fidl::UnbindInfo{decoded};
      }
      if (event_handler()) {
        auto* primary = &decoded.PrimaryObject()->body;
        event_handler()->OnLocalWithError(primary);
      }
      return std::nullopt;
    }
    case ::test_protocolpayloads::kMainProtocol_OnImport_Ordinal: {
      ::fidl::unstable::DecodedMessage<::fidl::internal::TransactionalEvent<
          ::test_protocolpayloads::MainProtocol::OnImport>>
          decoded{std::move(msg)};
      if (!decoded.ok()) {
        return ::fidl::UnbindInfo{decoded};
      }
      if (event_handler()) {
        auto* primary = &decoded.PrimaryObject()->body;
        event_handler()->OnImport(primary);
      }
      return std::nullopt;
    }
    case ::test_protocolpayloads::kMainProtocol_OnImportWithError_Ordinal: {
      ::fidl::unstable::DecodedMessage<::fidl::internal::TransactionalEvent<
          ::test_protocolpayloads::MainProtocol::OnImportWithError>>
          decoded{std::move(msg)};
      if (!decoded.ok()) {
        return ::fidl::UnbindInfo{decoded};
      }
      if (event_handler()) {
        auto* primary = &decoded.PrimaryObject()->body;
        event_handler()->OnImportWithError(primary);
      }
      return std::nullopt;
    }
    case ::test_protocolpayloads::kMainProtocol_OnAnon_Ordinal: {
      ::fidl::unstable::DecodedMessage<::fidl::internal::TransactionalEvent<
          ::test_protocolpayloads::MainProtocol::OnAnon>>
          decoded{std::move(msg)};
      if (!decoded.ok()) {
        return ::fidl::UnbindInfo{decoded};
      }
      if (event_handler()) {
        auto* primary = &decoded.PrimaryObject()->body;
        event_handler()->OnAnon(primary);
      }
      return std::nullopt;
    }
    case ::test_protocolpayloads::kMainProtocol_OnAnonWithError_Ordinal: {
      ::fidl::unstable::DecodedMessage<::fidl::internal::TransactionalEvent<
          ::test_protocolpayloads::MainProtocol::OnAnonWithError>>
          decoded{std::move(msg)};
      if (!decoded.ok()) {
        return ::fidl::UnbindInfo{decoded};
      }
      if (event_handler()) {
        auto* primary = &decoded.PrimaryObject()->body;
        event_handler()->OnAnonWithError(primary);
      }
      return std::nullopt;
    }
    default:
      break;
  }
  return ::fidl::UnbindInfo::UnknownOrdinal();
}
#endif  // __Fuchsia__

#ifdef __Fuchsia__

constexpr ::fidl::internal::MethodEntry fidl::internal::WireServerDispatcher<
    ::test_protocolpayloads::MainProtocol>::entries_[] = {
    {
        ::test_protocolpayloads::kMainProtocol_OneWayComposed_Ordinal,
        [](void* interface, ::fidl::IncomingMessage&& msg,
           internal::IncomingTransportContext transport_context,
           ::fidl::Transaction* txn) {
          ::fidl::unstable::DecodedMessage<
              ::fidl::internal::TransactionalRequest<
                  ::test_protocolpayloads::MainProtocol::OneWayComposed>>
              decoded{std::move(msg)};
          if (unlikely(!decoded.ok())) {
            return decoded.status();
          }
          auto* primary = &decoded.PrimaryObject()->body;
          ::fidl::internal::WireCompleter<
              ::test_protocolpayloads::MainProtocol::OneWayComposed>::Sync
              completer(txn);
          reinterpret_cast<
              ::fidl::WireServer<::test_protocolpayloads::MainProtocol>*>(
              interface)
              ->OneWayComposed(primary, completer);
          return ZX_OK;
        },
    },
    {
        ::test_protocolpayloads::kMainProtocol_TwoWayComposed_Ordinal,
        [](void* interface, ::fidl::IncomingMessage&& msg,
           internal::IncomingTransportContext transport_context,
           ::fidl::Transaction* txn) {
          ::fidl::unstable::DecodedMessage<
              ::fidl::internal::TransactionalRequest<
                  ::test_protocolpayloads::MainProtocol::TwoWayComposed>>
              decoded{std::move(msg)};
          if (unlikely(!decoded.ok())) {
            return decoded.status();
          }
          auto* primary = &decoded.PrimaryObject()->body;
          ::fidl::internal::WireCompleter<
              ::test_protocolpayloads::MainProtocol::TwoWayComposed>::Sync
              completer(txn);
          reinterpret_cast<
              ::fidl::WireServer<::test_protocolpayloads::MainProtocol>*>(
              interface)
              ->TwoWayComposed(primary, completer);
          return ZX_OK;
        },
    },
    {
        ::test_protocolpayloads::kMainProtocol_TwoWayComposedWithError_Ordinal,
        [](void* interface, ::fidl::IncomingMessage&& msg,
           internal::IncomingTransportContext transport_context,
           ::fidl::Transaction* txn) {
          ::fidl::unstable::DecodedMessage<
              ::fidl::internal::TransactionalRequest<
                  ::test_protocolpayloads::MainProtocol::
                      TwoWayComposedWithError>>
              decoded{std::move(msg)};
          if (unlikely(!decoded.ok())) {
            return decoded.status();
          }
          auto* primary = &decoded.PrimaryObject()->body;
          ::fidl::internal::WireCompleter<
              ::test_protocolpayloads::MainProtocol::TwoWayComposedWithError>::
              Sync completer(txn);
          reinterpret_cast<
              ::fidl::WireServer<::test_protocolpayloads::MainProtocol>*>(
              interface)
              ->TwoWayComposedWithError(primary, completer);
          return ZX_OK;
        },
    },
    {
        ::test_protocolpayloads::kMainProtocol_OneWayLocal_Ordinal,
        [](void* interface, ::fidl::IncomingMessage&& msg,
           internal::IncomingTransportContext transport_context,
           ::fidl::Transaction* txn) {
          ::fidl::unstable::DecodedMessage<
              ::fidl::internal::TransactionalRequest<
                  ::test_protocolpayloads::MainProtocol::OneWayLocal>>
              decoded{std::move(msg)};
          if (unlikely(!decoded.ok())) {
            return decoded.status();
          }
          auto* primary = &decoded.PrimaryObject()->body;
          ::fidl::internal::WireCompleter<
              ::test_protocolpayloads::MainProtocol::OneWayLocal>::Sync
              completer(txn);
          reinterpret_cast<
              ::fidl::WireServer<::test_protocolpayloads::MainProtocol>*>(
              interface)
              ->OneWayLocal(primary, completer);
          return ZX_OK;
        },
    },
    {
        ::test_protocolpayloads::kMainProtocol_TwoWayLocal_Ordinal,
        [](void* interface, ::fidl::IncomingMessage&& msg,
           internal::IncomingTransportContext transport_context,
           ::fidl::Transaction* txn) {
          ::fidl::unstable::DecodedMessage<
              ::fidl::internal::TransactionalRequest<
                  ::test_protocolpayloads::MainProtocol::TwoWayLocal>>
              decoded{std::move(msg)};
          if (unlikely(!decoded.ok())) {
            return decoded.status();
          }
          auto* primary = &decoded.PrimaryObject()->body;
          ::fidl::internal::WireCompleter<
              ::test_protocolpayloads::MainProtocol::TwoWayLocal>::Sync
              completer(txn);
          reinterpret_cast<
              ::fidl::WireServer<::test_protocolpayloads::MainProtocol>*>(
              interface)
              ->TwoWayLocal(primary, completer);
          return ZX_OK;
        },
    },
    {
        ::test_protocolpayloads::kMainProtocol_TwoWayLocalWithError_Ordinal,
        [](void* interface, ::fidl::IncomingMessage&& msg,
           internal::IncomingTransportContext transport_context,
           ::fidl::Transaction* txn) {
          ::fidl::unstable::DecodedMessage<
              ::fidl::internal::TransactionalRequest<
                  ::test_protocolpayloads::MainProtocol::TwoWayLocalWithError>>
              decoded{std::move(msg)};
          if (unlikely(!decoded.ok())) {
            return decoded.status();
          }
          auto* primary = &decoded.PrimaryObject()->body;
          ::fidl::internal::WireCompleter<
              ::test_protocolpayloads::MainProtocol::TwoWayLocalWithError>::Sync
              completer(txn);
          reinterpret_cast<
              ::fidl::WireServer<::test_protocolpayloads::MainProtocol>*>(
              interface)
              ->TwoWayLocalWithError(primary, completer);
          return ZX_OK;
        },
    },
    {
        ::test_protocolpayloads::kMainProtocol_OneWayImport_Ordinal,
        [](void* interface, ::fidl::IncomingMessage&& msg,
           internal::IncomingTransportContext transport_context,
           ::fidl::Transaction* txn) {
          ::fidl::unstable::DecodedMessage<
              ::fidl::internal::TransactionalRequest<
                  ::test_protocolpayloads::MainProtocol::OneWayImport>>
              decoded{std::move(msg)};
          if (unlikely(!decoded.ok())) {
            return decoded.status();
          }
          auto* primary = &decoded.PrimaryObject()->body;
          ::fidl::internal::WireCompleter<
              ::test_protocolpayloads::MainProtocol::OneWayImport>::Sync
              completer(txn);
          reinterpret_cast<
              ::fidl::WireServer<::test_protocolpayloads::MainProtocol>*>(
              interface)
              ->OneWayImport(primary, completer);
          return ZX_OK;
        },
    },
    {
        ::test_protocolpayloads::kMainProtocol_TwoWayImport_Ordinal,
        [](void* interface, ::fidl::IncomingMessage&& msg,
           internal::IncomingTransportContext transport_context,
           ::fidl::Transaction* txn) {
          ::fidl::unstable::DecodedMessage<
              ::fidl::internal::TransactionalRequest<
                  ::test_protocolpayloads::MainProtocol::TwoWayImport>>
              decoded{std::move(msg)};
          if (unlikely(!decoded.ok())) {
            return decoded.status();
          }
          auto* primary = &decoded.PrimaryObject()->body;
          ::fidl::internal::WireCompleter<
              ::test_protocolpayloads::MainProtocol::TwoWayImport>::Sync
              completer(txn);
          reinterpret_cast<
              ::fidl::WireServer<::test_protocolpayloads::MainProtocol>*>(
              interface)
              ->TwoWayImport(primary, completer);
          return ZX_OK;
        },
    },
    {
        ::test_protocolpayloads::kMainProtocol_TwoWayImportWithError_Ordinal,
        [](void* interface, ::fidl::IncomingMessage&& msg,
           internal::IncomingTransportContext transport_context,
           ::fidl::Transaction* txn) {
          ::fidl::unstable::DecodedMessage<
              ::fidl::internal::TransactionalRequest<
                  ::test_protocolpayloads::MainProtocol::TwoWayImportWithError>>
              decoded{std::move(msg)};
          if (unlikely(!decoded.ok())) {
            return decoded.status();
          }
          auto* primary = &decoded.PrimaryObject()->body;
          ::fidl::internal::WireCompleter<
              ::test_protocolpayloads::MainProtocol::TwoWayImportWithError>::
              Sync completer(txn);
          reinterpret_cast<
              ::fidl::WireServer<::test_protocolpayloads::MainProtocol>*>(
              interface)
              ->TwoWayImportWithError(primary, completer);
          return ZX_OK;
        },
    },
    {
        ::test_protocolpayloads::kMainProtocol_OneWayAnon_Ordinal,
        [](void* interface, ::fidl::IncomingMessage&& msg,
           internal::IncomingTransportContext transport_context,
           ::fidl::Transaction* txn) {
          ::fidl::unstable::DecodedMessage<
              ::fidl::internal::TransactionalRequest<
                  ::test_protocolpayloads::MainProtocol::OneWayAnon>>
              decoded{std::move(msg)};
          if (unlikely(!decoded.ok())) {
            return decoded.status();
          }
          auto* primary = &decoded.PrimaryObject()->body;
          ::fidl::internal::WireCompleter<
              ::test_protocolpayloads::MainProtocol::OneWayAnon>::Sync
              completer(txn);
          reinterpret_cast<
              ::fidl::WireServer<::test_protocolpayloads::MainProtocol>*>(
              interface)
              ->OneWayAnon(primary, completer);
          return ZX_OK;
        },
    },
    {
        ::test_protocolpayloads::kMainProtocol_TwoWayAnon_Ordinal,
        [](void* interface, ::fidl::IncomingMessage&& msg,
           internal::IncomingTransportContext transport_context,
           ::fidl::Transaction* txn) {
          ::fidl::unstable::DecodedMessage<
              ::fidl::internal::TransactionalRequest<
                  ::test_protocolpayloads::MainProtocol::TwoWayAnon>>
              decoded{std::move(msg)};
          if (unlikely(!decoded.ok())) {
            return decoded.status();
          }
          auto* primary = &decoded.PrimaryObject()->body;
          ::fidl::internal::WireCompleter<
              ::test_protocolpayloads::MainProtocol::TwoWayAnon>::Sync
              completer(txn);
          reinterpret_cast<
              ::fidl::WireServer<::test_protocolpayloads::MainProtocol>*>(
              interface)
              ->TwoWayAnon(primary, completer);
          return ZX_OK;
        },
    },
    {
        ::test_protocolpayloads::kMainProtocol_TwoWayAnonWithError_Ordinal,
        [](void* interface, ::fidl::IncomingMessage&& msg,
           internal::IncomingTransportContext transport_context,
           ::fidl::Transaction* txn) {
          ::fidl::unstable::DecodedMessage<
              ::fidl::internal::TransactionalRequest<
                  ::test_protocolpayloads::MainProtocol::TwoWayAnonWithError>>
              decoded{std::move(msg)};
          if (unlikely(!decoded.ok())) {
            return decoded.status();
          }
          auto* primary = &decoded.PrimaryObject()->body;
          ::fidl::internal::WireCompleter<
              ::test_protocolpayloads::MainProtocol::TwoWayAnonWithError>::Sync
              completer(txn);
          reinterpret_cast<
              ::fidl::WireServer<::test_protocolpayloads::MainProtocol>*>(
              interface)
              ->TwoWayAnonWithError(primary, completer);
          return ZX_OK;
        },
    },
};

const ::fidl::internal::MethodEntry* fidl::internal::WireServerDispatcher<
    ::test_protocolpayloads::MainProtocol>::entries_end_ = &entries_[12];

::fidl::DispatchResult fidl::internal::
    WireServerDispatcher<::test_protocolpayloads::MainProtocol>::TryDispatch(
        ::fidl::WireServer<::test_protocolpayloads::MainProtocol>* impl,
        ::fidl::IncomingMessage& msg,
        internal::IncomingTransportContext transport_context,
        ::fidl::Transaction* txn) {
  return ::fidl::internal::TryDispatch(impl, msg, std::move(transport_context),
                                       txn, entries_, entries_end_);
}

void fidl::internal::
    WireServerDispatcher<::test_protocolpayloads::MainProtocol>::Dispatch(
        ::fidl::WireServer<::test_protocolpayloads::MainProtocol>* impl,
        ::fidl::IncomingMessage&& msg,
        internal::IncomingTransportContext transport_context,
        ::fidl::Transaction* txn) {
  ::fidl::internal::Dispatch(impl, msg, std::move(transport_context), txn,
                             entries_, entries_end_);
}
void fidl::WireServer<::test_protocolpayloads::MainProtocol>::dispatch_message(
    ::fidl::IncomingMessage&& msg, ::fidl::Transaction* txn,
    ::fidl::internal::IncomingTransportContext transport_context) {
  ::fidl::internal::WireServerDispatcher<
      ::test_protocolpayloads::MainProtocol>::Dispatch(this, std::move(msg),
                                                       std::move(
                                                           transport_context),
                                                       txn);
}
#endif  // __Fuchsia__

#ifdef __Fuchsia__
void fidl::internal::WireCompleterImpl<
    ::test_protocolpayloads::MainProtocol::TwoWayComposed>::Reply(int32_t a) {
  ::fidl::internal::TransactionalResponse<
      ::test_protocolpayloads::MainProtocol::TwoWayComposed>
      _response{a};
  FIDL_INTERNAL_DISABLE_AUTO_VAR_INIT
  ::fidl::unstable::OwnedEncodedMessage<
      ::fidl::internal::TransactionalResponse<
          ::test_protocolpayloads::MainProtocol::TwoWayComposed>,
      ::fidl::internal::ChannelTransport>
      _response_message{::fidl::internal::AllowUnownedInputRef{}, &_response};
  return _core()->SendReply(&_response_message.GetOutgoingMessage(),
                            ::fidl::internal::OutgoingTransportContext());
}

void fidl::internal::WireBufferCompleterImpl<
    ::test_protocolpayloads::MainProtocol::TwoWayComposed>::Reply(int32_t a) {
  ::fidl::internal::TransactionalResponse<
      ::test_protocolpayloads::MainProtocol::TwoWayComposed>
      _response{a};
  constexpr uint32_t _buffer_size = ::fidl::ServerReplyBufferSizeInChannel<
      ::test_protocolpayloads::MainProtocol::TwoWayComposed>();
  ::fitx::result<::fidl::Error, ::fidl::BufferSpan> _allocation =
      _allocator().TryAllocate(_buffer_size);
  if (!_allocation.is_ok()) {
    ::fidl::OutgoingMessage _failure{_allocation.error_value()};
    return _core()->SendReply(&_failure,
                              ::fidl::internal::OutgoingTransportContext());
  }
  ::fidl::unstable::UnownedEncodedMessage<
      ::fidl::internal::TransactionalResponse<
          ::test_protocolpayloads::MainProtocol::TwoWayComposed>,
      ::fidl::internal::ChannelTransport>
      _response_message(_allocation->data, _buffer_size, &_response);
  return _core()->SendReply(&_response_message.GetOutgoingMessage(),
                            ::fidl::internal::OutgoingTransportContext());
}
#endif  // __Fuchsia__

#ifdef __Fuchsia__
void fidl::internal::WireCompleterImpl<
    ::test_protocolpayloads::MainProtocol::TwoWayComposedWithError>::
    Reply(::test_protocolpayloads_imported::wire::
              ComposedProtocolTwoWayComposedWithErrorResult result) {
  ::fidl::internal::TransactionalResponse<
      ::test_protocolpayloads::MainProtocol::TwoWayComposedWithError>
      _response{result};
  FIDL_INTERNAL_DISABLE_AUTO_VAR_INIT
  ::fidl::unstable::OwnedEncodedMessage<
      ::fidl::internal::TransactionalResponse<
          ::test_protocolpayloads::MainProtocol::TwoWayComposedWithError>,
      ::fidl::internal::ChannelTransport>
      _response_message{::fidl::internal::AllowUnownedInputRef{}, &_response};
  return _core()->SendReply(&_response_message.GetOutgoingMessage(),
                            ::fidl::internal::OutgoingTransportContext());
}
void fidl::internal::WireCompleterImpl<
    ::test_protocolpayloads::MainProtocol::TwoWayComposedWithError>::
    ReplySuccess(int32_t a) {
  ::test_protocolpayloads_imported::wire::ImportStructPayload _response =
      ::test_protocolpayloads_imported::wire::ImportStructPayload{
          .a = std::move(a),
      };

  return Reply(::test_protocolpayloads_imported::wire::
                   ComposedProtocolTwoWayComposedWithErrorResult::WithResponse(
                       std::move(_response)));
}

void fidl::internal::WireCompleterImpl<
    ::test_protocolpayloads::MainProtocol::TwoWayComposedWithError>::
    ReplyError(uint32_t error) {
  return Reply(::test_protocolpayloads_imported::wire::
                   ComposedProtocolTwoWayComposedWithErrorResult::WithErr(
                       std::move(error)));
}

void fidl::internal::WireBufferCompleterImpl<
    ::test_protocolpayloads::MainProtocol::TwoWayComposedWithError>::
    Reply(::test_protocolpayloads_imported::wire::
              ComposedProtocolTwoWayComposedWithErrorResult result) {
  ::fidl::internal::TransactionalResponse<
      ::test_protocolpayloads::MainProtocol::TwoWayComposedWithError>
      _response{result};
  constexpr uint32_t _buffer_size = ::fidl::ServerReplyBufferSizeInChannel<
      ::test_protocolpayloads::MainProtocol::TwoWayComposedWithError>();
  ::fitx::result<::fidl::Error, ::fidl::BufferSpan> _allocation =
      _allocator().TryAllocate(_buffer_size);
  if (!_allocation.is_ok()) {
    ::fidl::OutgoingMessage _failure{_allocation.error_value()};
    return _core()->SendReply(&_failure,
                              ::fidl::internal::OutgoingTransportContext());
  }
  ::fidl::unstable::UnownedEncodedMessage<
      ::fidl::internal::TransactionalResponse<
          ::test_protocolpayloads::MainProtocol::TwoWayComposedWithError>,
      ::fidl::internal::ChannelTransport>
      _response_message(_allocation->data, _buffer_size, &_response);
  return _core()->SendReply(&_response_message.GetOutgoingMessage(),
                            ::fidl::internal::OutgoingTransportContext());
}
void fidl::internal::WireBufferCompleterImpl<
    ::test_protocolpayloads::MainProtocol::TwoWayComposedWithError>::
    ReplySuccess(int32_t a) {
  ::test_protocolpayloads_imported::wire::ImportStructPayload _response =
      ::test_protocolpayloads_imported::wire::ImportStructPayload{
          .a = std::move(a),
      };

  return Reply(::test_protocolpayloads_imported::wire::
                   ComposedProtocolTwoWayComposedWithErrorResult::WithResponse(
                       std::move(_response)));
}

void fidl::internal::WireBufferCompleterImpl<
    ::test_protocolpayloads::MainProtocol::TwoWayComposedWithError>::
    ReplyError(uint32_t error) {
  return Reply(::test_protocolpayloads_imported::wire::
                   ComposedProtocolTwoWayComposedWithErrorResult::WithErr(
                       std::move(error)));
}
#endif  // __Fuchsia__

#ifdef __Fuchsia__
void fidl::internal::WireCompleterImpl<
    ::test_protocolpayloads::MainProtocol::TwoWayLocal>::Reply(uint32_t a,
                                                               uint32_t b) {
  ::fidl::internal::TransactionalResponse<
      ::test_protocolpayloads::MainProtocol::TwoWayLocal>
      _response{a, b};
  FIDL_INTERNAL_DISABLE_AUTO_VAR_INIT
  ::fidl::unstable::OwnedEncodedMessage<
      ::fidl::internal::TransactionalResponse<
          ::test_protocolpayloads::MainProtocol::TwoWayLocal>,
      ::fidl::internal::ChannelTransport>
      _response_message{::fidl::internal::AllowUnownedInputRef{}, &_response};
  return _core()->SendReply(&_response_message.GetOutgoingMessage(),
                            ::fidl::internal::OutgoingTransportContext());
}

void fidl::internal::WireBufferCompleterImpl<
    ::test_protocolpayloads::MainProtocol::TwoWayLocal>::Reply(uint32_t a,
                                                               uint32_t b) {
  ::fidl::internal::TransactionalResponse<
      ::test_protocolpayloads::MainProtocol::TwoWayLocal>
      _response{a, b};
  constexpr uint32_t _buffer_size = ::fidl::ServerReplyBufferSizeInChannel<
      ::test_protocolpayloads::MainProtocol::TwoWayLocal>();
  ::fitx::result<::fidl::Error, ::fidl::BufferSpan> _allocation =
      _allocator().TryAllocate(_buffer_size);
  if (!_allocation.is_ok()) {
    ::fidl::OutgoingMessage _failure{_allocation.error_value()};
    return _core()->SendReply(&_failure,
                              ::fidl::internal::OutgoingTransportContext());
  }
  ::fidl::unstable::UnownedEncodedMessage<
      ::fidl::internal::TransactionalResponse<
          ::test_protocolpayloads::MainProtocol::TwoWayLocal>,
      ::fidl::internal::ChannelTransport>
      _response_message(_allocation->data, _buffer_size, &_response);
  return _core()->SendReply(&_response_message.GetOutgoingMessage(),
                            ::fidl::internal::OutgoingTransportContext());
}
#endif  // __Fuchsia__

#ifdef __Fuchsia__
void fidl::internal::WireCompleterImpl<
    ::test_protocolpayloads::MainProtocol::TwoWayLocalWithError>::
    Reply(::test_protocolpayloads::wire::MainProtocolTwoWayLocalWithErrorResult
              result) {
  ::fidl::internal::TransactionalResponse<
      ::test_protocolpayloads::MainProtocol::TwoWayLocalWithError>
      _response{result};
  FIDL_INTERNAL_DISABLE_AUTO_VAR_INIT
  ::fidl::unstable::OwnedEncodedMessage<
      ::fidl::internal::TransactionalResponse<
          ::test_protocolpayloads::MainProtocol::TwoWayLocalWithError>,
      ::fidl::internal::ChannelTransport>
      _response_message{::fidl::internal::AllowUnownedInputRef{}, &_response};
  return _core()->SendReply(&_response_message.GetOutgoingMessage(),
                            ::fidl::internal::OutgoingTransportContext());
}
void fidl::internal::WireCompleterImpl<
    ::test_protocolpayloads::MainProtocol::TwoWayLocalWithError>::
    ReplySuccess(uint32_t a, uint32_t b) {
  ::test_protocolpayloads::wire::LocalStructPayload _response =
      ::test_protocolpayloads::wire::LocalStructPayload{
          .a = std::move(a),
          .b = std::move(b),
      };

  return Reply(
      ::test_protocolpayloads::wire::MainProtocolTwoWayLocalWithErrorResult::
          WithResponse(::fidl::ObjectView<
                       ::test_protocolpayloads::wire::LocalStructPayload>::
                           FromExternal(&_response)));
}

void fidl::internal::WireCompleterImpl<
    ::test_protocolpayloads::MainProtocol::TwoWayLocalWithError>::
    ReplyError(uint32_t error) {
  return Reply(
      ::test_protocolpayloads::wire::MainProtocolTwoWayLocalWithErrorResult::
          WithErr(std::move(error)));
}

void fidl::internal::WireBufferCompleterImpl<
    ::test_protocolpayloads::MainProtocol::TwoWayLocalWithError>::
    Reply(::test_protocolpayloads::wire::MainProtocolTwoWayLocalWithErrorResult
              result) {
  ::fidl::internal::TransactionalResponse<
      ::test_protocolpayloads::MainProtocol::TwoWayLocalWithError>
      _response{result};
  constexpr uint32_t _buffer_size = ::fidl::ServerReplyBufferSizeInChannel<
      ::test_protocolpayloads::MainProtocol::TwoWayLocalWithError>();
  ::fitx::result<::fidl::Error, ::fidl::BufferSpan> _allocation =
      _allocator().TryAllocate(_buffer_size);
  if (!_allocation.is_ok()) {
    ::fidl::OutgoingMessage _failure{_allocation.error_value()};
    return _core()->SendReply(&_failure,
                              ::fidl::internal::OutgoingTransportContext());
  }
  ::fidl::unstable::UnownedEncodedMessage<
      ::fidl::internal::TransactionalResponse<
          ::test_protocolpayloads::MainProtocol::TwoWayLocalWithError>,
      ::fidl::internal::ChannelTransport>
      _response_message(_allocation->data, _buffer_size, &_response);
  return _core()->SendReply(&_response_message.GetOutgoingMessage(),
                            ::fidl::internal::OutgoingTransportContext());
}
void fidl::internal::WireBufferCompleterImpl<
    ::test_protocolpayloads::MainProtocol::TwoWayLocalWithError>::
    ReplySuccess(uint32_t a, uint32_t b) {
  ::test_protocolpayloads::wire::LocalStructPayload _response =
      ::test_protocolpayloads::wire::LocalStructPayload{
          .a = std::move(a),
          .b = std::move(b),
      };

  return Reply(
      ::test_protocolpayloads::wire::MainProtocolTwoWayLocalWithErrorResult::
          WithResponse(::fidl::ObjectView<
                       ::test_protocolpayloads::wire::LocalStructPayload>::
                           FromExternal(&_response)));
}

void fidl::internal::WireBufferCompleterImpl<
    ::test_protocolpayloads::MainProtocol::TwoWayLocalWithError>::
    ReplyError(uint32_t error) {
  return Reply(
      ::test_protocolpayloads::wire::MainProtocolTwoWayLocalWithErrorResult::
          WithErr(std::move(error)));
}
#endif  // __Fuchsia__

#ifdef __Fuchsia__
void fidl::internal::WireCompleterImpl<
    ::test_protocolpayloads::MainProtocol::TwoWayImport>::Reply(int32_t a) {
  ::fidl::internal::TransactionalResponse<
      ::test_protocolpayloads::MainProtocol::TwoWayImport>
      _response{a};
  FIDL_INTERNAL_DISABLE_AUTO_VAR_INIT
  ::fidl::unstable::OwnedEncodedMessage<
      ::fidl::internal::TransactionalResponse<
          ::test_protocolpayloads::MainProtocol::TwoWayImport>,
      ::fidl::internal::ChannelTransport>
      _response_message{::fidl::internal::AllowUnownedInputRef{}, &_response};
  return _core()->SendReply(&_response_message.GetOutgoingMessage(),
                            ::fidl::internal::OutgoingTransportContext());
}

void fidl::internal::WireBufferCompleterImpl<
    ::test_protocolpayloads::MainProtocol::TwoWayImport>::Reply(int32_t a) {
  ::fidl::internal::TransactionalResponse<
      ::test_protocolpayloads::MainProtocol::TwoWayImport>
      _response{a};
  constexpr uint32_t _buffer_size = ::fidl::ServerReplyBufferSizeInChannel<
      ::test_protocolpayloads::MainProtocol::TwoWayImport>();
  ::fitx::result<::fidl::Error, ::fidl::BufferSpan> _allocation =
      _allocator().TryAllocate(_buffer_size);
  if (!_allocation.is_ok()) {
    ::fidl::OutgoingMessage _failure{_allocation.error_value()};
    return _core()->SendReply(&_failure,
                              ::fidl::internal::OutgoingTransportContext());
  }
  ::fidl::unstable::UnownedEncodedMessage<
      ::fidl::internal::TransactionalResponse<
          ::test_protocolpayloads::MainProtocol::TwoWayImport>,
      ::fidl::internal::ChannelTransport>
      _response_message(_allocation->data, _buffer_size, &_response);
  return _core()->SendReply(&_response_message.GetOutgoingMessage(),
                            ::fidl::internal::OutgoingTransportContext());
}
#endif  // __Fuchsia__

#ifdef __Fuchsia__
void fidl::internal::WireCompleterImpl<
    ::test_protocolpayloads::MainProtocol::TwoWayImportWithError>::
    Reply(::test_protocolpayloads::wire::MainProtocolTwoWayImportWithErrorResult
              result) {
  ::fidl::internal::TransactionalResponse<
      ::test_protocolpayloads::MainProtocol::TwoWayImportWithError>
      _response{result};
  FIDL_INTERNAL_DISABLE_AUTO_VAR_INIT
  ::fidl::unstable::OwnedEncodedMessage<
      ::fidl::internal::TransactionalResponse<
          ::test_protocolpayloads::MainProtocol::TwoWayImportWithError>,
      ::fidl::internal::ChannelTransport>
      _response_message{::fidl::internal::AllowUnownedInputRef{}, &_response};
  return _core()->SendReply(&_response_message.GetOutgoingMessage(),
                            ::fidl::internal::OutgoingTransportContext());
}
void fidl::internal::WireCompleterImpl<
    ::test_protocolpayloads::MainProtocol::TwoWayImportWithError>::
    ReplySuccess(int32_t a) {
  ::test_protocolpayloads_imported::wire::ImportStructPayload _response =
      ::test_protocolpayloads_imported::wire::ImportStructPayload{
          .a = std::move(a),
      };

  return Reply(
      ::test_protocolpayloads::wire::MainProtocolTwoWayImportWithErrorResult::
          WithResponse(std::move(_response)));
}

void fidl::internal::WireCompleterImpl<
    ::test_protocolpayloads::MainProtocol::TwoWayImportWithError>::
    ReplyError(uint32_t error) {
  return Reply(
      ::test_protocolpayloads::wire::MainProtocolTwoWayImportWithErrorResult::
          WithErr(std::move(error)));
}

void fidl::internal::WireBufferCompleterImpl<
    ::test_protocolpayloads::MainProtocol::TwoWayImportWithError>::
    Reply(::test_protocolpayloads::wire::MainProtocolTwoWayImportWithErrorResult
              result) {
  ::fidl::internal::TransactionalResponse<
      ::test_protocolpayloads::MainProtocol::TwoWayImportWithError>
      _response{result};
  constexpr uint32_t _buffer_size = ::fidl::ServerReplyBufferSizeInChannel<
      ::test_protocolpayloads::MainProtocol::TwoWayImportWithError>();
  ::fitx::result<::fidl::Error, ::fidl::BufferSpan> _allocation =
      _allocator().TryAllocate(_buffer_size);
  if (!_allocation.is_ok()) {
    ::fidl::OutgoingMessage _failure{_allocation.error_value()};
    return _core()->SendReply(&_failure,
                              ::fidl::internal::OutgoingTransportContext());
  }
  ::fidl::unstable::UnownedEncodedMessage<
      ::fidl::internal::TransactionalResponse<
          ::test_protocolpayloads::MainProtocol::TwoWayImportWithError>,
      ::fidl::internal::ChannelTransport>
      _response_message(_allocation->data, _buffer_size, &_response);
  return _core()->SendReply(&_response_message.GetOutgoingMessage(),
                            ::fidl::internal::OutgoingTransportContext());
}
void fidl::internal::WireBufferCompleterImpl<
    ::test_protocolpayloads::MainProtocol::TwoWayImportWithError>::
    ReplySuccess(int32_t a) {
  ::test_protocolpayloads_imported::wire::ImportStructPayload _response =
      ::test_protocolpayloads_imported::wire::ImportStructPayload{
          .a = std::move(a),
      };

  return Reply(
      ::test_protocolpayloads::wire::MainProtocolTwoWayImportWithErrorResult::
          WithResponse(std::move(_response)));
}

void fidl::internal::WireBufferCompleterImpl<
    ::test_protocolpayloads::MainProtocol::TwoWayImportWithError>::
    ReplyError(uint32_t error) {
  return Reply(
      ::test_protocolpayloads::wire::MainProtocolTwoWayImportWithErrorResult::
          WithErr(std::move(error)));
}
#endif  // __Fuchsia__

#ifdef __Fuchsia__
void fidl::internal::WireCompleterImpl<
    ::test_protocolpayloads::MainProtocol::TwoWayAnon>::Reply(uint32_t a,
                                                              uint32_t b) {
  ::fidl::internal::TransactionalResponse<
      ::test_protocolpayloads::MainProtocol::TwoWayAnon>
      _response{a, b};
  FIDL_INTERNAL_DISABLE_AUTO_VAR_INIT
  ::fidl::unstable::OwnedEncodedMessage<
      ::fidl::internal::TransactionalResponse<
          ::test_protocolpayloads::MainProtocol::TwoWayAnon>,
      ::fidl::internal::ChannelTransport>
      _response_message{::fidl::internal::AllowUnownedInputRef{}, &_response};
  return _core()->SendReply(&_response_message.GetOutgoingMessage(),
                            ::fidl::internal::OutgoingTransportContext());
}

void fidl::internal::WireBufferCompleterImpl<
    ::test_protocolpayloads::MainProtocol::TwoWayAnon>::Reply(uint32_t a,
                                                              uint32_t b) {
  ::fidl::internal::TransactionalResponse<
      ::test_protocolpayloads::MainProtocol::TwoWayAnon>
      _response{a, b};
  constexpr uint32_t _buffer_size = ::fidl::ServerReplyBufferSizeInChannel<
      ::test_protocolpayloads::MainProtocol::TwoWayAnon>();
  ::fitx::result<::fidl::Error, ::fidl::BufferSpan> _allocation =
      _allocator().TryAllocate(_buffer_size);
  if (!_allocation.is_ok()) {
    ::fidl::OutgoingMessage _failure{_allocation.error_value()};
    return _core()->SendReply(&_failure,
                              ::fidl::internal::OutgoingTransportContext());
  }
  ::fidl::unstable::UnownedEncodedMessage<
      ::fidl::internal::TransactionalResponse<
          ::test_protocolpayloads::MainProtocol::TwoWayAnon>,
      ::fidl::internal::ChannelTransport>
      _response_message(_allocation->data, _buffer_size, &_response);
  return _core()->SendReply(&_response_message.GetOutgoingMessage(),
                            ::fidl::internal::OutgoingTransportContext());
}
#endif  // __Fuchsia__

#ifdef __Fuchsia__
void fidl::internal::WireCompleterImpl<
    ::test_protocolpayloads::MainProtocol::TwoWayAnonWithError>::
    Reply(::test_protocolpayloads::wire::MainProtocolTwoWayAnonWithErrorResult
              result) {
  ::fidl::internal::TransactionalResponse<
      ::test_protocolpayloads::MainProtocol::TwoWayAnonWithError>
      _response{result};
  FIDL_INTERNAL_DISABLE_AUTO_VAR_INIT
  ::fidl::unstable::OwnedEncodedMessage<
      ::fidl::internal::TransactionalResponse<
          ::test_protocolpayloads::MainProtocol::TwoWayAnonWithError>,
      ::fidl::internal::ChannelTransport>
      _response_message{::fidl::internal::AllowUnownedInputRef{}, &_response};
  return _core()->SendReply(&_response_message.GetOutgoingMessage(),
                            ::fidl::internal::OutgoingTransportContext());
}
void fidl::internal::WireCompleterImpl<
    ::test_protocolpayloads::MainProtocol::TwoWayAnonWithError>::
    ReplySuccess(uint32_t a, uint32_t b) {
  ::test_protocolpayloads::wire::MainProtocolTwoWayAnonWithErrorResponse
      _response = ::test_protocolpayloads::wire::
          MainProtocolTwoWayAnonWithErrorResponse{
              .a = std::move(a),
              .b = std::move(b),
          };

  return Reply(
      ::test_protocolpayloads::wire::MainProtocolTwoWayAnonWithErrorResult::
          WithResponse(
              ::fidl::ObjectView<::test_protocolpayloads::wire::
                                     MainProtocolTwoWayAnonWithErrorResponse>::
                  FromExternal(&_response)));
}

void fidl::internal::WireCompleterImpl<
    ::test_protocolpayloads::MainProtocol::TwoWayAnonWithError>::
    ReplyError(uint32_t error) {
  return Reply(
      ::test_protocolpayloads::wire::MainProtocolTwoWayAnonWithErrorResult::
          WithErr(std::move(error)));
}

void fidl::internal::WireBufferCompleterImpl<
    ::test_protocolpayloads::MainProtocol::TwoWayAnonWithError>::
    Reply(::test_protocolpayloads::wire::MainProtocolTwoWayAnonWithErrorResult
              result) {
  ::fidl::internal::TransactionalResponse<
      ::test_protocolpayloads::MainProtocol::TwoWayAnonWithError>
      _response{result};
  constexpr uint32_t _buffer_size = ::fidl::ServerReplyBufferSizeInChannel<
      ::test_protocolpayloads::MainProtocol::TwoWayAnonWithError>();
  ::fitx::result<::fidl::Error, ::fidl::BufferSpan> _allocation =
      _allocator().TryAllocate(_buffer_size);
  if (!_allocation.is_ok()) {
    ::fidl::OutgoingMessage _failure{_allocation.error_value()};
    return _core()->SendReply(&_failure,
                              ::fidl::internal::OutgoingTransportContext());
  }
  ::fidl::unstable::UnownedEncodedMessage<
      ::fidl::internal::TransactionalResponse<
          ::test_protocolpayloads::MainProtocol::TwoWayAnonWithError>,
      ::fidl::internal::ChannelTransport>
      _response_message(_allocation->data, _buffer_size, &_response);
  return _core()->SendReply(&_response_message.GetOutgoingMessage(),
                            ::fidl::internal::OutgoingTransportContext());
}
void fidl::internal::WireBufferCompleterImpl<
    ::test_protocolpayloads::MainProtocol::TwoWayAnonWithError>::
    ReplySuccess(uint32_t a, uint32_t b) {
  ::test_protocolpayloads::wire::MainProtocolTwoWayAnonWithErrorResponse
      _response = ::test_protocolpayloads::wire::
          MainProtocolTwoWayAnonWithErrorResponse{
              .a = std::move(a),
              .b = std::move(b),
          };

  return Reply(
      ::test_protocolpayloads::wire::MainProtocolTwoWayAnonWithErrorResult::
          WithResponse(
              ::fidl::ObjectView<::test_protocolpayloads::wire::
                                     MainProtocolTwoWayAnonWithErrorResponse>::
                  FromExternal(&_response)));
}

void fidl::internal::WireBufferCompleterImpl<
    ::test_protocolpayloads::MainProtocol::TwoWayAnonWithError>::
    ReplyError(uint32_t error) {
  return Reply(
      ::test_protocolpayloads::wire::MainProtocolTwoWayAnonWithErrorResult::
          WithErr(std::move(error)));
}
#endif  // __Fuchsia__

void ::fidl::internal::TransactionalRequest<
    ::test_protocolpayloads::MainProtocol::OneWayComposed>::_InitHeader() {
  ::fidl::InitTxnHeader(
      &header, 0, ::test_protocolpayloads::kMainProtocol_OneWayComposed_Ordinal,
      ::test_protocolpayloads::kMainProtocol_OneWayComposed_DynamicFlags);
}

void ::fidl::internal::TransactionalRequest<
    ::test_protocolpayloads::MainProtocol::TwoWayComposed>::_InitHeader() {
  ::fidl::InitTxnHeader(
      &header, 0, ::test_protocolpayloads::kMainProtocol_TwoWayComposed_Ordinal,
      ::test_protocolpayloads::kMainProtocol_TwoWayComposed_DynamicFlags);
}

void ::fidl::internal::TransactionalResponse<
    ::test_protocolpayloads::MainProtocol::TwoWayComposed>::_InitHeader() {
  ::fidl::InitTxnHeader(
      &header, 0, ::test_protocolpayloads::kMainProtocol_TwoWayComposed_Ordinal,
      ::test_protocolpayloads::kMainProtocol_TwoWayComposed_DynamicFlags);
}

void ::fidl::internal::TransactionalRequest<
    ::test_protocolpayloads::MainProtocol::TwoWayComposedWithError>::
    _InitHeader() {
  ::fidl::InitTxnHeader(
      &header, 0,
      ::test_protocolpayloads::kMainProtocol_TwoWayComposedWithError_Ordinal,
      ::test_protocolpayloads::
          kMainProtocol_TwoWayComposedWithError_DynamicFlags);
}

void ::fidl::internal::TransactionalResponse<
    ::test_protocolpayloads::MainProtocol::TwoWayComposedWithError>::
    _InitHeader() {
  ::fidl::InitTxnHeader(
      &header, 0,
      ::test_protocolpayloads::kMainProtocol_TwoWayComposedWithError_Ordinal,
      ::test_protocolpayloads::
          kMainProtocol_TwoWayComposedWithError_DynamicFlags);
}

void ::fidl::internal::TransactionalEvent<
    ::test_protocolpayloads::MainProtocol::OnComposed>::_InitHeader() {
  ::fidl::InitTxnHeader(
      &header, 0, ::test_protocolpayloads::kMainProtocol_OnComposed_Ordinal,
      ::test_protocolpayloads::kMainProtocol_OnComposed_DynamicFlags);
}

void ::fidl::internal::TransactionalEvent<
    ::test_protocolpayloads::MainProtocol::OnComposedWithError>::_InitHeader() {
  ::fidl::InitTxnHeader(
      &header, 0,
      ::test_protocolpayloads::kMainProtocol_OnComposedWithError_Ordinal,
      ::test_protocolpayloads::kMainProtocol_OnComposedWithError_DynamicFlags);
}

void ::fidl::internal::TransactionalRequest<
    ::test_protocolpayloads::MainProtocol::OneWayLocal>::_InitHeader() {
  ::fidl::InitTxnHeader(
      &header, 0, ::test_protocolpayloads::kMainProtocol_OneWayLocal_Ordinal,
      ::test_protocolpayloads::kMainProtocol_OneWayLocal_DynamicFlags);
}

void ::fidl::internal::TransactionalRequest<
    ::test_protocolpayloads::MainProtocol::TwoWayLocal>::_InitHeader() {
  ::fidl::InitTxnHeader(
      &header, 0, ::test_protocolpayloads::kMainProtocol_TwoWayLocal_Ordinal,
      ::test_protocolpayloads::kMainProtocol_TwoWayLocal_DynamicFlags);
}

void ::fidl::internal::TransactionalResponse<
    ::test_protocolpayloads::MainProtocol::TwoWayLocal>::_InitHeader() {
  ::fidl::InitTxnHeader(
      &header, 0, ::test_protocolpayloads::kMainProtocol_TwoWayLocal_Ordinal,
      ::test_protocolpayloads::kMainProtocol_TwoWayLocal_DynamicFlags);
}

void ::fidl::internal::TransactionalRequest<
    ::test_protocolpayloads::MainProtocol::TwoWayLocalWithError>::
    _InitHeader() {
  ::fidl::InitTxnHeader(
      &header, 0,
      ::test_protocolpayloads::kMainProtocol_TwoWayLocalWithError_Ordinal,
      ::test_protocolpayloads::kMainProtocol_TwoWayLocalWithError_DynamicFlags);
}

void ::fidl::internal::TransactionalResponse<
    ::test_protocolpayloads::MainProtocol::TwoWayLocalWithError>::
    _InitHeader() {
  ::fidl::InitTxnHeader(
      &header, 0,
      ::test_protocolpayloads::kMainProtocol_TwoWayLocalWithError_Ordinal,
      ::test_protocolpayloads::kMainProtocol_TwoWayLocalWithError_DynamicFlags);
}

void ::fidl::internal::TransactionalEvent<
    ::test_protocolpayloads::MainProtocol::OnLocal>::_InitHeader() {
  ::fidl::InitTxnHeader(
      &header, 0, ::test_protocolpayloads::kMainProtocol_OnLocal_Ordinal,
      ::test_protocolpayloads::kMainProtocol_OnLocal_DynamicFlags);
}

void ::fidl::internal::TransactionalEvent<
    ::test_protocolpayloads::MainProtocol::OnLocalWithError>::_InitHeader() {
  ::fidl::InitTxnHeader(
      &header, 0,
      ::test_protocolpayloads::kMainProtocol_OnLocalWithError_Ordinal,
      ::test_protocolpayloads::kMainProtocol_OnLocalWithError_DynamicFlags);
}

void ::fidl::internal::TransactionalRequest<
    ::test_protocolpayloads::MainProtocol::OneWayImport>::_InitHeader() {
  ::fidl::InitTxnHeader(
      &header, 0, ::test_protocolpayloads::kMainProtocol_OneWayImport_Ordinal,
      ::test_protocolpayloads::kMainProtocol_OneWayImport_DynamicFlags);
}

void ::fidl::internal::TransactionalRequest<
    ::test_protocolpayloads::MainProtocol::TwoWayImport>::_InitHeader() {
  ::fidl::InitTxnHeader(
      &header, 0, ::test_protocolpayloads::kMainProtocol_TwoWayImport_Ordinal,
      ::test_protocolpayloads::kMainProtocol_TwoWayImport_DynamicFlags);
}

void ::fidl::internal::TransactionalResponse<
    ::test_protocolpayloads::MainProtocol::TwoWayImport>::_InitHeader() {
  ::fidl::InitTxnHeader(
      &header, 0, ::test_protocolpayloads::kMainProtocol_TwoWayImport_Ordinal,
      ::test_protocolpayloads::kMainProtocol_TwoWayImport_DynamicFlags);
}

void ::fidl::internal::TransactionalRequest<
    ::test_protocolpayloads::MainProtocol::TwoWayImportWithError>::
    _InitHeader() {
  ::fidl::InitTxnHeader(
      &header, 0,
      ::test_protocolpayloads::kMainProtocol_TwoWayImportWithError_Ordinal,
      ::test_protocolpayloads::
          kMainProtocol_TwoWayImportWithError_DynamicFlags);
}

void ::fidl::internal::TransactionalResponse<
    ::test_protocolpayloads::MainProtocol::TwoWayImportWithError>::
    _InitHeader() {
  ::fidl::InitTxnHeader(
      &header, 0,
      ::test_protocolpayloads::kMainProtocol_TwoWayImportWithError_Ordinal,
      ::test_protocolpayloads::
          kMainProtocol_TwoWayImportWithError_DynamicFlags);
}

void ::fidl::internal::TransactionalEvent<
    ::test_protocolpayloads::MainProtocol::OnImport>::_InitHeader() {
  ::fidl::InitTxnHeader(
      &header, 0, ::test_protocolpayloads::kMainProtocol_OnImport_Ordinal,
      ::test_protocolpayloads::kMainProtocol_OnImport_DynamicFlags);
}

void ::fidl::internal::TransactionalEvent<
    ::test_protocolpayloads::MainProtocol::OnImportWithError>::_InitHeader() {
  ::fidl::InitTxnHeader(
      &header, 0,
      ::test_protocolpayloads::kMainProtocol_OnImportWithError_Ordinal,
      ::test_protocolpayloads::kMainProtocol_OnImportWithError_DynamicFlags);
}

void ::fidl::internal::TransactionalRequest<
    ::test_protocolpayloads::MainProtocol::OneWayAnon>::_InitHeader() {
  ::fidl::InitTxnHeader(
      &header, 0, ::test_protocolpayloads::kMainProtocol_OneWayAnon_Ordinal,
      ::test_protocolpayloads::kMainProtocol_OneWayAnon_DynamicFlags);
}

void ::fidl::internal::TransactionalRequest<
    ::test_protocolpayloads::MainProtocol::TwoWayAnon>::_InitHeader() {
  ::fidl::InitTxnHeader(
      &header, 0, ::test_protocolpayloads::kMainProtocol_TwoWayAnon_Ordinal,
      ::test_protocolpayloads::kMainProtocol_TwoWayAnon_DynamicFlags);
}

void ::fidl::internal::TransactionalResponse<
    ::test_protocolpayloads::MainProtocol::TwoWayAnon>::_InitHeader() {
  ::fidl::InitTxnHeader(
      &header, 0, ::test_protocolpayloads::kMainProtocol_TwoWayAnon_Ordinal,
      ::test_protocolpayloads::kMainProtocol_TwoWayAnon_DynamicFlags);
}

void ::fidl::internal::TransactionalRequest<
    ::test_protocolpayloads::MainProtocol::TwoWayAnonWithError>::_InitHeader() {
  ::fidl::InitTxnHeader(
      &header, 0,
      ::test_protocolpayloads::kMainProtocol_TwoWayAnonWithError_Ordinal,
      ::test_protocolpayloads::kMainProtocol_TwoWayAnonWithError_DynamicFlags);
}

void ::fidl::internal::TransactionalResponse<
    ::test_protocolpayloads::MainProtocol::TwoWayAnonWithError>::_InitHeader() {
  ::fidl::InitTxnHeader(
      &header, 0,
      ::test_protocolpayloads::kMainProtocol_TwoWayAnonWithError_Ordinal,
      ::test_protocolpayloads::kMainProtocol_TwoWayAnonWithError_DynamicFlags);
}

void ::fidl::internal::TransactionalEvent<
    ::test_protocolpayloads::MainProtocol::OnAnon>::_InitHeader() {
  ::fidl::InitTxnHeader(
      &header, 0, ::test_protocolpayloads::kMainProtocol_OnAnon_Ordinal,
      ::test_protocolpayloads::kMainProtocol_OnAnon_DynamicFlags);
}

void ::fidl::internal::TransactionalEvent<
    ::test_protocolpayloads::MainProtocol::OnAnonWithError>::_InitHeader() {
  ::fidl::InitTxnHeader(
      &header, 0,
      ::test_protocolpayloads::kMainProtocol_OnAnonWithError_Ordinal,
      ::test_protocolpayloads::kMainProtocol_OnAnonWithError_DynamicFlags);
}

#ifdef __Fuchsia__

fidl::Status fidl::internal::WireWeakEventSender<
    ::test_protocolpayloads::MainProtocol>::OnComposed(int32_t a) {
  ::fidl::internal::TransactionalEvent<
      ::test_protocolpayloads::MainProtocol::OnComposed>
      _response{a};
  FIDL_INTERNAL_DISABLE_AUTO_VAR_INIT
  ::fidl::unstable::OwnedEncodedMessage<
      ::fidl::internal::TransactionalEvent<
          ::test_protocolpayloads::MainProtocol::OnComposed>,
      ::fidl::internal::ChannelTransport>
      _response_message{::fidl::internal::AllowUnownedInputRef{}, &_response};
  return _inner().SendEvent(_response_message.GetOutgoingMessage());
}

fidl::Status fidl::internal::WireWeakBufferEventSender<
    ::test_protocolpayloads::MainProtocol>::OnComposed(int32_t a) {
  constexpr uint32_t _buffer_size = ::fidl::EventReplyBufferSizeInChannel<
      ::test_protocolpayloads::MainProtocol::OnComposed>();
  ::fitx::result<::fidl::Error, ::fidl::BufferSpan> _allocation =
      _allocator().TryAllocate(_buffer_size);
  if (!_allocation.is_ok()) {
    _inner().HandleSendError(_allocation.error_value());
    return _allocation.error_value();
  }

  ::fidl::internal::TransactionalEvent<
      ::test_protocolpayloads::MainProtocol::OnComposed>
      _response{a};
  ::fidl::unstable::UnownedEncodedMessage<
      ::fidl::internal::TransactionalEvent<
          ::test_protocolpayloads::MainProtocol::OnComposed>,
      ::fidl::internal::ChannelTransport>
      _response_message(_allocation->data, _buffer_size, &_response);
  return _inner().SendEvent(_response_message.GetOutgoingMessage());
}

fidl::Status fidl::internal::WireEventSender<
    ::test_protocolpayloads::MainProtocol>::OnComposed(int32_t a) {
  ::fidl::internal::TransactionalEvent<
      ::test_protocolpayloads::MainProtocol::OnComposed>
      _response{a};
  FIDL_INTERNAL_DISABLE_AUTO_VAR_INIT
  ::fidl::unstable::OwnedEncodedMessage<
      ::fidl::internal::TransactionalEvent<
          ::test_protocolpayloads::MainProtocol::OnComposed>,
      ::fidl::internal::ChannelTransport>
      _response_message{::fidl::internal::AllowUnownedInputRef{}, &_response};
  auto& _message = _response_message.GetOutgoingMessage();
  _message.Write(_transport());
  return ::fidl::Status{_message};
}

fidl::Status fidl::internal::WireBufferEventSender<
    ::test_protocolpayloads::MainProtocol>::OnComposed(int32_t a) {
  constexpr uint32_t _buffer_size = ::fidl::EventReplyBufferSizeInChannel<
      ::test_protocolpayloads::MainProtocol::OnComposed>();
  ::fitx::result<::fidl::Error, ::fidl::BufferSpan> _allocation =
      _allocator().TryAllocate(_buffer_size);
  if (!_allocation.is_ok()) {
    return _allocation.error_value();
  }

  ::fidl::internal::TransactionalEvent<
      ::test_protocolpayloads::MainProtocol::OnComposed>
      _response{a};
  ::fidl::unstable::UnownedEncodedMessage<
      ::fidl::internal::TransactionalEvent<
          ::test_protocolpayloads::MainProtocol::OnComposed>,
      ::fidl::internal::ChannelTransport>
      _response_message(_allocation->data, _buffer_size, &_response);
  auto& _message = _response_message.GetOutgoingMessage();
  _message.Write(_transport());
  return ::fidl::Status{_message};
}

fidl::Status
fidl::internal::WireWeakEventSender<::test_protocolpayloads::MainProtocol>::
    OnComposedWithError(::test_protocolpayloads_imported::wire::
                            ComposedProtocolOnComposedWithErrorResult result) {
  ::fidl::internal::TransactionalEvent<
      ::test_protocolpayloads::MainProtocol::OnComposedWithError>
      _response{result};
  FIDL_INTERNAL_DISABLE_AUTO_VAR_INIT
  ::fidl::unstable::OwnedEncodedMessage<
      ::fidl::internal::TransactionalEvent<
          ::test_protocolpayloads::MainProtocol::OnComposedWithError>,
      ::fidl::internal::ChannelTransport>
      _response_message{::fidl::internal::AllowUnownedInputRef{}, &_response};
  return _inner().SendEvent(_response_message.GetOutgoingMessage());
}

fidl::Status fidl::internal::WireWeakBufferEventSender<
    ::test_protocolpayloads::MainProtocol>::
    OnComposedWithError(::test_protocolpayloads_imported::wire::
                            ComposedProtocolOnComposedWithErrorResult result) {
  constexpr uint32_t _buffer_size = ::fidl::EventReplyBufferSizeInChannel<
      ::test_protocolpayloads::MainProtocol::OnComposedWithError>();
  ::fitx::result<::fidl::Error, ::fidl::BufferSpan> _allocation =
      _allocator().TryAllocate(_buffer_size);
  if (!_allocation.is_ok()) {
    _inner().HandleSendError(_allocation.error_value());
    return _allocation.error_value();
  }

  ::fidl::internal::TransactionalEvent<
      ::test_protocolpayloads::MainProtocol::OnComposedWithError>
      _response{result};
  ::fidl::unstable::UnownedEncodedMessage<
      ::fidl::internal::TransactionalEvent<
          ::test_protocolpayloads::MainProtocol::OnComposedWithError>,
      ::fidl::internal::ChannelTransport>
      _response_message(_allocation->data, _buffer_size, &_response);
  return _inner().SendEvent(_response_message.GetOutgoingMessage());
}

fidl::Status fidl::internal::
    WireEventSender<::test_protocolpayloads::MainProtocol>::OnComposedWithError(
        ::test_protocolpayloads_imported::wire::
            ComposedProtocolOnComposedWithErrorResult result) {
  ::fidl::internal::TransactionalEvent<
      ::test_protocolpayloads::MainProtocol::OnComposedWithError>
      _response{result};
  FIDL_INTERNAL_DISABLE_AUTO_VAR_INIT
  ::fidl::unstable::OwnedEncodedMessage<
      ::fidl::internal::TransactionalEvent<
          ::test_protocolpayloads::MainProtocol::OnComposedWithError>,
      ::fidl::internal::ChannelTransport>
      _response_message{::fidl::internal::AllowUnownedInputRef{}, &_response};
  auto& _message = _response_message.GetOutgoingMessage();
  _message.Write(_transport());
  return ::fidl::Status{_message};
}

fidl::Status
fidl::internal::WireBufferEventSender<::test_protocolpayloads::MainProtocol>::
    OnComposedWithError(::test_protocolpayloads_imported::wire::
                            ComposedProtocolOnComposedWithErrorResult result) {
  constexpr uint32_t _buffer_size = ::fidl::EventReplyBufferSizeInChannel<
      ::test_protocolpayloads::MainProtocol::OnComposedWithError>();
  ::fitx::result<::fidl::Error, ::fidl::BufferSpan> _allocation =
      _allocator().TryAllocate(_buffer_size);
  if (!_allocation.is_ok()) {
    return _allocation.error_value();
  }

  ::fidl::internal::TransactionalEvent<
      ::test_protocolpayloads::MainProtocol::OnComposedWithError>
      _response{result};
  ::fidl::unstable::UnownedEncodedMessage<
      ::fidl::internal::TransactionalEvent<
          ::test_protocolpayloads::MainProtocol::OnComposedWithError>,
      ::fidl::internal::ChannelTransport>
      _response_message(_allocation->data, _buffer_size, &_response);
  auto& _message = _response_message.GetOutgoingMessage();
  _message.Write(_transport());
  return ::fidl::Status{_message};
}

fidl::Status fidl::internal::WireWeakEventSender<
    ::test_protocolpayloads::MainProtocol>::OnLocal(uint32_t a, uint32_t b) {
  ::fidl::internal::TransactionalEvent<
      ::test_protocolpayloads::MainProtocol::OnLocal>
      _response{a, b};
  FIDL_INTERNAL_DISABLE_AUTO_VAR_INIT
  ::fidl::unstable::OwnedEncodedMessage<
      ::fidl::internal::TransactionalEvent<
          ::test_protocolpayloads::MainProtocol::OnLocal>,
      ::fidl::internal::ChannelTransport>
      _response_message{::fidl::internal::AllowUnownedInputRef{}, &_response};
  return _inner().SendEvent(_response_message.GetOutgoingMessage());
}

fidl::Status fidl::internal::WireWeakBufferEventSender<
    ::test_protocolpayloads::MainProtocol>::OnLocal(uint32_t a, uint32_t b) {
  constexpr uint32_t _buffer_size = ::fidl::EventReplyBufferSizeInChannel<
      ::test_protocolpayloads::MainProtocol::OnLocal>();
  ::fitx::result<::fidl::Error, ::fidl::BufferSpan> _allocation =
      _allocator().TryAllocate(_buffer_size);
  if (!_allocation.is_ok()) {
    _inner().HandleSendError(_allocation.error_value());
    return _allocation.error_value();
  }

  ::fidl::internal::TransactionalEvent<
      ::test_protocolpayloads::MainProtocol::OnLocal>
      _response{a, b};
  ::fidl::unstable::UnownedEncodedMessage<
      ::fidl::internal::TransactionalEvent<
          ::test_protocolpayloads::MainProtocol::OnLocal>,
      ::fidl::internal::ChannelTransport>
      _response_message(_allocation->data, _buffer_size, &_response);
  return _inner().SendEvent(_response_message.GetOutgoingMessage());
}

fidl::Status fidl::internal::WireEventSender<
    ::test_protocolpayloads::MainProtocol>::OnLocal(uint32_t a, uint32_t b) {
  ::fidl::internal::TransactionalEvent<
      ::test_protocolpayloads::MainProtocol::OnLocal>
      _response{a, b};
  FIDL_INTERNAL_DISABLE_AUTO_VAR_INIT
  ::fidl::unstable::OwnedEncodedMessage<
      ::fidl::internal::TransactionalEvent<
          ::test_protocolpayloads::MainProtocol::OnLocal>,
      ::fidl::internal::ChannelTransport>
      _response_message{::fidl::internal::AllowUnownedInputRef{}, &_response};
  auto& _message = _response_message.GetOutgoingMessage();
  _message.Write(_transport());
  return ::fidl::Status{_message};
}

fidl::Status fidl::internal::WireBufferEventSender<
    ::test_protocolpayloads::MainProtocol>::OnLocal(uint32_t a, uint32_t b) {
  constexpr uint32_t _buffer_size = ::fidl::EventReplyBufferSizeInChannel<
      ::test_protocolpayloads::MainProtocol::OnLocal>();
  ::fitx::result<::fidl::Error, ::fidl::BufferSpan> _allocation =
      _allocator().TryAllocate(_buffer_size);
  if (!_allocation.is_ok()) {
    return _allocation.error_value();
  }

  ::fidl::internal::TransactionalEvent<
      ::test_protocolpayloads::MainProtocol::OnLocal>
      _response{a, b};
  ::fidl::unstable::UnownedEncodedMessage<
      ::fidl::internal::TransactionalEvent<
          ::test_protocolpayloads::MainProtocol::OnLocal>,
      ::fidl::internal::ChannelTransport>
      _response_message(_allocation->data, _buffer_size, &_response);
  auto& _message = _response_message.GetOutgoingMessage();
  _message.Write(_transport());
  return ::fidl::Status{_message};
}

fidl::Status
fidl::internal::WireWeakEventSender<::test_protocolpayloads::MainProtocol>::
    OnLocalWithError(
        ::test_protocolpayloads::wire::MainProtocolOnLocalWithErrorResult
            result) {
  ::fidl::internal::TransactionalEvent<
      ::test_protocolpayloads::MainProtocol::OnLocalWithError>
      _response{result};
  FIDL_INTERNAL_DISABLE_AUTO_VAR_INIT
  ::fidl::unstable::OwnedEncodedMessage<
      ::fidl::internal::TransactionalEvent<
          ::test_protocolpayloads::MainProtocol::OnLocalWithError>,
      ::fidl::internal::ChannelTransport>
      _response_message{::fidl::internal::AllowUnownedInputRef{}, &_response};
  return _inner().SendEvent(_response_message.GetOutgoingMessage());
}

fidl::Status fidl::internal::WireWeakBufferEventSender<
    ::test_protocolpayloads::MainProtocol>::
    OnLocalWithError(
        ::test_protocolpayloads::wire::MainProtocolOnLocalWithErrorResult
            result) {
  constexpr uint32_t _buffer_size = ::fidl::EventReplyBufferSizeInChannel<
      ::test_protocolpayloads::MainProtocol::OnLocalWithError>();
  ::fitx::result<::fidl::Error, ::fidl::BufferSpan> _allocation =
      _allocator().TryAllocate(_buffer_size);
  if (!_allocation.is_ok()) {
    _inner().HandleSendError(_allocation.error_value());
    return _allocation.error_value();
  }

  ::fidl::internal::TransactionalEvent<
      ::test_protocolpayloads::MainProtocol::OnLocalWithError>
      _response{result};
  ::fidl::unstable::UnownedEncodedMessage<
      ::fidl::internal::TransactionalEvent<
          ::test_protocolpayloads::MainProtocol::OnLocalWithError>,
      ::fidl::internal::ChannelTransport>
      _response_message(_allocation->data, _buffer_size, &_response);
  return _inner().SendEvent(_response_message.GetOutgoingMessage());
}

fidl::Status fidl::internal::
    WireEventSender<::test_protocolpayloads::MainProtocol>::OnLocalWithError(
        ::test_protocolpayloads::wire::MainProtocolOnLocalWithErrorResult
            result) {
  ::fidl::internal::TransactionalEvent<
      ::test_protocolpayloads::MainProtocol::OnLocalWithError>
      _response{result};
  FIDL_INTERNAL_DISABLE_AUTO_VAR_INIT
  ::fidl::unstable::OwnedEncodedMessage<
      ::fidl::internal::TransactionalEvent<
          ::test_protocolpayloads::MainProtocol::OnLocalWithError>,
      ::fidl::internal::ChannelTransport>
      _response_message{::fidl::internal::AllowUnownedInputRef{}, &_response};
  auto& _message = _response_message.GetOutgoingMessage();
  _message.Write(_transport());
  return ::fidl::Status{_message};
}

fidl::Status
fidl::internal::WireBufferEventSender<::test_protocolpayloads::MainProtocol>::
    OnLocalWithError(
        ::test_protocolpayloads::wire::MainProtocolOnLocalWithErrorResult
            result) {
  constexpr uint32_t _buffer_size = ::fidl::EventReplyBufferSizeInChannel<
      ::test_protocolpayloads::MainProtocol::OnLocalWithError>();
  ::fitx::result<::fidl::Error, ::fidl::BufferSpan> _allocation =
      _allocator().TryAllocate(_buffer_size);
  if (!_allocation.is_ok()) {
    return _allocation.error_value();
  }

  ::fidl::internal::TransactionalEvent<
      ::test_protocolpayloads::MainProtocol::OnLocalWithError>
      _response{result};
  ::fidl::unstable::UnownedEncodedMessage<
      ::fidl::internal::TransactionalEvent<
          ::test_protocolpayloads::MainProtocol::OnLocalWithError>,
      ::fidl::internal::ChannelTransport>
      _response_message(_allocation->data, _buffer_size, &_response);
  auto& _message = _response_message.GetOutgoingMessage();
  _message.Write(_transport());
  return ::fidl::Status{_message};
}

fidl::Status fidl::internal::WireWeakEventSender<
    ::test_protocolpayloads::MainProtocol>::OnImport(int32_t a) {
  ::fidl::internal::TransactionalEvent<
      ::test_protocolpayloads::MainProtocol::OnImport>
      _response{a};
  FIDL_INTERNAL_DISABLE_AUTO_VAR_INIT
  ::fidl::unstable::OwnedEncodedMessage<
      ::fidl::internal::TransactionalEvent<
          ::test_protocolpayloads::MainProtocol::OnImport>,
      ::fidl::internal::ChannelTransport>
      _response_message{::fidl::internal::AllowUnownedInputRef{}, &_response};
  return _inner().SendEvent(_response_message.GetOutgoingMessage());
}

fidl::Status fidl::internal::WireWeakBufferEventSender<
    ::test_protocolpayloads::MainProtocol>::OnImport(int32_t a) {
  constexpr uint32_t _buffer_size = ::fidl::EventReplyBufferSizeInChannel<
      ::test_protocolpayloads::MainProtocol::OnImport>();
  ::fitx::result<::fidl::Error, ::fidl::BufferSpan> _allocation =
      _allocator().TryAllocate(_buffer_size);
  if (!_allocation.is_ok()) {
    _inner().HandleSendError(_allocation.error_value());
    return _allocation.error_value();
  }

  ::fidl::internal::TransactionalEvent<
      ::test_protocolpayloads::MainProtocol::OnImport>
      _response{a};
  ::fidl::unstable::UnownedEncodedMessage<
      ::fidl::internal::TransactionalEvent<
          ::test_protocolpayloads::MainProtocol::OnImport>,
      ::fidl::internal::ChannelTransport>
      _response_message(_allocation->data, _buffer_size, &_response);
  return _inner().SendEvent(_response_message.GetOutgoingMessage());
}

fidl::Status fidl::internal::WireEventSender<
    ::test_protocolpayloads::MainProtocol>::OnImport(int32_t a) {
  ::fidl::internal::TransactionalEvent<
      ::test_protocolpayloads::MainProtocol::OnImport>
      _response{a};
  FIDL_INTERNAL_DISABLE_AUTO_VAR_INIT
  ::fidl::unstable::OwnedEncodedMessage<
      ::fidl::internal::TransactionalEvent<
          ::test_protocolpayloads::MainProtocol::OnImport>,
      ::fidl::internal::ChannelTransport>
      _response_message{::fidl::internal::AllowUnownedInputRef{}, &_response};
  auto& _message = _response_message.GetOutgoingMessage();
  _message.Write(_transport());
  return ::fidl::Status{_message};
}

fidl::Status fidl::internal::WireBufferEventSender<
    ::test_protocolpayloads::MainProtocol>::OnImport(int32_t a) {
  constexpr uint32_t _buffer_size = ::fidl::EventReplyBufferSizeInChannel<
      ::test_protocolpayloads::MainProtocol::OnImport>();
  ::fitx::result<::fidl::Error, ::fidl::BufferSpan> _allocation =
      _allocator().TryAllocate(_buffer_size);
  if (!_allocation.is_ok()) {
    return _allocation.error_value();
  }

  ::fidl::internal::TransactionalEvent<
      ::test_protocolpayloads::MainProtocol::OnImport>
      _response{a};
  ::fidl::unstable::UnownedEncodedMessage<
      ::fidl::internal::TransactionalEvent<
          ::test_protocolpayloads::MainProtocol::OnImport>,
      ::fidl::internal::ChannelTransport>
      _response_message(_allocation->data, _buffer_size, &_response);
  auto& _message = _response_message.GetOutgoingMessage();
  _message.Write(_transport());
  return ::fidl::Status{_message};
}

fidl::Status
fidl::internal::WireWeakEventSender<::test_protocolpayloads::MainProtocol>::
    OnImportWithError(
        ::test_protocolpayloads::wire::MainProtocolOnImportWithErrorResult
            result) {
  ::fidl::internal::TransactionalEvent<
      ::test_protocolpayloads::MainProtocol::OnImportWithError>
      _response{result};
  FIDL_INTERNAL_DISABLE_AUTO_VAR_INIT
  ::fidl::unstable::OwnedEncodedMessage<
      ::fidl::internal::TransactionalEvent<
          ::test_protocolpayloads::MainProtocol::OnImportWithError>,
      ::fidl::internal::ChannelTransport>
      _response_message{::fidl::internal::AllowUnownedInputRef{}, &_response};
  return _inner().SendEvent(_response_message.GetOutgoingMessage());
}

fidl::Status fidl::internal::WireWeakBufferEventSender<
    ::test_protocolpayloads::MainProtocol>::
    OnImportWithError(
        ::test_protocolpayloads::wire::MainProtocolOnImportWithErrorResult
            result) {
  constexpr uint32_t _buffer_size = ::fidl::EventReplyBufferSizeInChannel<
      ::test_protocolpayloads::MainProtocol::OnImportWithError>();
  ::fitx::result<::fidl::Error, ::fidl::BufferSpan> _allocation =
      _allocator().TryAllocate(_buffer_size);
  if (!_allocation.is_ok()) {
    _inner().HandleSendError(_allocation.error_value());
    return _allocation.error_value();
  }

  ::fidl::internal::TransactionalEvent<
      ::test_protocolpayloads::MainProtocol::OnImportWithError>
      _response{result};
  ::fidl::unstable::UnownedEncodedMessage<
      ::fidl::internal::TransactionalEvent<
          ::test_protocolpayloads::MainProtocol::OnImportWithError>,
      ::fidl::internal::ChannelTransport>
      _response_message(_allocation->data, _buffer_size, &_response);
  return _inner().SendEvent(_response_message.GetOutgoingMessage());
}

fidl::Status fidl::internal::
    WireEventSender<::test_protocolpayloads::MainProtocol>::OnImportWithError(
        ::test_protocolpayloads::wire::MainProtocolOnImportWithErrorResult
            result) {
  ::fidl::internal::TransactionalEvent<
      ::test_protocolpayloads::MainProtocol::OnImportWithError>
      _response{result};
  FIDL_INTERNAL_DISABLE_AUTO_VAR_INIT
  ::fidl::unstable::OwnedEncodedMessage<
      ::fidl::internal::TransactionalEvent<
          ::test_protocolpayloads::MainProtocol::OnImportWithError>,
      ::fidl::internal::ChannelTransport>
      _response_message{::fidl::internal::AllowUnownedInputRef{}, &_response};
  auto& _message = _response_message.GetOutgoingMessage();
  _message.Write(_transport());
  return ::fidl::Status{_message};
}

fidl::Status
fidl::internal::WireBufferEventSender<::test_protocolpayloads::MainProtocol>::
    OnImportWithError(
        ::test_protocolpayloads::wire::MainProtocolOnImportWithErrorResult
            result) {
  constexpr uint32_t _buffer_size = ::fidl::EventReplyBufferSizeInChannel<
      ::test_protocolpayloads::MainProtocol::OnImportWithError>();
  ::fitx::result<::fidl::Error, ::fidl::BufferSpan> _allocation =
      _allocator().TryAllocate(_buffer_size);
  if (!_allocation.is_ok()) {
    return _allocation.error_value();
  }

  ::fidl::internal::TransactionalEvent<
      ::test_protocolpayloads::MainProtocol::OnImportWithError>
      _response{result};
  ::fidl::unstable::UnownedEncodedMessage<
      ::fidl::internal::TransactionalEvent<
          ::test_protocolpayloads::MainProtocol::OnImportWithError>,
      ::fidl::internal::ChannelTransport>
      _response_message(_allocation->data, _buffer_size, &_response);
  auto& _message = _response_message.GetOutgoingMessage();
  _message.Write(_transport());
  return ::fidl::Status{_message};
}

fidl::Status fidl::internal::WireWeakEventSender<
    ::test_protocolpayloads::MainProtocol>::OnAnon(uint32_t a, uint32_t b) {
  ::fidl::internal::TransactionalEvent<
      ::test_protocolpayloads::MainProtocol::OnAnon>
      _response{a, b};
  FIDL_INTERNAL_DISABLE_AUTO_VAR_INIT
  ::fidl::unstable::OwnedEncodedMessage<
      ::fidl::internal::TransactionalEvent<
          ::test_protocolpayloads::MainProtocol::OnAnon>,
      ::fidl::internal::ChannelTransport>
      _response_message{::fidl::internal::AllowUnownedInputRef{}, &_response};
  return _inner().SendEvent(_response_message.GetOutgoingMessage());
}

fidl::Status fidl::internal::WireWeakBufferEventSender<
    ::test_protocolpayloads::MainProtocol>::OnAnon(uint32_t a, uint32_t b) {
  constexpr uint32_t _buffer_size = ::fidl::EventReplyBufferSizeInChannel<
      ::test_protocolpayloads::MainProtocol::OnAnon>();
  ::fitx::result<::fidl::Error, ::fidl::BufferSpan> _allocation =
      _allocator().TryAllocate(_buffer_size);
  if (!_allocation.is_ok()) {
    _inner().HandleSendError(_allocation.error_value());
    return _allocation.error_value();
  }

  ::fidl::internal::TransactionalEvent<
      ::test_protocolpayloads::MainProtocol::OnAnon>
      _response{a, b};
  ::fidl::unstable::UnownedEncodedMessage<
      ::fidl::internal::TransactionalEvent<
          ::test_protocolpayloads::MainProtocol::OnAnon>,
      ::fidl::internal::ChannelTransport>
      _response_message(_allocation->data, _buffer_size, &_response);
  return _inner().SendEvent(_response_message.GetOutgoingMessage());
}

fidl::Status fidl::internal::WireEventSender<
    ::test_protocolpayloads::MainProtocol>::OnAnon(uint32_t a, uint32_t b) {
  ::fidl::internal::TransactionalEvent<
      ::test_protocolpayloads::MainProtocol::OnAnon>
      _response{a, b};
  FIDL_INTERNAL_DISABLE_AUTO_VAR_INIT
  ::fidl::unstable::OwnedEncodedMessage<
      ::fidl::internal::TransactionalEvent<
          ::test_protocolpayloads::MainProtocol::OnAnon>,
      ::fidl::internal::ChannelTransport>
      _response_message{::fidl::internal::AllowUnownedInputRef{}, &_response};
  auto& _message = _response_message.GetOutgoingMessage();
  _message.Write(_transport());
  return ::fidl::Status{_message};
}

fidl::Status fidl::internal::WireBufferEventSender<
    ::test_protocolpayloads::MainProtocol>::OnAnon(uint32_t a, uint32_t b) {
  constexpr uint32_t _buffer_size = ::fidl::EventReplyBufferSizeInChannel<
      ::test_protocolpayloads::MainProtocol::OnAnon>();
  ::fitx::result<::fidl::Error, ::fidl::BufferSpan> _allocation =
      _allocator().TryAllocate(_buffer_size);
  if (!_allocation.is_ok()) {
    return _allocation.error_value();
  }

  ::fidl::internal::TransactionalEvent<
      ::test_protocolpayloads::MainProtocol::OnAnon>
      _response{a, b};
  ::fidl::unstable::UnownedEncodedMessage<
      ::fidl::internal::TransactionalEvent<
          ::test_protocolpayloads::MainProtocol::OnAnon>,
      ::fidl::internal::ChannelTransport>
      _response_message(_allocation->data, _buffer_size, &_response);
  auto& _message = _response_message.GetOutgoingMessage();
  _message.Write(_transport());
  return ::fidl::Status{_message};
}

fidl::Status fidl::internal::
    WireWeakEventSender<::test_protocolpayloads::MainProtocol>::OnAnonWithError(
        ::test_protocolpayloads::wire::MainProtocolOnAnonWithErrorResult
            result) {
  ::fidl::internal::TransactionalEvent<
      ::test_protocolpayloads::MainProtocol::OnAnonWithError>
      _response{result};
  FIDL_INTERNAL_DISABLE_AUTO_VAR_INIT
  ::fidl::unstable::OwnedEncodedMessage<
      ::fidl::internal::TransactionalEvent<
          ::test_protocolpayloads::MainProtocol::OnAnonWithError>,
      ::fidl::internal::ChannelTransport>
      _response_message{::fidl::internal::AllowUnownedInputRef{}, &_response};
  return _inner().SendEvent(_response_message.GetOutgoingMessage());
}

fidl::Status fidl::internal::WireWeakBufferEventSender<
    ::test_protocolpayloads::MainProtocol>::
    OnAnonWithError(
        ::test_protocolpayloads::wire::MainProtocolOnAnonWithErrorResult
            result) {
  constexpr uint32_t _buffer_size = ::fidl::EventReplyBufferSizeInChannel<
      ::test_protocolpayloads::MainProtocol::OnAnonWithError>();
  ::fitx::result<::fidl::Error, ::fidl::BufferSpan> _allocation =
      _allocator().TryAllocate(_buffer_size);
  if (!_allocation.is_ok()) {
    _inner().HandleSendError(_allocation.error_value());
    return _allocation.error_value();
  }

  ::fidl::internal::TransactionalEvent<
      ::test_protocolpayloads::MainProtocol::OnAnonWithError>
      _response{result};
  ::fidl::unstable::UnownedEncodedMessage<
      ::fidl::internal::TransactionalEvent<
          ::test_protocolpayloads::MainProtocol::OnAnonWithError>,
      ::fidl::internal::ChannelTransport>
      _response_message(_allocation->data, _buffer_size, &_response);
  return _inner().SendEvent(_response_message.GetOutgoingMessage());
}

fidl::Status fidl::internal::
    WireEventSender<::test_protocolpayloads::MainProtocol>::OnAnonWithError(
        ::test_protocolpayloads::wire::MainProtocolOnAnonWithErrorResult
            result) {
  ::fidl::internal::TransactionalEvent<
      ::test_protocolpayloads::MainProtocol::OnAnonWithError>
      _response{result};
  FIDL_INTERNAL_DISABLE_AUTO_VAR_INIT
  ::fidl::unstable::OwnedEncodedMessage<
      ::fidl::internal::TransactionalEvent<
          ::test_protocolpayloads::MainProtocol::OnAnonWithError>,
      ::fidl::internal::ChannelTransport>
      _response_message{::fidl::internal::AllowUnownedInputRef{}, &_response};
  auto& _message = _response_message.GetOutgoingMessage();
  _message.Write(_transport());
  return ::fidl::Status{_message};
}

fidl::Status
fidl::internal::WireBufferEventSender<::test_protocolpayloads::MainProtocol>::
    OnAnonWithError(
        ::test_protocolpayloads::wire::MainProtocolOnAnonWithErrorResult
            result) {
  constexpr uint32_t _buffer_size = ::fidl::EventReplyBufferSizeInChannel<
      ::test_protocolpayloads::MainProtocol::OnAnonWithError>();
  ::fitx::result<::fidl::Error, ::fidl::BufferSpan> _allocation =
      _allocator().TryAllocate(_buffer_size);
  if (!_allocation.is_ok()) {
    return _allocation.error_value();
  }

  ::fidl::internal::TransactionalEvent<
      ::test_protocolpayloads::MainProtocol::OnAnonWithError>
      _response{result};
  ::fidl::unstable::UnownedEncodedMessage<
      ::fidl::internal::TransactionalEvent<
          ::test_protocolpayloads::MainProtocol::OnAnonWithError>,
      ::fidl::internal::ChannelTransport>
      _response_message(_allocation->data, _buffer_size, &_response);
  auto& _message = _response_message.GetOutgoingMessage();
  _message.Write(_transport());
  return ::fidl::Status{_message};
}

#endif  // __Fuchsia__
