// 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 foreigntypeinresponseusedthroughcompose {

//
// 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_middle_MiddleGetFooResponseTable;

}  // 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 foreigntypeinresponseusedthroughcompose
}  // namespace test
namespace fidl {

//
// Proxies and stubs declarations
//
}  // namespace fidl
namespace test {
namespace foreigntypeinresponseusedthroughcompose {

#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 = 0x401a9ffa95a4c333lu;

constexpr ::fidl::MessageDynamicFlags kTop_GetFoo_DynamicFlags = ::fidl::MessageDynamicFlags::kStrictMethod;
}  // namespace internal

#endif  // __Fuchsia__

#ifdef __Fuchsia__

class Top {
 public:
  using Proxy_ = ::test::foreigntypeinresponseusedthroughcompose::Top_Proxy;
  using Stub_ = ::test::foreigntypeinresponseusedthroughcompose::Top_Stub;
  using EventSender_ = ::test::foreigntypeinresponseusedthroughcompose::Top_EventSender;
  using Sync_ = ::test::foreigntypeinresponseusedthroughcompose::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::foreigntypeinresponseusedthroughcompose::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.foreigntypeinresponseusedthroughcompose/Top.GetFoo
  void GetFoo(GetFooCallback callback) override;

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

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

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

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

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

class Top_SyncProxy : public ::test::foreigntypeinresponseusedthroughcompose::Top_Sync {
 public:
  explicit Top_SyncProxy(::zx::channel channel);
  ~Top_SyncProxy() override;
  // cts-coverage-fidl-name:test.foreigntypeinresponseusedthroughcompose/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 foreigntypeinresponseusedthroughcompose
}  // namespace test
