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

#include <fidl/test.service/cpp/natural_messaging.h>

namespace test_service {
[[maybe_unused]] constexpr inline uint64_t
    kSecondProtocol_MethodOnSecond_Ordinal = 8121179205110225988lu;

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

#ifdef __Fuchsia__
}  // namespace test_service
::fitx::result<::fidl::Error> fidl::internal::NaturalClientImpl<
    ::test_service::SecondProtocol>::MethodOnSecond() const {
  ::fidl::internal::NaturalMessageEncoder _encoder{
      &::fidl::internal::ChannelTransport::VTable,
      ::test_service::kSecondProtocol_MethodOnSecond_Ordinal,
      ::test_service::kSecondProtocol_MethodOnSecond_DynamicFlags};
  ::fidl::OutgoingMessage _encoded_message = _encoder.GetMessage();
  ::fidl::Status status = client_base().SendOneWay(_encoded_message);
  return ::fidl::internal::ToFitxResult(status);
}
namespace test_service {
#endif  // __Fuchsia__

}  // namespace test_service
#ifdef __Fuchsia__

std::optional<::fidl::UnbindInfo> fidl::internal::
    NaturalEventDispatcher<::test_service::SecondProtocol>::DispatchEvent(
        ::fidl::IncomingMessage& msg,
        ::fidl::internal::IncomingTransportContext transport_context) {
  return ::fidl::UnbindInfo::UnknownOrdinal();
}
#endif  // __Fuchsia__

#ifdef __Fuchsia__

#endif  // __Fuchsia__

#ifdef __Fuchsia__

constexpr ::fidl::internal::MethodEntry fidl::internal::NaturalServerDispatcher<
    ::test_service::SecondProtocol>::entries_[] = {
    {
        ::test_service::kSecondProtocol_MethodOnSecond_Ordinal,
        [](void* interface, ::fidl::IncomingMessage&& msg,
           internal::IncomingTransportContext transport_context,
           ::fidl::Transaction* txn) {
          ::fitx::result decoded =
              ::fidl::internal::DecodeTransactionalMessage(std::move(msg));
          if (decoded.is_error()) {
            return decoded.error_value().status();
          }
          ::fidl::Request<::test_service::SecondProtocol::MethodOnSecond>
              request;
          ::fidl::internal::NaturalCompleter<
              ::test_service::SecondProtocol::MethodOnSecond>::Sync
              completer(txn);
          static_cast<::fidl::Server<::test_service::SecondProtocol>*>(
              interface)
              ->MethodOnSecond(request, completer);
          return ZX_OK;
        },
    },
};

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

void fidl::internal::NaturalServerDispatcher<::test_service::SecondProtocol>::
    Dispatch(::fidl::Server<::test_service::SecondProtocol>* 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::Server<::test_service::SecondProtocol>::dispatch_message(
    ::fidl::IncomingMessage&& msg, ::fidl::Transaction* txn,
    ::fidl::internal::IncomingTransportContext transport_context) {
  ::fidl::internal::NaturalServerDispatcher<
      ::test_service::SecondProtocol>::Dispatch(this, std::move(msg),
                                                std::move(transport_context),
                                                txn);
}
#endif  // __Fuchsia__

namespace test_service {
[[maybe_unused]] constexpr inline uint64_t
    kFirstProtocol_MethodOnFirst_Ordinal = 6352548393671797041lu;

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

#ifdef __Fuchsia__
}  // namespace test_service
::fitx::result<::fidl::Error> fidl::internal::NaturalClientImpl<
    ::test_service::FirstProtocol>::MethodOnFirst() const {
  ::fidl::internal::NaturalMessageEncoder _encoder{
      &::fidl::internal::ChannelTransport::VTable,
      ::test_service::kFirstProtocol_MethodOnFirst_Ordinal,
      ::test_service::kFirstProtocol_MethodOnFirst_DynamicFlags};
  ::fidl::OutgoingMessage _encoded_message = _encoder.GetMessage();
  ::fidl::Status status = client_base().SendOneWay(_encoded_message);
  return ::fidl::internal::ToFitxResult(status);
}
namespace test_service {
#endif  // __Fuchsia__

}  // namespace test_service
#ifdef __Fuchsia__

std::optional<::fidl::UnbindInfo> fidl::internal::
    NaturalEventDispatcher<::test_service::FirstProtocol>::DispatchEvent(
        ::fidl::IncomingMessage& msg,
        ::fidl::internal::IncomingTransportContext transport_context) {
  return ::fidl::UnbindInfo::UnknownOrdinal();
}
#endif  // __Fuchsia__

#ifdef __Fuchsia__

#endif  // __Fuchsia__

#ifdef __Fuchsia__

constexpr ::fidl::internal::MethodEntry fidl::internal::NaturalServerDispatcher<
    ::test_service::FirstProtocol>::entries_[] = {
    {
        ::test_service::kFirstProtocol_MethodOnFirst_Ordinal,
        [](void* interface, ::fidl::IncomingMessage&& msg,
           internal::IncomingTransportContext transport_context,
           ::fidl::Transaction* txn) {
          ::fitx::result decoded =
              ::fidl::internal::DecodeTransactionalMessage(std::move(msg));
          if (decoded.is_error()) {
            return decoded.error_value().status();
          }
          ::fidl::Request<::test_service::FirstProtocol::MethodOnFirst> request;
          ::fidl::internal::NaturalCompleter<
              ::test_service::FirstProtocol::MethodOnFirst>::Sync
              completer(txn);
          static_cast<::fidl::Server<::test_service::FirstProtocol>*>(interface)
              ->MethodOnFirst(request, completer);
          return ZX_OK;
        },
    },
};

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

void fidl::internal::NaturalServerDispatcher<::test_service::FirstProtocol>::
    Dispatch(::fidl::Server<::test_service::FirstProtocol>* 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::Server<::test_service::FirstProtocol>::dispatch_message(
    ::fidl::IncomingMessage&& msg, ::fidl::Transaction* txn,
    ::fidl::internal::IncomingTransportContext transport_context) {
  ::fidl::internal::NaturalServerDispatcher<
      ::test_service::FirstProtocol>::Dispatch(this, std::move(msg),
                                               std::move(transport_context),
                                               txn);
}
#endif  // __Fuchsia__
