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

}  // 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::foreigntypeinresponseusedthroughcompose::_internal::test_middle_MiddleGetFooTopResponseTable, _encoder->GetPtr<const char>(0), _encoder->CurrentLength(), _encoder->CurrentHandleCount());

    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);
  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
