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

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

namespace test_error {
[[maybe_unused]] constexpr inline uint64_t kExample_foo_Ordinal =
    1107623248440401476lu;

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

#ifdef __Fuchsia__
}  // namespace test_error
::fidl::internal::NaturalThenable<::test_error::Example::Foo>
fidl::internal::NaturalClientImpl<::test_error::Example>::Foo(
    ::fidl::Request<::test_error::Example::Foo> request) const {
  ::fidl::internal::NaturalMessageEncoder _encoder{
      &::fidl::internal::ChannelTransport::VTable,
      ::test_error::kExample_foo_Ordinal,
      ::test_error::kExample_foo_DynamicFlags};
  _encoder.EncodeBody(
      ::fidl::internal::NaturalMessageConverter<::fidl::Request<
          ::test_error::Example::Foo>>::IntoDomainObject(std::move(request)));
  return ::fidl::internal::NaturalThenable<::test_error::Example::Foo>(
      &client_base(), {}, std::move(_encoder),
      [](::fidl::internal::ThenableBase* base,
         ::fidl::internal::NaturalMessageEncoder& encoder,
         ::fidl::internal::ResponseContext* response_context) {
        ::fidl::OutgoingMessage msg = encoder.GetMessage();
        return base->SendTwoWay(msg, response_context);
      });
}

namespace test_error {
#endif  // __Fuchsia__

}  // namespace test_error
#ifdef __Fuchsia__

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

#ifdef __Fuchsia__

#endif  // __Fuchsia__

void fidl::internal::NaturalCompleterBase<::test_error::Example::Foo>::Reply(
    ::fidl::Response<::test_error::Example::Foo>&& response) {
  ::fidl::internal::NaturalMessageEncoder _encoder{
      &::fidl::internal::ChannelTransport::VTable,
      ::test_error::kExample_foo_Ordinal,
      ::test_error::kExample_foo_DynamicFlags};
  _encoder.EncodeBody(
      ::fidl::internal::NaturalMessageConverter<::fidl::Response<
          ::test_error::Example::Foo>>::IntoDomainObject(std::move(response)));
  ::fidl::OutgoingMessage _encoded_message = _encoder.GetMessage();
  SendReply(&_encoded_message, ::fidl::internal::OutgoingTransportContext{});
}

#ifdef __Fuchsia__

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

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

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