#include <fidl/test.drivertwoway/cpp/driver/natural_messaging.h>
#include <lib/fidl_driver/cpp/unknown_interactions.h>

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

namespace test_drivertwoway {

[[maybe_unused]]
constexpr inline uint64_t kTwoWay_Add_Ordinal = 989730524426044687lu;

[[maybe_unused]]
constexpr inline ::fidl::MessageDynamicFlags kTwoWay_Add_DynamicFlags = ::fidl::MessageDynamicFlags::kStrictMethod;
#ifdef __Fuchsia__
}  // namespace test_drivertwoway

::fidl::internal::NaturalThenable<::test_drivertwoway::TwoWay::Add>
fidl::internal::NaturalClientImpl<::test_drivertwoway::TwoWay>::Add(const ::fidl::Request<::test_drivertwoway::TwoWay::Add>& request) const {
  fdf::Arena _arena('FIDL');

  ::fidl::WriteOptions _options = {
      .outgoing_transport_context =
          ::fidl::internal::OutgoingTransportContext::Create<::fidl::internal::DriverTransport>(_arena.get()),
  };
  return ::fidl::internal::NaturalThenable<::test_drivertwoway::TwoWay::Add>(
      &client_base(), std::move(_options), &::fidl::internal::DriverTransport::VTable, ::test_drivertwoway::kTwoWay_Add_Ordinal, ::test_drivertwoway::kTwoWay_Add_DynamicFlags,
      [request = request](NaturalMessageEncoder& encoder) mutable {
        encoder.EncodeBody(request);
      },
      [arena = std::move(_arena)](
          ::fidl::internal::ThenableBase* base,
          ::fidl::internal::NaturalMessageEncoder& encoder,
          ::fidl::internal::ResponseContext* response_context) {
        ::fidl::OutgoingMessage msg = encoder.GetMessage();
        ::fidl::OutgoingMessage arena_msg = ::fdf::internal::MoveToArena(msg, arena);
        return base->SendTwoWay(arena_msg, response_context);
      });
}

namespace test_drivertwoway {

#endif  // __Fuchsia__
}  // namespace test_drivertwoway

#ifdef __Fuchsia__

#endif  // __Fuchsia__

void fidl::internal::NaturalCompleterBase<::test_drivertwoway::TwoWay::Add>::Reply(const ::fidl::Response<::test_drivertwoway::TwoWay::Add>& response) {
  ::fidl::internal::NaturalMessageEncoder _encoder{
      &::fidl::internal::DriverTransport::VTable, ::test_drivertwoway::kTwoWay_Add_Ordinal, ::test_drivertwoway::kTwoWay_Add_DynamicFlags};

  fdf::Arena _arena('FIDL');
  ::fidl::internal::OutgoingTransportContext _context =
      ::fidl::internal::OutgoingTransportContext::Create<::fidl::internal::DriverTransport>(_arena.get());
  _encoder.EncodeBody(
      ::fidl::internal::ResponseMessageConverter<::test_drivertwoway::TwoWay::Add>::IntoDomainObject(response));
  ::fidl::OutgoingMessage _msg = _encoder.GetMessage();
  ::fidl::OutgoingMessage _arena_msg = ::fdf::internal::MoveToArena(_msg, _arena);
  SendReply(&_arena_msg, std::move(_context));
}
#ifdef __Fuchsia__

constexpr ::fidl::internal::MethodEntry fidl::internal::NaturalServerDispatcher<::test_drivertwoway::TwoWay>::entries_[] = {
    {
        ::test_drivertwoway::kTwoWay_Add_Ordinal,
        [](void* interface, ::fidl::EncodedMessage& msg, ::fidl::WireFormatMetadata metadata,
           internal::MessageStorageViewBase* storage_view, ::fidl::Transaction* txn) {
          ::fit::result decoded = ::fidl::StandaloneDecode<::test_drivertwoway::TwoWayAddRequest>(
              std::move(msg), metadata);
          if (decoded.is_error()) {
            return decoded.error_value();
          }
          ::fidl::internal::NaturalCompleter<::test_drivertwoway::TwoWay::Add>::Sync completer(txn);
          static_cast<::fdf::Server<::test_drivertwoway::TwoWay>*>(interface)->Add(
              decoded.value(),
              completer);
          return ::fidl::Status::Ok();
        },
    },
};

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

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

#endif  // __Fuchsia__

#pragma clang diagnostic pop
