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

// fidl_experiment = output_index_json

#pragma once

#include <fidl/test.bottom/cpp/natural_messaging.h>
#include <fidl/test.foreigntypeinresponseusedthroughcompose/cpp/markers.h>
#include <fidl/test.foreigntypeinresponseusedthroughcompose/cpp/natural_types.h>
#include <fidl/test.foreigntypeinresponseusedthroughcompose/cpp/wire_messaging.h>
#include <fidl/test.middle/cpp/natural_messaging.h>
#include <lib/fidl/cpp/channel.h>
#include <lib/fidl/cpp/client.h>
#include <lib/fidl/cpp/internal/thenable.h>
#include <lib/fidl/cpp/natural_types.h>
#include <lib/fidl/cpp/unified_messaging.h>
#include <lib/fidl/cpp/wire/unknown_interaction_handler.h>

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

namespace fidl {

}  // namespace fidl

template <>
struct ::fidl::internal::NaturalMethodTypes<::test_foreigntypeinresponseusedthroughcompose::Top::GetFoo> {
  using Response = ::test_middle::MiddleGetFooResponse;

  using Completer = fidl::Completer<::fidl::internal::NaturalCompleterBase<::test_foreigntypeinresponseusedthroughcompose::Top::GetFoo>>;
  using ResultCallback =
      ::fit::callback<void(::fidl::Result<::test_foreigntypeinresponseusedthroughcompose::Top::GetFoo>&)>;
};

#ifdef __Fuchsia__

template <>
class ::fidl::Response<::test_foreigntypeinresponseusedthroughcompose::Top::GetFoo> final : public ::test_middle::MiddleGetFooResponse {
 public:
  using ::test_middle::MiddleGetFooResponse::MiddleGetFooResponse;
  Response(::test_middle::MiddleGetFooResponse v) : MiddleGetFooResponse(std::move(v)) {}
};

template <>
class ::fidl::Result<::test_foreigntypeinresponseusedthroughcompose::Top::GetFoo> final : public ::fit::result<::fidl::Error, ::test_middle::MiddleGetFooResponse> {
 public:
  using ::fit::result<::fidl::Error, ::test_middle::MiddleGetFooResponse>::result;

 protected:
  Result() = default;
};

template <>
class ::fidl::internal::NaturalClientImpl<::test_foreigntypeinresponseusedthroughcompose::Top> final : public ::fidl::internal::NaturalClientBase {
 public:
  using NaturalClientBase::NaturalClientBase;
  ::fidl::internal::NaturalThenable<::test_foreigntypeinresponseusedthroughcompose::Top::GetFoo> GetFoo() const;
};

#endif  // __Fuchsia__

#ifdef __Fuchsia__

template <>
class ::fidl::internal::NaturalSyncClientImpl<::test_foreigntypeinresponseusedthroughcompose::Top> final
    : public ::fidl::internal::SyncEndpointManagedVeneer<::fidl::internal::NaturalSyncClientImpl<::test_foreigntypeinresponseusedthroughcompose::Top>> {
 public:
  ::fidl::Result<::test_foreigntypeinresponseusedthroughcompose::Top::GetFoo> GetFoo();

 private:
  ::fidl::UnownedClientEnd<::test_foreigntypeinresponseusedthroughcompose::Top> _client_end() const {
    return ::fidl::UnownedClientEnd<::test_foreigntypeinresponseusedthroughcompose::Top>(
        _transport().get<::fidl::internal::ChannelTransport>());
  }
};

#endif  // __Fuchsia__

#ifdef __Fuchsia__

template <>
class ::fidl::internal::NaturalEventHandlerInterface<::test_foreigntypeinresponseusedthroughcompose::Top> : public ::fidl::internal::BaseEventHandlerInterface {
 public:
  NaturalEventHandlerInterface() = default;
  virtual ~NaturalEventHandlerInterface() = default;
};

template <>
class ::fidl::AsyncEventHandler<::test_foreigntypeinresponseusedthroughcompose::Top>
    : public ::fidl::internal::NaturalEventHandlerInterface<::test_foreigntypeinresponseusedthroughcompose::Top>, public ::fidl::internal::AsyncEventHandler {
 public:
  AsyncEventHandler() = default;
};

template <>
class ::fidl::SyncEventHandler<::test_foreigntypeinresponseusedthroughcompose::Top>
    : public ::fidl::internal::NaturalEventHandlerInterface<::test_foreigntypeinresponseusedthroughcompose::Top>, public ::fidl::internal::SyncEventHandler {
 public:
  SyncEventHandler() = default;

  // Handle all possible events defined in this protocol.
  // Blocks to consume exactly one message from the channel, then call the corresponding virtual
  // method.
  ::fidl::Status HandleOneEvent(
      ::fidl::UnownedClientEnd<::test_foreigntypeinresponseusedthroughcompose::Top> client_end);
};

template <>
class ::fidl::internal::NaturalEventDispatcher<::test_foreigntypeinresponseusedthroughcompose::Top> final : public ::fidl::internal::IncomingEventDispatcher<::fidl::internal::NaturalEventHandlerInterface<::test_foreigntypeinresponseusedthroughcompose::Top>> {
 public:
  explicit NaturalEventDispatcher(::fidl::internal::NaturalEventHandlerInterface<::test_foreigntypeinresponseusedthroughcompose::Top>* event_handler)
      : IncomingEventDispatcher(event_handler) {}
};

#endif  // __Fuchsia__

#ifdef __Fuchsia__
template <>
class ::fidl::internal::NaturalWeakEventSender<::test_foreigntypeinresponseusedthroughcompose::Top> : public ::fidl::internal::WeakEventSenderBase {
 public:
  using WeakEventSenderBase::WeakEventSenderBase;
};

template <>
class ::fidl::internal::NaturalEventSender<::test_foreigntypeinresponseusedthroughcompose::Top>
    : public ::fidl::internal::SyncEndpointManagedVeneer<::fidl::internal::NaturalEventSender<::test_foreigntypeinresponseusedthroughcompose::Top>> {
 public:
  using SyncEndpointManagedVeneer::SyncEndpointManagedVeneer;
};

#endif  // __Fuchsia__

template <>
class ::fidl::internal::NaturalCompleterBase<::test_foreigntypeinresponseusedthroughcompose::Top::GetFoo> : public ::fidl::CompleterBase {
 public:
  void Reply(const ::fidl::Response<::test_foreigntypeinresponseusedthroughcompose::Top::GetFoo>& response);

 protected:
  using ::fidl::CompleterBase::CompleterBase;
};

template <>
class ::fidl::Server<::test_foreigntypeinresponseusedthroughcompose::Top> : public ::fidl::internal::IncomingMessageDispatcher {
 public:
  Server() = default;
  virtual ~Server() = default;

  // The FIDL protocol type that is implemented by this server.
  using _EnclosingProtocol = ::test_foreigntypeinresponseusedthroughcompose::Top;

  using Handler = fidl::ProtocolHandler<::test_foreigntypeinresponseusedthroughcompose::Top>;

  using GetFooCompleter = ::fidl::internal::NaturalCompleter<::test_foreigntypeinresponseusedthroughcompose::Top::GetFoo>;

  virtual void GetFoo(
      GetFooCompleter::Sync& completer) = 0;

  // |bind_handler| returns a handler that binds incoming connections to this
  // server implementation.
  //
  // The returned handler borrows the server instance.
  // The server must outlive the provided |dispatcher|. Only after
  // the dispatcher is shutdown will it be safe to destroy the servers.
  // The server should not be moved.
  Handler bind_handler(async_dispatcher_t* dispatcher) {
    return [impl = this, dispatcher = dispatcher](::fidl::ServerEnd<::test_foreigntypeinresponseusedthroughcompose::Top> request) {
      (void)::fidl::BindServer(dispatcher, std::move(request), impl);
    };
  }

 private:
  void dispatch_message(
      ::fidl::IncomingHeaderAndMessage&& msg, ::fidl::Transaction* txn,
      ::fidl::internal::MessageStorageViewBase* storage_view) final;
};

#ifdef __Fuchsia__

template <>
struct ::fidl::internal::NaturalServerDispatcher<::test_foreigntypeinresponseusedthroughcompose::Top> final {
  NaturalServerDispatcher() = delete;
  static void Dispatch(::fidl::Server<::test_foreigntypeinresponseusedthroughcompose::Top>* impl, ::fidl::IncomingHeaderAndMessage&& msg,
                       internal::MessageStorageViewBase* storage_view,
                       ::fidl::Transaction* txn);

 private:
  static const ::fidl::internal::MethodEntry entries_[];
  static const ::fidl::internal::MethodEntry* entries_end_;
  static constexpr const ::fidl::internal::UnknownMethodHandlerEntry& unknown_method_handler_entry_ =
      ::fidl::internal::UnknownMethodHandlerEntry::kClosedProtocolHandlerEntry;
};

#endif  // __Fuchsia__

#pragma clang diagnostic pop
