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

#pragma once

#include <fidl/test.bottom/cpp/natural_messaging.h>
#include <fidl/test.middle/cpp/natural_messaging.h>
#include <fidl/test.transitivedependenciescompose/cpp/markers.h>
#include <fidl/test.transitivedependenciescompose/cpp/natural_types.h>
#include <fidl/test.transitivedependenciescompose/cpp/wire_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>

namespace fidl {}  // namespace fidl
template <>
struct ::fidl::internal::NaturalMethodTypes<
    ::test_transitivedependenciescompose::Top::GetFoo> {
  using Completer = fidl::Completer<::fidl::internal::NaturalCompleterBase<
      ::test_transitivedependenciescompose::Top::GetFoo>>;

  using ResultCallback = ::fit::callback<void(
      ::fidl::Result<::test_transitivedependenciescompose::Top::GetFoo>&)>;

  static constexpr bool HasApplicationError = false;

  static constexpr bool IsAbsentBody = false;
};

namespace test_transitivedependenciescompose {
__LOCAL extern "C" const fidl_type_t test_bottom_BottomGetFooTopResponseTable;

#ifdef __Fuchsia__
}  // namespace test_transitivedependenciescompose

template <>
class ::fidl::Response<::test_transitivedependenciescompose::Top::GetFoo> final
    : public ::test_bottom::BottomGetFooTopResponse {
 public:
  using ::test_bottom::BottomGetFooTopResponse::BottomGetFooTopResponse;
  Response(::test_bottom::BottomGetFooTopResponse v)
      : BottomGetFooTopResponse(std::move(v)) {}
};

template <>
struct ::fidl::internal::MessageTraits<
    ::fidl::Response<::test_transitivedependenciescompose::Top::GetFoo>>
    final {
 public:
  static constexpr bool kHasPayload = true;
  using Payload = ::test_bottom::BottomGetFooTopResponse;
};
namespace test_transitivedependenciescompose {
}  // namespace test_transitivedependenciescompose
template <>
class ::fidl::Result<::test_transitivedependenciescompose::Top::GetFoo> final
    : public ::fitx::result<::fidl::Error,
                            ::test_bottom::BottomGetFooTopResponse> {
 public:
  using ::fitx::result<::fidl::Error,
                       ::test_bottom::BottomGetFooTopResponse>::result;

 protected:
  Result() = default;
};

template <>
class ::fidl::internal::NaturalClientImpl<
    ::test_transitivedependenciescompose::Top>
    final : public ::fidl::internal::NaturalClientBase {
 public:
  using NaturalClientBase::NaturalClientBase;
  ::fidl::internal::NaturalThenable<
      ::test_transitivedependenciescompose::Top::GetFoo>
  GetFoo() const;
};
namespace test_transitivedependenciescompose {
#endif  // __Fuchsia__

}  // namespace test_transitivedependenciescompose
#ifdef __Fuchsia__

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

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

template <>
class ::fidl::internal::NaturalEventDispatcher<
    ::test_transitivedependenciescompose::Top>
    final : public ::fidl::internal::IncomingEventDispatcher<
                ::fidl::AsyncEventHandler<
                    ::test_transitivedependenciescompose::Top>> {
 public:
  explicit NaturalEventDispatcher(
      ::fidl::AsyncEventHandler<::test_transitivedependenciescompose::Top>*
          event_handler)
      : IncomingEventDispatcher(event_handler) {}

 private:
  std::optional<::fidl::UnbindInfo> DispatchEvent(
      ::fidl::IncomingMessage& msg,
      internal::IncomingTransportContext transport_context) override;
};
#endif  // __Fuchsia__

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

template <>
class ::fidl::internal::NaturalEventSender<
    ::test_transitivedependenciescompose::Top>
    : public ::fidl::internal::SyncEndpointManagedVeneer<
          ::fidl::internal::NaturalEventSender<
              ::test_transitivedependenciescompose::Top>> {
 public:
  using SyncEndpointManagedVeneer::SyncEndpointManagedVeneer;
};
#endif  // __Fuchsia__

#ifdef __Fuchsia__

template <>
class ::fidl::Request<::test_transitivedependenciescompose::Top::GetFoo> final {
 public:
};

template <>
struct ::fidl::internal::MessageTraits<
    ::fidl::Request<::test_transitivedependenciescompose::Top::GetFoo>>
    final {
 public:
  static constexpr bool kHasPayload = false;
};
#endif  // __Fuchsia__

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

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

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

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

  using GetFooRequest =
      ::fidl::Request<::test_transitivedependenciescompose::Top::GetFoo>;
  using GetFooCompleter = ::fidl::internal::NaturalCompleter<
      ::test_transitivedependenciescompose::Top::GetFoo>;

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

 private:
  void dispatch_message(
      ::fidl::IncomingMessage&& msg, ::fidl::Transaction* txn,
      ::fidl::internal::IncomingTransportContext transport_context) final;
};

#ifdef __Fuchsia__

template <>
struct ::fidl::internal::NaturalServerDispatcher<
    ::test_transitivedependenciescompose::Top>
    final {
  NaturalServerDispatcher() = delete;
  static void Dispatch(
      ::fidl::Server<::test_transitivedependenciescompose::Top>* impl,
      ::fidl::IncomingMessage&& msg,
      internal::IncomingTransportContext transport_context,
      ::fidl::Transaction* txn);

 private:
  static const ::fidl::internal::MethodEntry entries_[];
  static const ::fidl::internal::MethodEntry* entries_end_;
};
#endif  // __Fuchsia__
