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

// fidl_experiment = output_index_json

#include <fidl/test.doccomments/cpp/natural_messaging.h>
#include <lib/fidl/cpp/wire/unknown_interactions.h>

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

namespace test_doccomments {

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

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

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

[[maybe_unused]]
constexpr inline ::fidl::MessageDynamicFlags kInterface_OnEvent_DynamicFlags = ::fidl::MessageDynamicFlags::kStrictMethod;

#ifdef __Fuchsia__
}  // namespace test_doccomments

::fit::result<::fidl::OneWayError>
fidl::internal::NaturalClientImpl<::test_doccomments::Interface>::Method() const {
  ::fidl::internal::NaturalMessageEncoder _encoder{
      &::fidl::internal::ChannelTransport::VTable, ::test_doccomments::kInterface_Method_Ordinal, ::test_doccomments::kInterface_Method_DynamicFlags};
  ::fidl::OutgoingMessage _encoded_message = _encoder.GetMessage();
  ::fidl::OneWayStatus status = client_base().SendOneWay(_encoded_message);
  return ::fidl::internal::ToFitxResult(status);
}
namespace test_doccomments {

#endif  // __Fuchsia__

}  // namespace test_doccomments

#ifdef __Fuchsia__

::fit::result<::fidl::OneWayError>
fidl::internal::NaturalSyncClientImpl<::test_doccomments::Interface>::Method() {
  ::fidl::internal::NaturalMessageEncoder encoder{
      &::fidl::internal::ChannelTransport::VTable, ::test_doccomments::kInterface_Method_Ordinal, ::test_doccomments::kInterface_Method_DynamicFlags};
  ::fidl::OutgoingMessage msg = encoder.GetMessage();
  msg.Write(_client_end().handle());
  return ::fidl::internal::ToFitxResult(::fidl::OneWayStatus{msg});
}

#endif  // __Fuchsia__

#ifdef __Fuchsia__

::fidl::Status fidl::SyncEventHandler<::test_doccomments::Interface>::HandleOneEvent(
    ::fidl::UnownedClientEnd<::test_doccomments::Interface> client_end) {
  ::fidl::internal::IncomingEventsStorage<::test_doccomments::Interface> event_storage;
  fidl::internal::NaturalEventDispatcher<::test_doccomments::Interface> dispatcher{this};
  return HandleOneEventImpl_(client_end.channel(), event_storage.view(), dispatcher);
}
::fidl::Status
fidl::internal::NaturalEventDispatcher<::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::DecodeTransactionalMessage(std::move(msg));
      if (decoded.is_error()) {
        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__

::fit::result<::fidl::OneWayError> fidl::internal::NaturalWeakEventSender<::test_doccomments::Interface>::OnEvent() {
  ::fidl::internal::NaturalMessageEncoder _encoder{
      &::fidl::internal::ChannelTransport::VTable, ::test_doccomments::kInterface_OnEvent_Ordinal, ::test_doccomments::kInterface_OnEvent_DynamicFlags};
  ::fidl::OutgoingMessage _encoded_message = _encoder.GetMessage();
  return ::fidl::internal::ToFitxResult(_inner().SendEvent(_encoded_message));
}

::fit::result<::fidl::OneWayError> fidl::internal::NaturalEventSender<::test_doccomments::Interface>::OnEvent() {
  ::fidl::internal::NaturalMessageEncoder _encoder{
      &::fidl::internal::ChannelTransport::VTable, ::test_doccomments::kInterface_OnEvent_Ordinal, ::test_doccomments::kInterface_OnEvent_DynamicFlags};
  ::fidl::OutgoingMessage _encoded_message = _encoder.GetMessage();
  _encoded_message.Write(_transport());
  return ::fidl::internal::ToFitxResult(::fidl::OneWayStatus{::fidl::Status{_encoded_message}});
}

#endif  // __Fuchsia__

#ifdef __Fuchsia__

constexpr ::fidl::internal::MethodEntry fidl::internal::NaturalServerDispatcher<::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 (decoded.is_error()) {
            return decoded.error_value();
          }
          ::fidl::internal::NaturalCompleter<::test_doccomments::Interface::Method>::Sync completer(txn);
          static_cast<::fidl::Server<::test_doccomments::Interface>*>(interface)->Method(

              completer);
          return ::fidl::Status::Ok();
        },
    },
};

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

void fidl::internal::NaturalServerDispatcher<::test_doccomments::Interface>::Dispatch(::fidl::Server<::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::Server<::test_doccomments::Interface>::dispatch_message(
    ::fidl::IncomingHeaderAndMessage&& msg, ::fidl::Transaction* txn,
    ::fidl::internal::MessageStorageViewBase* storage_view) {
  ::fidl::internal::NaturalServerDispatcher<::test_doccomments::Interface>::Dispatch(this, std::move(msg), storage_view, txn);
}

#endif  // __Fuchsia__

#pragma clang diagnostic pop
