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

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

namespace test_inheritancewithrecursivedecl {
[[maybe_unused]] constexpr inline uint64_t kParent_First_Ordinal = 3973163707930985819lu;

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

#ifdef __Fuchsia__
}  // namespace test_inheritancewithrecursivedecl
::fitx::result<::fidl::Error>
fidl::internal::NaturalClientImpl<::test_inheritancewithrecursivedecl::Parent>::First(::fidl::Request<::test_inheritancewithrecursivedecl::Parent::First> request) const {
  ::fidl::internal::NaturalMessageEncoder _encoder{
      &::fidl::internal::ChannelTransport::VTable, ::test_inheritancewithrecursivedecl::kParent_First_Ordinal, ::test_inheritancewithrecursivedecl::kParent_First_DynamicFlags};
  _encoder.EncodeBody(
      ::fidl::internal::NaturalMessageConverter<::fidl::Request<::test_inheritancewithrecursivedecl::Parent::First>>::IntoDomainObject(std::move(request)));

  ::fidl::OutgoingMessage _encoded_message = _encoder.GetMessage();
  ::fidl::Status status = client_base().SendOneWay(_encoded_message);
  return ::fidl::internal::ToFitxResult(status);
}
namespace test_inheritancewithrecursivedecl {
#endif  // __Fuchsia__

}  // namespace test_inheritancewithrecursivedecl
#ifdef __Fuchsia__

::fitx::result<::fidl::Error>
fidl::internal::NaturalSyncClientImpl<::test_inheritancewithrecursivedecl::Parent>::First(::fidl::Request<::test_inheritancewithrecursivedecl::Parent::First> request) {
  ::fidl::internal::NaturalMessageEncoder encoder{
      &::fidl::internal::ChannelTransport::VTable, ::test_inheritancewithrecursivedecl::kParent_First_Ordinal, ::test_inheritancewithrecursivedecl::kParent_First_DynamicFlags};
  encoder.EncodeBody(
      ::fidl::internal::NaturalMessageConverter<::fidl::Request<::test_inheritancewithrecursivedecl::Parent::First>>::IntoDomainObject(std::move(request)));
  ::fidl::OutgoingMessage msg = encoder.GetMessage();
  msg.Write(_client_end().handle());
  return ::fidl::internal::ToFitxResult(::fidl::Status{msg});
}

#endif  // __Fuchsia__

#ifdef __Fuchsia__

::fidl::Status fidl::SyncEventHandler<::test_inheritancewithrecursivedecl::Parent>::HandleOneEvent(
    ::fidl::UnownedClientEnd<::test_inheritancewithrecursivedecl::Parent> client_end) {
  ::fidl::internal::IncomingEventsStorage<::test_inheritancewithrecursivedecl::Parent> event_storage;
  fidl::internal::NaturalEventDispatcher<::test_inheritancewithrecursivedecl::Parent> dispatcher{this};
  return HandleOneEventImpl_(client_end.channel(), event_storage.view(), dispatcher);
}
#endif  // __Fuchsia__

#ifdef __Fuchsia__

#endif  // __Fuchsia__

#ifdef __Fuchsia__

constexpr ::fidl::internal::MethodEntry fidl::internal::NaturalServerDispatcher<::test_inheritancewithrecursivedecl::Parent>::entries_[] = {
    {
        ::test_inheritancewithrecursivedecl::kParent_First_Ordinal,
        [](void* interface, ::fidl::IncomingMessage&& msg,
           internal::MessageStorageViewBase* storage_view, ::fidl::Transaction* txn) {
          ::fitx::result decoded = ::fidl::internal::DecodeTransactionalMessage<::test_inheritancewithrecursivedecl::ParentFirstRequest>(std::move(msg));
          if (decoded.is_error()) {
            return decoded.error_value();
          }
          ::fidl::Request<::test_inheritancewithrecursivedecl::Parent::First> request = ::fidl::internal::NaturalMessageConverter<::fidl::Request<::test_inheritancewithrecursivedecl::Parent::First>>::FromDomainObject(std::move(decoded.value()));
          ::fidl::internal::NaturalCompleter<::test_inheritancewithrecursivedecl::Parent::First>::Sync completer(txn);
          static_cast<::fidl::Server<::test_inheritancewithrecursivedecl::Parent>*>(interface)->First(
              request, completer);
          return ::fidl::Status::Ok();
        },
    },
};

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

void fidl::internal::NaturalServerDispatcher<::test_inheritancewithrecursivedecl::Parent>::Dispatch(::fidl::Server<::test_inheritancewithrecursivedecl::Parent>* impl, ::fidl::IncomingMessage&& msg,
                                                                                                    internal::MessageStorageViewBase* storage_view, ::fidl::Transaction* txn) {
  ::fidl::internal::Dispatch(impl, msg, storage_view, txn, entries_, entries_end_);
}
void fidl::Server<::test_inheritancewithrecursivedecl::Parent>::dispatch_message(
    ::fidl::IncomingMessage&& msg, ::fidl::Transaction* txn,
    ::fidl::internal::MessageStorageViewBase* storage_view) {
  ::fidl::internal::NaturalServerDispatcher<::test_inheritancewithrecursivedecl::Parent>::Dispatch(this, std::move(msg), storage_view, txn);
}
#endif  // __Fuchsia__

namespace test_inheritancewithrecursivedecl {
[[maybe_unused]] constexpr inline uint64_t kChild_First_Ordinal = 3973163707930985819lu;

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

[[maybe_unused]] constexpr inline uint64_t kChild_Second_Ordinal = 2545123272820824165lu;

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

#ifdef __Fuchsia__
}  // namespace test_inheritancewithrecursivedecl
::fitx::result<::fidl::Error>
fidl::internal::NaturalClientImpl<::test_inheritancewithrecursivedecl::Child>::First(::fidl::Request<::test_inheritancewithrecursivedecl::Child::First> request) const {
  ::fidl::internal::NaturalMessageEncoder _encoder{
      &::fidl::internal::ChannelTransport::VTable, ::test_inheritancewithrecursivedecl::kChild_First_Ordinal, ::test_inheritancewithrecursivedecl::kChild_First_DynamicFlags};
  _encoder.EncodeBody(
      ::fidl::internal::NaturalMessageConverter<::fidl::Request<::test_inheritancewithrecursivedecl::Child::First>>::IntoDomainObject(std::move(request)));

  ::fidl::OutgoingMessage _encoded_message = _encoder.GetMessage();
  ::fidl::Status status = client_base().SendOneWay(_encoded_message);
  return ::fidl::internal::ToFitxResult(status);
}

::fitx::result<::fidl::Error>
fidl::internal::NaturalClientImpl<::test_inheritancewithrecursivedecl::Child>::Second(::fidl::Request<::test_inheritancewithrecursivedecl::Child::Second> request) const {
  ::fidl::internal::NaturalMessageEncoder _encoder{
      &::fidl::internal::ChannelTransport::VTable, ::test_inheritancewithrecursivedecl::kChild_Second_Ordinal, ::test_inheritancewithrecursivedecl::kChild_Second_DynamicFlags};
  _encoder.EncodeBody(
      ::fidl::internal::NaturalMessageConverter<::fidl::Request<::test_inheritancewithrecursivedecl::Child::Second>>::IntoDomainObject(std::move(request)));

  ::fidl::OutgoingMessage _encoded_message = _encoder.GetMessage();
  ::fidl::Status status = client_base().SendOneWay(_encoded_message);
  return ::fidl::internal::ToFitxResult(status);
}
namespace test_inheritancewithrecursivedecl {
#endif  // __Fuchsia__

}  // namespace test_inheritancewithrecursivedecl
#ifdef __Fuchsia__

::fitx::result<::fidl::Error>
fidl::internal::NaturalSyncClientImpl<::test_inheritancewithrecursivedecl::Child>::First(::fidl::Request<::test_inheritancewithrecursivedecl::Child::First> request) {
  ::fidl::internal::NaturalMessageEncoder encoder{
      &::fidl::internal::ChannelTransport::VTable, ::test_inheritancewithrecursivedecl::kChild_First_Ordinal, ::test_inheritancewithrecursivedecl::kChild_First_DynamicFlags};
  encoder.EncodeBody(
      ::fidl::internal::NaturalMessageConverter<::fidl::Request<::test_inheritancewithrecursivedecl::Child::First>>::IntoDomainObject(std::move(request)));
  ::fidl::OutgoingMessage msg = encoder.GetMessage();
  msg.Write(_client_end().handle());
  return ::fidl::internal::ToFitxResult(::fidl::Status{msg});
}

::fitx::result<::fidl::Error>
fidl::internal::NaturalSyncClientImpl<::test_inheritancewithrecursivedecl::Child>::Second(::fidl::Request<::test_inheritancewithrecursivedecl::Child::Second> request) {
  ::fidl::internal::NaturalMessageEncoder encoder{
      &::fidl::internal::ChannelTransport::VTable, ::test_inheritancewithrecursivedecl::kChild_Second_Ordinal, ::test_inheritancewithrecursivedecl::kChild_Second_DynamicFlags};
  encoder.EncodeBody(
      ::fidl::internal::NaturalMessageConverter<::fidl::Request<::test_inheritancewithrecursivedecl::Child::Second>>::IntoDomainObject(std::move(request)));
  ::fidl::OutgoingMessage msg = encoder.GetMessage();
  msg.Write(_client_end().handle());
  return ::fidl::internal::ToFitxResult(::fidl::Status{msg});
}

#endif  // __Fuchsia__

#ifdef __Fuchsia__

::fidl::Status fidl::SyncEventHandler<::test_inheritancewithrecursivedecl::Child>::HandleOneEvent(
    ::fidl::UnownedClientEnd<::test_inheritancewithrecursivedecl::Child> client_end) {
  ::fidl::internal::IncomingEventsStorage<::test_inheritancewithrecursivedecl::Child> event_storage;
  fidl::internal::NaturalEventDispatcher<::test_inheritancewithrecursivedecl::Child> dispatcher{this};
  return HandleOneEventImpl_(client_end.channel(), event_storage.view(), dispatcher);
}
#endif  // __Fuchsia__

#ifdef __Fuchsia__

#endif  // __Fuchsia__

#ifdef __Fuchsia__

constexpr ::fidl::internal::MethodEntry fidl::internal::NaturalServerDispatcher<::test_inheritancewithrecursivedecl::Child>::entries_[] = {
    {
        ::test_inheritancewithrecursivedecl::kChild_First_Ordinal,
        [](void* interface, ::fidl::IncomingMessage&& msg,
           internal::MessageStorageViewBase* storage_view, ::fidl::Transaction* txn) {
          ::fitx::result decoded = ::fidl::internal::DecodeTransactionalMessage<::test_inheritancewithrecursivedecl::ParentFirstRequest>(std::move(msg));
          if (decoded.is_error()) {
            return decoded.error_value();
          }
          ::fidl::Request<::test_inheritancewithrecursivedecl::Child::First> request = ::fidl::internal::NaturalMessageConverter<::fidl::Request<::test_inheritancewithrecursivedecl::Child::First>>::FromDomainObject(std::move(decoded.value()));
          ::fidl::internal::NaturalCompleter<::test_inheritancewithrecursivedecl::Child::First>::Sync completer(txn);
          static_cast<::fidl::Server<::test_inheritancewithrecursivedecl::Child>*>(interface)->First(
              request, completer);
          return ::fidl::Status::Ok();
        },
    },
    {
        ::test_inheritancewithrecursivedecl::kChild_Second_Ordinal,
        [](void* interface, ::fidl::IncomingMessage&& msg,
           internal::MessageStorageViewBase* storage_view, ::fidl::Transaction* txn) {
          ::fitx::result decoded = ::fidl::internal::DecodeTransactionalMessage<::test_inheritancewithrecursivedecl::ChildSecondRequest>(std::move(msg));
          if (decoded.is_error()) {
            return decoded.error_value();
          }
          ::fidl::Request<::test_inheritancewithrecursivedecl::Child::Second> request = ::fidl::internal::NaturalMessageConverter<::fidl::Request<::test_inheritancewithrecursivedecl::Child::Second>>::FromDomainObject(std::move(decoded.value()));
          ::fidl::internal::NaturalCompleter<::test_inheritancewithrecursivedecl::Child::Second>::Sync completer(txn);
          static_cast<::fidl::Server<::test_inheritancewithrecursivedecl::Child>*>(interface)->Second(
              request, completer);
          return ::fidl::Status::Ok();
        },
    },
};

const ::fidl::internal::MethodEntry* fidl::internal::NaturalServerDispatcher<::test_inheritancewithrecursivedecl::Child>::entries_end_ =
    &entries_[2];

void fidl::internal::NaturalServerDispatcher<::test_inheritancewithrecursivedecl::Child>::Dispatch(::fidl::Server<::test_inheritancewithrecursivedecl::Child>* impl, ::fidl::IncomingMessage&& msg,
                                                                                                   internal::MessageStorageViewBase* storage_view, ::fidl::Transaction* txn) {
  ::fidl::internal::Dispatch(impl, msg, storage_view, txn, entries_, entries_end_);
}
void fidl::Server<::test_inheritancewithrecursivedecl::Child>::dispatch_message(
    ::fidl::IncomingMessage&& msg, ::fidl::Transaction* txn,
    ::fidl::internal::MessageStorageViewBase* storage_view) {
  ::fidl::internal::NaturalServerDispatcher<::test_inheritancewithrecursivedecl::Child>::Dispatch(this, std::move(msg), storage_view, txn);
}
#endif  // __Fuchsia__
