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

// fidl_experiment = output_index_json

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

#include <memory>

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

namespace test_doccomments {

[[maybe_unused]]
constexpr uint64_t kInterface_Method_Ordinal = 5017051197196532121lu;

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

[[maybe_unused]]
constexpr uint64_t kInterface_OnEvent_Ordinal = 28780186509098736lu;

[[maybe_unused]]
constexpr ::fidl::MessageDynamicFlags kInterface_OnEvent_DynamicFlags = ::fidl::MessageDynamicFlags::kStrictMethod;
#ifdef __Fuchsia__
}  // namespace test_doccomments

::fidl::WireResult<::test_doccomments::Interface::Method>::WireResult(
    ::fidl::UnownedClientEnd<::test_doccomments::Interface> client,
    ::fidl::internal::TransactionalRequest<::test_doccomments::Interface::Method>* request) {
  FIDL_INTERNAL_DISABLE_AUTO_VAR_INIT
  ::fidl::internal::OwnedEncodedMessage<::fidl::internal::TransactionalRequest<::test_doccomments::Interface::Method>, ::fidl::internal::ChannelTransport> request_message(
      ::fidl::internal::AllowUnownedInputRef{}, request);
  auto& outgoing = request_message.GetOutgoingMessage();
  outgoing.Write(client.handle());
  SetStatus(outgoing);
}
namespace test_doccomments {

#endif  // __Fuchsia__

#ifdef __Fuchsia__
}  // namespace test_doccomments

::fidl::WireUnownedResult<::test_doccomments::Interface::Method>::WireUnownedResult(::fidl::UnownedClientEnd<::test_doccomments::Interface> client_end, ::fidl::internal::AnyBufferAllocator& allocator, ::fidl::internal::TransactionalRequest<::test_doccomments::Interface::Method>* request) {
  constexpr uint32_t buffer_size = ::fidl::SyncClientMethodBufferSizeInChannel<::test_doccomments::Interface::Method>();
  ::fit::result<::fidl::Error, ::fidl::BufferSpan> allocation = allocator.TryAllocate(buffer_size);
  if (!allocation.is_ok()) {
    SetStatus(allocation.error_value());
    return;
  }
  uint8_t* buffer = allocation->data;
  uint32_t request_byte_capacity = buffer_size;
  uint8_t* request_bytes = buffer;

  ::fidl::internal::UnownedEncodedMessage<::fidl::internal::TransactionalRequest<::test_doccomments::Interface::Method>> request_message(
      request_bytes, request_byte_capacity, request);
  auto& outgoing = request_message.GetOutgoingMessage();
  outgoing.Write(client_end.handle());
  SetStatus(outgoing);
}
namespace test_doccomments {

#endif  // __Fuchsia__

}  // namespace test_doccomments

#ifdef __Fuchsia__

::fidl::OneWayStatus fidl::internal::WireWeakOnewayClientImpl<::test_doccomments::Interface>::Method() {
  FIDL_INTERNAL_DISABLE_AUTO_VAR_INIT
  ::fidl::internal::TransactionalRequest<::test_doccomments::Interface::Method> _request_object{};
  ::fidl::internal::OwnedEncodedMessage<::fidl::internal::TransactionalRequest<::test_doccomments::Interface::Method>, ::fidl::internal::ChannelTransport> _request_message(
      ::fidl::internal::AllowUnownedInputRef{}, &_request_object);
  return _client_base()->SendOneWay(_request_message.GetOutgoingMessage());
}
::fidl::OneWayStatus fidl::internal::WireWeakOnewayBufferClientImpl<::test_doccomments::Interface>::Method() {
  constexpr uint32_t _buffer_size = ::fidl::AsyncClientMethodBufferSizeInChannel<::test_doccomments::Interface::Method>();
  ::fit::result<::fidl::Error, ::fidl::BufferSpan> _allocation =
      _allocator().TryAllocate(_buffer_size);
  if (!_allocation.is_ok()) {
    return ::fidl::OneWayStatus{_allocation.error_value()};
  }

  ::fidl::internal::TransactionalRequest<::test_doccomments::Interface::Method> _request{};
  ::fidl::internal::UnownedEncodedMessage<::fidl::internal::TransactionalRequest<::test_doccomments::Interface::Method>> _request_message(
      _allocation->data, _buffer_size, &_request);
  return _client_base()->SendOneWay(_request_message.GetOutgoingMessage());
}

#endif  // __Fuchsia__

#ifdef __Fuchsia__

::fidl::Status fidl::WireSyncEventHandler<::test_doccomments::Interface>::HandleOneEvent(
    ::fidl::UnownedClientEnd<::test_doccomments::Interface> client_end) {
  ::fidl::internal::IncomingEventsStorage<::test_doccomments::Interface> event_storage;
  fidl::internal::WireEventDispatcher<::test_doccomments::Interface> dispatcher{this};
  return HandleOneEventImpl_(client_end.channel(), event_storage.view(), dispatcher);
}
::fidl::Status
fidl::internal::WireEventDispatcher<::test_doccomments::Interface>::DispatchEvent(
    ::fidl::IncomingHeaderAndMessage& msg,
    ::fidl::internal::MessageStorageViewBase* storage_view) {
  switch (msg.header()->ordinal) {
    case ::test_doccomments::kInterface_OnEvent_Ordinal: {
      ::fit::result decoded = ::fidl::internal::InplaceDecodeTransactionalEvent<::test_doccomments::Interface::OnEvent>(
          std::move(msg));
      if (!decoded.is_ok()) {
        return decoded.error_value();
      }
      if (event_handler()) {
        event_handler()->OnEvent();
      }
      return ::fidl::Status::Ok();
    }
    default:
      std::move(msg).CloseHandles();
      return ::fidl::Status::UnknownOrdinal();
  }
}

#endif  // __Fuchsia__

#ifdef __Fuchsia__

constexpr ::fidl::internal::MethodEntry fidl::internal::WireServerDispatcher<::test_doccomments::Interface>::entries_[] = {
    {
        ::test_doccomments::kInterface_Method_Ordinal,
        [](void* interface, ::fidl::EncodedMessage& msg, ::fidl::WireFormatMetadata metadata,
           internal::MessageStorageViewBase* storage_view, ::fidl::Transaction* txn) {
          ::fit::result decoded = ::fidl::internal::DecodeTransactionalMessageWithoutBody(
              msg, metadata);
          if (unlikely(!decoded.is_ok())) {
            return decoded.error_value();
          }
          ::fidl::internal::WireCompleter<::test_doccomments::Interface::Method>::Sync completer(txn);
          reinterpret_cast<::fidl::WireServer<::test_doccomments::Interface>*>(interface)->Method(
              completer);
          return ::fidl::Status::Ok();
        },
    },
};

const ::fidl::internal::MethodEntry* fidl::internal::WireServerDispatcher<::test_doccomments::Interface>::entries_end_ =
    &entries_[1];

::fidl::DispatchResult fidl::internal::WireServerDispatcher<::test_doccomments::Interface>::TryDispatch(
    ::fidl::WireServer<::test_doccomments::Interface>* impl, ::fidl::IncomingHeaderAndMessage& msg,
    internal::MessageStorageViewBase* storage_view, ::fidl::Transaction* txn) {
  return ::fidl::internal::TryDispatch(
      impl, msg, storage_view, txn, entries_, entries_end_);
}

void fidl::internal::WireServerDispatcher<::test_doccomments::Interface>::Dispatch(::fidl::WireServer<::test_doccomments::Interface>* impl, ::fidl::IncomingHeaderAndMessage&& msg,
                                                                                   internal::MessageStorageViewBase* storage_view, ::fidl::Transaction* txn) {
  ::fidl::internal::Dispatch(impl, msg, storage_view, txn, entries_, entries_end_,
                             &unknown_method_handler_entry_);
}

void fidl::WireServer<::test_doccomments::Interface>::dispatch_message(
    ::fidl::IncomingHeaderAndMessage&& msg, ::fidl::Transaction* txn,
    ::fidl::internal::MessageStorageViewBase* storage_view) {
  ::fidl::internal::WireServerDispatcher<::test_doccomments::Interface>::Dispatch(this, std::move(msg), storage_view, txn);
}

#endif  // __Fuchsia__

#ifdef __Fuchsia__
void ::fidl::internal::TransactionalRequest<::test_doccomments::Interface::Method>::_InitHeader() {
  ::fidl::InitTxnHeader(&header, 0, ::test_doccomments::kInterface_Method_Ordinal, ::test_doccomments::kInterface_Method_DynamicFlags);
}

#endif  // __Fuchsia__

#ifdef __Fuchsia__
void ::fidl::internal::TransactionalEvent<::test_doccomments::Interface::OnEvent>::_InitHeader() {
  ::fidl::InitTxnHeader(&header, 0, ::test_doccomments::kInterface_OnEvent_Ordinal, ::test_doccomments::kInterface_OnEvent_DynamicFlags);
}

#endif  // __Fuchsia__

#ifdef __Fuchsia__

::fidl::OneWayStatus fidl::internal::WireWeakEventSender<::test_doccomments::Interface>::OnEvent() {
  ::fidl::internal::TransactionalEvent<::test_doccomments::Interface::OnEvent> _response{};
  FIDL_INTERNAL_DISABLE_AUTO_VAR_INIT
  ::fidl::internal::OwnedEncodedMessage<::fidl::internal::TransactionalEvent<::test_doccomments::Interface::OnEvent>, ::fidl::internal::ChannelTransport> _response_message{
      ::fidl::internal::AllowUnownedInputRef{}, &_response};
  return _inner().SendEvent(_response_message.GetOutgoingMessage());
}

fidl::OneWayStatus fidl::internal::WireWeakBufferEventSender<::test_doccomments::Interface>::OnEvent() {
  constexpr uint32_t _buffer_size = ::fidl::EventReplyBufferSizeInChannel<::test_doccomments::Interface::OnEvent>();
  ::fit::result<::fidl::Error, ::fidl::BufferSpan> _allocation =
      _allocator().TryAllocate(_buffer_size);
  if (!_allocation.is_ok()) {
    _inner().HandleSendError(_allocation.error_value());
    return fidl::OneWayStatus{_allocation.error_value()};
  }

  ::fidl::internal::TransactionalEvent<::test_doccomments::Interface::OnEvent> _response{};
  ::fidl::internal::UnownedEncodedMessage<::fidl::internal::TransactionalEvent<::test_doccomments::Interface::OnEvent>, ::fidl::internal::ChannelTransport> _response_message(
      _allocation->data, _buffer_size, &_response);
  return _inner().SendEvent(_response_message.GetOutgoingMessage());
}

fidl::OneWayStatus fidl::internal::WireEventSender<::test_doccomments::Interface>::OnEvent() {
  ::fidl::internal::TransactionalEvent<::test_doccomments::Interface::OnEvent> _response{};
  FIDL_INTERNAL_DISABLE_AUTO_VAR_INIT
  ::fidl::internal::OwnedEncodedMessage<::fidl::internal::TransactionalEvent<::test_doccomments::Interface::OnEvent>, ::fidl::internal::ChannelTransport> _response_message{
      ::fidl::internal::AllowUnownedInputRef{}, &_response};
  auto& _message = _response_message.GetOutgoingMessage();
  _message.Write(_transport());
  return ::fidl::OneWayStatus{::fidl::Status{_message}};
}

fidl::OneWayStatus fidl::internal::WireBufferEventSender<::test_doccomments::Interface>::OnEvent() {
  constexpr uint32_t _buffer_size = ::fidl::EventReplyBufferSizeInChannel<::test_doccomments::Interface::OnEvent>();
  ::fit::result<::fidl::Error, ::fidl::BufferSpan> _allocation =
      _allocator().TryAllocate(_buffer_size);
  if (!_allocation.is_ok()) {
    return fidl::OneWayStatus{_allocation.error_value()};
  }

  ::fidl::internal::TransactionalEvent<::test_doccomments::Interface::OnEvent> _response{};
  ::fidl::internal::UnownedEncodedMessage<::fidl::internal::TransactionalEvent<::test_doccomments::Interface::OnEvent>, ::fidl::internal::ChannelTransport> _response_message(
      _allocation->data, _buffer_size, &_response);
  auto& _message = _response_message.GetOutgoingMessage();
  _message.Write(_transport());
  return ::fidl::OneWayStatus{::fidl::Status{_message}};
}

#endif  // __Fuchsia__

#pragma clang diagnostic pop
