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

#pragma once

#include <test/bottom/cpp/fidl.h>
#include <test/middle/cpp/fidl.h>

#include "lib/fidl/cpp/internal/header.h"
namespace test {
namespace transitivedependenciescompose {

//
// Domain objects declarations
//

#ifdef __Fuchsia__

class Top;
using TopHandle = ::fidl::InterfaceHandle<Top>;
#endif  // __Fuchsia__

#ifdef __Fuchsia__

class Top_RequestEncoder {
 public:
  static ::fidl::HLCPPOutgoingMessage GetFoo(::fidl::MessageEncoder* _encoder) {
    return _encoder->GetMessage();
  }
};
namespace _internal {
__LOCAL extern "C" const fidl_type_t test_bottom_BottomGetFooTopResponseTable;

}  // namespace _internal
class Top_ResponseEncoder {
 public:
  static ::fidl::HLCPPOutgoingMessage GetFoo(::fidl::MessageEncoder* _encoder, ::test::bottom::Foo* foo) {
    fidl_trace(WillHLCPPEncode);

    _encoder->Alloc(4);
    ::fidl::Encode(_encoder, foo, 0 + sizeof(fidl_message_header_t));

    fidl_trace(DidHLCPPEncode, &::test::transitivedependenciescompose::_internal::test_bottom_BottomGetFooTopResponseTable, _encoder->GetPtr<const char>(0), _encoder->CurrentLength(), _encoder->CurrentHandleCount());

    return _encoder->GetMessage();
  }
};
#endif  // __Fuchsia__

}  // namespace transitivedependenciescompose
}  // namespace test
namespace fidl {

//
// Proxies and stubs declarations
//
}  // namespace fidl
namespace test {
namespace transitivedependenciescompose {
#ifdef __Fuchsia__

using TopPtr = ::fidl::InterfacePtr<Top>;
class Top_Proxy;
class Top_Stub;
class Top_EventSender;
class Top_Sync;
using TopSyncPtr = ::fidl::SynchronousInterfacePtr<Top>;
class Top_SyncProxy;

namespace internal {
constexpr uint64_t kTop_GetFoo_Ordinal = 0x245770d9d719c667lu;
constexpr ::fidl::MessageDynamicFlags kTop_GetFoo_DynamicFlags = ::fidl::MessageDynamicFlags::kStrictMethod;
}  // namespace internal
#endif  // __Fuchsia__

#ifdef __Fuchsia__

class Top {
 public:
  using Proxy_ = ::test::transitivedependenciescompose::Top_Proxy;
  using Stub_ = ::test::transitivedependenciescompose::Top_Stub;
  using EventSender_ = ::test::transitivedependenciescompose::Top_EventSender;
  using Sync_ = ::test::transitivedependenciescompose::Top_Sync;
  virtual ~Top();
  using GetFooCallback =
      fit::function<void(::test::bottom::Foo)>;

  virtual void GetFoo(GetFooCallback callback) = 0;
};

class Top_RequestDecoder {
 public:
  Top_RequestDecoder() = default;
  virtual ~Top_RequestDecoder() = default;
  static const fidl_type_t* GetType(uint64_t ordinal, bool* out_needs_response);
  virtual void GetFoo() = 0;
};

class Top_ResponseDecoder {
 public:
  Top_ResponseDecoder() = default;
  virtual ~Top_ResponseDecoder() = default;
  static const fidl_type_t* GetType(uint64_t ordinal);
  virtual void GetFoo(::test::bottom::Foo foo) = 0;
};

class Top_EventSender {
 public:
  virtual ~Top_EventSender();
};

class Top_Sync {
 public:
  using Proxy_ = ::test::transitivedependenciescompose::Top_SyncProxy;
  virtual ~Top_Sync();
  virtual zx_status_t GetFoo(::test::bottom::Foo* out_foo) = 0;
};

class Top_Proxy final : public ::fidl::internal::Proxy, public Top {
 public:
  explicit Top_Proxy(::fidl::internal::ProxyController* controller);
  ~Top_Proxy() override;

  zx_status_t Dispatch_(::fidl::HLCPPIncomingMessage message) override;
  // cts-coverage-fidl-name:test.transitivedependenciescompose/Top.GetFoo
  void GetFoo(GetFooCallback callback) override;

 private:
  Top_Proxy(const ::test::transitivedependenciescompose::Top_Proxy&) = delete;
  Top_Proxy& operator=(const ::test::transitivedependenciescompose::Top_Proxy&) = delete;

  ::fidl::internal::ProxyController* controller_;
};

class Top_Stub final : public ::fidl::internal::Stub, public ::test::transitivedependenciescompose::Top_EventSender {
 public:
  typedef class ::test::transitivedependenciescompose::Top Top_clazz;
  explicit Top_Stub(::test::transitivedependenciescompose::Top_Stub::Top_clazz* impl);
  ~Top_Stub() override;

  zx_status_t Dispatch_(::fidl::HLCPPIncomingMessage message,
                        ::fidl::internal::PendingResponse response) override;

 private:
  ::test::transitivedependenciescompose::Top_Stub::Top_clazz* impl_;
};

class Top_SyncProxy : public ::test::transitivedependenciescompose::Top_Sync {
 public:
  explicit Top_SyncProxy(::zx::channel channel);
  ~Top_SyncProxy() override;
  // cts-coverage-fidl-name:test.transitivedependenciescompose/Top.GetFoo
  zx_status_t GetFoo(::test::bottom::Foo* out_foo) override;

 private:
  ::fidl::internal::SynchronousProxy proxy_;
  friend class ::fidl::SynchronousInterfacePtr<Top>;
};
#endif  // __Fuchsia__

}  // namespace transitivedependenciescompose
}  // namespace test
