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

// fidl_experiment = output_index_json

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

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

namespace test_foreigntypeinresponseusedthroughcompose {

[[maybe_unused]]
constexpr inline uint64_t kTop_GetFoo_Ordinal = 4619180266423108403lu;

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

#ifdef __Fuchsia__
}  // namespace test_foreigntypeinresponseusedthroughcompose

::fidl::internal::NaturalThenable<::test_foreigntypeinresponseusedthroughcompose::Top::GetFoo>
fidl::internal::NaturalClientImpl<::test_foreigntypeinresponseusedthroughcompose::Top>::GetFoo() const {
  return ::fidl::internal::NaturalThenable<::test_foreigntypeinresponseusedthroughcompose::Top::GetFoo>(
      &client_base(), {}, &::fidl::internal::ChannelTransport::VTable, ::test_foreigntypeinresponseusedthroughcompose::kTop_GetFoo_Ordinal, ::test_foreigntypeinresponseusedthroughcompose::kTop_GetFoo_DynamicFlags,
      [](NaturalMessageEncoder& encoder) mutable {
        return ZX_OK;
      },
      [](
          ::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_foreigntypeinresponseusedthroughcompose {

#endif  // __Fuchsia__

}  // namespace test_foreigntypeinresponseusedthroughcompose

#ifdef __Fuchsia__

::fidl::Result<::test_foreigntypeinresponseusedthroughcompose::Top::GetFoo>
fidl::internal::NaturalSyncClientImpl<::test_foreigntypeinresponseusedthroughcompose::Top>::GetFoo() {
  ::fidl::internal::NaturalMessageEncoder encoder{
      &::fidl::internal::ChannelTransport::VTable, ::test_foreigntypeinresponseusedthroughcompose::kTop_GetFoo_Ordinal, ::test_foreigntypeinresponseusedthroughcompose::kTop_GetFoo_DynamicFlags};
  ::fidl::OutgoingMessage msg = encoder.GetMessage();
  ::fidl::internal::IncomingMessageStorage<::fidl::internal::TransactionalResponse<::test_foreigntypeinresponseusedthroughcompose::Top::GetFoo>> response_storage;
  return ::fidl::internal::DecodeResponseAndFoldError<::test_foreigntypeinresponseusedthroughcompose::Top::GetFoo>(
      msg.Call(_client_end().handle(), response_storage.view()), nullptr);
}

#endif  // __Fuchsia__

#ifdef __Fuchsia__

::fidl::Status fidl::SyncEventHandler<::test_foreigntypeinresponseusedthroughcompose::Top>::HandleOneEvent(
    ::fidl::UnownedClientEnd<::test_foreigntypeinresponseusedthroughcompose::Top> client_end) {
  ::fidl::internal::IncomingEventsStorage<::test_foreigntypeinresponseusedthroughcompose::Top> event_storage;
  fidl::internal::NaturalEventDispatcher<::test_foreigntypeinresponseusedthroughcompose::Top> dispatcher{this};
  return HandleOneEventImpl_(client_end.channel(), event_storage.view(), dispatcher);
}

#endif  // __Fuchsia__

#ifdef __Fuchsia__

#endif  // __Fuchsia__

void fidl::internal::NaturalCompleterBase<::test_foreigntypeinresponseusedthroughcompose::Top::GetFoo>::Reply(const ::fidl::Response<::test_foreigntypeinresponseusedthroughcompose::Top::GetFoo>& response) {
  ::fidl::internal::NaturalMessageEncoder _encoder{
      &::fidl::internal::ChannelTransport::VTable, ::test_foreigntypeinresponseusedthroughcompose::kTop_GetFoo_Ordinal, ::test_foreigntypeinresponseusedthroughcompose::kTop_GetFoo_DynamicFlags};
  _encoder.EncodeBody(
      ::fidl::internal::ResponseMessageConverter<::test_foreigntypeinresponseusedthroughcompose::Top::GetFoo>::IntoDomainObject(response));
  ::fidl::OutgoingMessage _encoded_message = _encoder.GetMessage();
  SendReply(&_encoded_message, ::fidl::internal::OutgoingTransportContext{});
}

#ifdef __Fuchsia__

constexpr ::fidl::internal::MethodEntry fidl::internal::NaturalServerDispatcher<::test_foreigntypeinresponseusedthroughcompose::Top>::entries_[] = {
    {
        ::test_foreigntypeinresponseusedthroughcompose::kTop_GetFoo_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_foreigntypeinresponseusedthroughcompose::Top::GetFoo>::Sync completer(txn);
          static_cast<::fidl::Server<::test_foreigntypeinresponseusedthroughcompose::Top>*>(interface)->GetFoo(

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

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

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

#endif  // __Fuchsia__

#pragma clang diagnostic pop
