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

// fidl_experiment = output_index_json

#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_BottomGetFooResponseTable;

}  // namespace _internal

class Top_ResponseEncoder {
 public:
  static ::fidl::HLCPPOutgoingMessage GetFoo(::fidl::MessageEncoder* _encoder, ::test::bottom::Foo* foo) {
    _encoder->Alloc(4);
    ::fidl::Encode(_encoder, foo, 0 + sizeof(fidl_message_header_t));

    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, bool* is_known);
  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
