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

#pragma once

#include "lib/fidl/cpp/internal/natural_types_header.h"

//
// Domain objects declarations (i.e. "natural types" in unified bindings).
//
namespace fidl {
namespace test {
namespace inheritance {
#ifdef __Fuchsia__

class super;
using superHandle = ::fidl::InterfaceHandle<super>;
#endif  // __Fuchsia__

#ifdef __Fuchsia__

class sub;
using subHandle = ::fidl::InterfaceHandle<sub>;
#endif  // __Fuchsia__

#ifdef __Fuchsia__

namespace _internal {
extern "C" const fidl_type_t fidl_test_inheritance_superfooRequestTable;

}  // namespace _internal
class super_RequestEncoder {
 public:
  static ::fidl::HLCPPOutgoingMessage foo(::fidl::Encoder* _encoder,
                                          ::std::string* s) {
    fidl_trace(WillHLCPPEncode);
    _encoder->Alloc(32 - sizeof(fidl_message_header_t));
    ::fidl::Encode(_encoder, s, 16);

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

    return _encoder->GetMessage();
  }
};
namespace _internal {
extern "C" const fidl_type_t fidl_test_inheritance_superfooResponseTable;

}  // namespace _internal
class super_ResponseEncoder {
 public:
  static ::fidl::HLCPPOutgoingMessage foo(::fidl::Encoder* _encoder,
                                          int64_t* y) {
    fidl_trace(WillHLCPPEncode);
    _encoder->Alloc(24 - sizeof(fidl_message_header_t));
    ::fidl::Encode(_encoder, y, 16);

    fidl_trace(DidHLCPPEncode,
               &::fidl::test::inheritance::_internal::
                   fidl_test_inheritance_superfooResponseTable,
               _encoder->GetPtr<const char>(0), _encoder->CurrentLength(),
               _encoder->CurrentHandleCount());
    return _encoder->GetMessage();
  }
};
#endif  // __Fuchsia__

#ifdef __Fuchsia__

namespace _internal {
extern "C" const fidl_type_t fidl_test_inheritance_subfooRequestTable;

}  // namespace _internal
class sub_RequestEncoder {
 public:
  static ::fidl::HLCPPOutgoingMessage foo(::fidl::Encoder* _encoder,
                                          ::std::string* s) {
    fidl_trace(WillHLCPPEncode);
    _encoder->Alloc(32 - sizeof(fidl_message_header_t));
    ::fidl::Encode(_encoder, s, 16);

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

    return _encoder->GetMessage();
  }
};
namespace _internal {
extern "C" const fidl_type_t fidl_test_inheritance_subfooResponseTable;

}  // namespace _internal
class sub_ResponseEncoder {
 public:
  static ::fidl::HLCPPOutgoingMessage foo(::fidl::Encoder* _encoder,
                                          int64_t* y) {
    fidl_trace(WillHLCPPEncode);
    _encoder->Alloc(24 - sizeof(fidl_message_header_t));
    ::fidl::Encode(_encoder, y, 16);

    fidl_trace(DidHLCPPEncode,
               &::fidl::test::inheritance::_internal::
                   fidl_test_inheritance_subfooResponseTable,
               _encoder->GetPtr<const char>(0), _encoder->CurrentLength(),
               _encoder->CurrentHandleCount());
    return _encoder->GetMessage();
  }
};
#endif  // __Fuchsia__

}  // namespace inheritance
}  // namespace test

}  // namespace fidl
