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

#include <test/inheritance/cpp/fidl.h>

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

//
// Domain objects definitions
//
namespace test {
namespace inheritance {
extern "C" const fidl_type_t test_inheritance_SuperFooTopResponseTable;
const fidl_type_t* SuperFooTopResponse::FidlType = &test_inheritance_SuperFooTopResponseTable;

void SuperFooTopResponse::Encode(::fidl::Encoder* _encoder, size_t _offset,
                                 cpp17::optional<::fidl::HandleInformation> maybe_handle_info) {
  if (::fidl::IsMemcpyCompatible<SuperFooTopResponse>::value) {
    memcpy(_encoder->template GetPtr<SuperFooTopResponse>(_offset), this, sizeof(SuperFooTopResponse));
  } else {
    ::fidl::Encode(_encoder, &y, _offset + 0);
  }
}

void SuperFooTopResponse::Decode(::fidl::Decoder* _decoder, SuperFooTopResponse* _value, size_t _offset) {
  if (::fidl::IsMemcpyCompatible<SuperFooTopResponse>::value) {
    memcpy(_value, _decoder->template GetPtr<SuperFooTopResponse>(_offset), sizeof(SuperFooTopResponse));
  } else {
    ::fidl::Decode(_decoder, &_value->y, _offset + 0);
  }
}

zx_status_t SuperFooTopResponse::Clone(SuperFooTopResponse* _result) const {
  zx_status_t _status = ::fidl::Clone(y, &_result->y);
  if (_status != ZX_OK)
    return _status;
  return ZX_OK;
}

extern "C" const fidl_type_t test_inheritance_SuperFooRequestTable;
const fidl_type_t* SuperFooRequest::FidlType = &test_inheritance_SuperFooRequestTable;

void SuperFooRequest::Encode(::fidl::Encoder* _encoder, size_t _offset,
                             cpp17::optional<::fidl::HandleInformation> maybe_handle_info) {
  if (::fidl::IsMemcpyCompatible<SuperFooRequest>::value) {
    memcpy(_encoder->template GetPtr<SuperFooRequest>(_offset), this, sizeof(SuperFooRequest));
  } else {
    ::fidl::Encode(_encoder, &s, _offset + 0);
  }
}

void SuperFooRequest::Decode(::fidl::Decoder* _decoder, SuperFooRequest* _value, size_t _offset) {
  if (::fidl::IsMemcpyCompatible<SuperFooRequest>::value) {
    memcpy(_value, _decoder->template GetPtr<SuperFooRequest>(_offset), sizeof(SuperFooRequest));
  } else {
    ::fidl::Decode(_decoder, &_value->s, _offset + 0);
  }
}

zx_status_t SuperFooRequest::Clone(SuperFooRequest* _result) const {
  zx_status_t _status = ::fidl::Clone(s, &_result->s);
  if (_status != ZX_OK)
    return _status;
  return ZX_OK;
}

//
// Proxies and stubs definitions
//
#ifdef __Fuchsia__

namespace _internal {
__LOCAL extern "C" const fidl_type_t test_inheritance_SuperFooRequestTable;
__LOCAL extern "C" const fidl_type_t test_inheritance_SuperFooTopResponseTable;

}  // namespace _internal
super::~super() = default;

const fidl_type_t* ::test::inheritance::super_RequestDecoder::GetType(uint64_t ordinal, bool* out_needs_response) {
  *out_needs_response = false;
  switch (ordinal) {
    case ::test::inheritance::internal::ksuper_foo_Ordinal:
      *out_needs_response = true;
      return &::test::inheritance::_internal::test_inheritance_SuperFooRequestTable;
      ;
    default:
      return nullptr;
  }
}

const fidl_type_t* super_ResponseDecoder::GetType(uint64_t ordinal) {
  switch (ordinal) {
    case ::test::inheritance::internal::ksuper_foo_Ordinal:
      return &::test::inheritance::_internal::test_inheritance_SuperFooTopResponseTable;
      ;
    default:
      return nullptr;
  }
}

super_EventSender::~super_EventSender() = default;

super_Sync::~super_Sync() = default;

super_Proxy::super_Proxy(::fidl::internal::ProxyController* controller)
    : controller_(controller) {
  (void)controller_;
}

super_Proxy::~super_Proxy() = default;

zx_status_t super_Proxy::Dispatch_(::fidl::HLCPPIncomingMessage message) {
  zx_status_t status = ZX_OK;
  switch (message.ordinal()) {
    default: {
      status = ZX_ERR_NOT_SUPPORTED;
      break;
    }
  }
  return status;
}

namespace {

::std::unique_ptr<::fidl::internal::SingleUseMessageHandler>
super_foo_ResponseHandler(super::fooCallback&& callback) {
  ZX_DEBUG_ASSERT_MSG(callback,
                      "Callback must not be empty for super::foo\n");
  return ::std::make_unique<::fidl::internal::SingleUseMessageHandler>(
      [callback_ = std::move(callback)](::fidl::HLCPPIncomingMessage&& message) {
        ::fidl::Decoder decoder(std::move(message));
        callback_(::fidl::DecodeAs<int64_t>(&decoder, 0 + sizeof(fidl_message_header_t)));
        return ZX_OK;
      },
      &::test::inheritance::_internal::test_inheritance_SuperFooTopResponseTable);
}

}  // namespace
void super_Proxy::foo(::std::string s, fooCallback callback) {
  ::fidl::MessageEncoder _encoder(::test::inheritance::internal::ksuper_foo_Ordinal, ::test::inheritance::internal::ksuper_foo_DynamicFlags);
  const fidl_type_t* req_type = &::test::inheritance::_internal::test_inheritance_SuperFooRequestTable;
  controller_->Send(req_type, ::test::inheritance::super_RequestEncoder::foo(&_encoder, &s), super_foo_ResponseHandler(std::move(callback)));
}

super_Stub::super_Stub(::test::inheritance::super_Stub::super_clazz* impl) : impl_(impl) {
  (void)impl_;
}

super_Stub::~super_Stub() = default;

namespace {

class super_foo_Responder final {
 public:
  super_foo_Responder(::fidl::internal::PendingResponse response)
      : response_(std::move(response)) {}

  void operator()(int64_t y) {
    ::fidl::MessageEncoder _encoder(::test::inheritance::internal::ksuper_foo_Ordinal, ::test::inheritance::internal::ksuper_foo_DynamicFlags);
    const fidl_type_t* resp_type = &::test::inheritance::_internal::test_inheritance_SuperFooTopResponseTable;
    response_.Send(resp_type, ::test::inheritance::super_ResponseEncoder::foo(&_encoder, &y));
  }

 private:
  ::fidl::internal::PendingResponse response_;
};

}  // namespace

zx_status_t super_Stub::Dispatch_(
    ::fidl::HLCPPIncomingMessage message,
    ::fidl::internal::PendingResponse response) {
  bool needs_response;
  const fidl_type_t* request_type = ::test::inheritance::super_RequestDecoder::GetType(message.ordinal(), &needs_response);
  if (!message.has_only_header()) {
    if (request_type == nullptr) {
      return ZX_ERR_NOT_SUPPORTED;
    }
    const char* error_msg = nullptr;
    zx_status_t status = message.Decode(request_type, &error_msg);
    if (status != ZX_OK) {
      FIDL_REPORT_DECODING_ERROR(message, request_type, error_msg);
      return status;
    }
  }

  if (response.needs_response() != needs_response) {
    if (needs_response) {
      FIDL_REPORT_DECODING_ERROR(message, request_type, "Message needing a response with no txid");
    } else {
      FIDL_REPORT_DECODING_ERROR(message, request_type, "Message not needing a response with a txid");
    }
    return ZX_ERR_INVALID_ARGS;
  }

  uint64_t ordinal = message.ordinal();
  switch (ordinal) {
    case ::test::inheritance::internal::ksuper_foo_Ordinal: {
      ::fidl::Decoder decoder(std::move(message));
      impl_->foo(::fidl::DecodeAs<::std::string>(&decoder, 0 + sizeof(fidl_message_header_t)), super_foo_Responder(std::move(response)));
      break;
    }
    default: {
      return ZX_ERR_NOT_SUPPORTED;
    }
  }
  return ZX_OK;
}

super_SyncProxy::super_SyncProxy(::zx::channel channel)
    : proxy_(::std::move(channel)) {}

super_SyncProxy::~super_SyncProxy() = default;

zx_status_t super_SyncProxy::foo(::std::string s, int64_t* out_y) {
  ::fidl::MessageEncoder _encoder(::test::inheritance::internal::ksuper_foo_Ordinal, ::test::inheritance::internal::ksuper_foo_DynamicFlags);
  ::fidl::IncomingMessageBuffer buffer_;
  ::fidl::HLCPPIncomingMessage response_ = buffer_.CreateEmptyIncomingMessage();
  const fidl_type_t* req_type = &::test::inheritance::_internal::test_inheritance_SuperFooRequestTable;
  const fidl_type_t* resp_type = &::test::inheritance::_internal::test_inheritance_SuperFooTopResponseTable;
  zx_status_t status_ = proxy_.Call(req_type, resp_type, ::test::inheritance::super_RequestEncoder::foo(&_encoder, &s), &response_);
  if (status_ != ZX_OK)
    return status_;
  ::fidl::Decoder decoder_(std::move(response_));
  *out_y = ::fidl::DecodeAs<int64_t>(&decoder_, 0 + sizeof(fidl_message_header_t));
  return ZX_OK;
}
#endif  // __Fuchsia__

#ifdef __Fuchsia__

sub::~sub() = default;

const fidl_type_t* ::test::inheritance::sub_RequestDecoder::GetType(uint64_t ordinal, bool* out_needs_response) {
  *out_needs_response = false;
  switch (ordinal) {
    case ::test::inheritance::internal::ksub_foo_Ordinal:
      *out_needs_response = true;
      return &::test::inheritance::_internal::test_inheritance_SuperFooRequestTable;
      ;
    default:
      return nullptr;
  }
}

const fidl_type_t* sub_ResponseDecoder::GetType(uint64_t ordinal) {
  switch (ordinal) {
    case ::test::inheritance::internal::ksub_foo_Ordinal:
      return &::test::inheritance::_internal::test_inheritance_SuperFooTopResponseTable;
      ;
    default:
      return nullptr;
  }
}

sub_EventSender::~sub_EventSender() = default;

sub_Sync::~sub_Sync() = default;

sub_Proxy::sub_Proxy(::fidl::internal::ProxyController* controller)
    : controller_(controller) {
  (void)controller_;
}

sub_Proxy::~sub_Proxy() = default;

zx_status_t sub_Proxy::Dispatch_(::fidl::HLCPPIncomingMessage message) {
  zx_status_t status = ZX_OK;
  switch (message.ordinal()) {
    default: {
      status = ZX_ERR_NOT_SUPPORTED;
      break;
    }
  }
  return status;
}

namespace {

::std::unique_ptr<::fidl::internal::SingleUseMessageHandler>
sub_foo_ResponseHandler(sub::fooCallback&& callback) {
  ZX_DEBUG_ASSERT_MSG(callback,
                      "Callback must not be empty for sub::foo\n");
  return ::std::make_unique<::fidl::internal::SingleUseMessageHandler>(
      [callback_ = std::move(callback)](::fidl::HLCPPIncomingMessage&& message) {
        ::fidl::Decoder decoder(std::move(message));
        callback_(::fidl::DecodeAs<int64_t>(&decoder, 0 + sizeof(fidl_message_header_t)));
        return ZX_OK;
      },
      &::test::inheritance::_internal::test_inheritance_SuperFooTopResponseTable);
}

}  // namespace
void sub_Proxy::foo(::std::string s, fooCallback callback) {
  ::fidl::MessageEncoder _encoder(::test::inheritance::internal::ksub_foo_Ordinal, ::test::inheritance::internal::ksub_foo_DynamicFlags);
  const fidl_type_t* req_type = &::test::inheritance::_internal::test_inheritance_SuperFooRequestTable;
  controller_->Send(req_type, ::test::inheritance::sub_RequestEncoder::foo(&_encoder, &s), sub_foo_ResponseHandler(std::move(callback)));
}

sub_Stub::sub_Stub(::test::inheritance::sub_Stub::sub_clazz* impl) : impl_(impl) {
  (void)impl_;
}

sub_Stub::~sub_Stub() = default;

namespace {

class sub_foo_Responder final {
 public:
  sub_foo_Responder(::fidl::internal::PendingResponse response)
      : response_(std::move(response)) {}

  void operator()(int64_t y) {
    ::fidl::MessageEncoder _encoder(::test::inheritance::internal::ksub_foo_Ordinal, ::test::inheritance::internal::ksub_foo_DynamicFlags);
    const fidl_type_t* resp_type = &::test::inheritance::_internal::test_inheritance_SuperFooTopResponseTable;
    response_.Send(resp_type, ::test::inheritance::sub_ResponseEncoder::foo(&_encoder, &y));
  }

 private:
  ::fidl::internal::PendingResponse response_;
};

}  // namespace

zx_status_t sub_Stub::Dispatch_(
    ::fidl::HLCPPIncomingMessage message,
    ::fidl::internal::PendingResponse response) {
  bool needs_response;
  const fidl_type_t* request_type = ::test::inheritance::sub_RequestDecoder::GetType(message.ordinal(), &needs_response);
  if (!message.has_only_header()) {
    if (request_type == nullptr) {
      return ZX_ERR_NOT_SUPPORTED;
    }
    const char* error_msg = nullptr;
    zx_status_t status = message.Decode(request_type, &error_msg);
    if (status != ZX_OK) {
      FIDL_REPORT_DECODING_ERROR(message, request_type, error_msg);
      return status;
    }
  }

  if (response.needs_response() != needs_response) {
    if (needs_response) {
      FIDL_REPORT_DECODING_ERROR(message, request_type, "Message needing a response with no txid");
    } else {
      FIDL_REPORT_DECODING_ERROR(message, request_type, "Message not needing a response with a txid");
    }
    return ZX_ERR_INVALID_ARGS;
  }

  uint64_t ordinal = message.ordinal();
  switch (ordinal) {
    case ::test::inheritance::internal::ksub_foo_Ordinal: {
      ::fidl::Decoder decoder(std::move(message));
      impl_->foo(::fidl::DecodeAs<::std::string>(&decoder, 0 + sizeof(fidl_message_header_t)), sub_foo_Responder(std::move(response)));
      break;
    }
    default: {
      return ZX_ERR_NOT_SUPPORTED;
    }
  }
  return ZX_OK;
}

sub_SyncProxy::sub_SyncProxy(::zx::channel channel)
    : proxy_(::std::move(channel)) {}

sub_SyncProxy::~sub_SyncProxy() = default;

zx_status_t sub_SyncProxy::foo(::std::string s, int64_t* out_y) {
  ::fidl::MessageEncoder _encoder(::test::inheritance::internal::ksub_foo_Ordinal, ::test::inheritance::internal::ksub_foo_DynamicFlags);
  ::fidl::IncomingMessageBuffer buffer_;
  ::fidl::HLCPPIncomingMessage response_ = buffer_.CreateEmptyIncomingMessage();
  const fidl_type_t* req_type = &::test::inheritance::_internal::test_inheritance_SuperFooRequestTable;
  const fidl_type_t* resp_type = &::test::inheritance::_internal::test_inheritance_SuperFooTopResponseTable;
  zx_status_t status_ = proxy_.Call(req_type, resp_type, ::test::inheritance::sub_RequestEncoder::foo(&_encoder, &s), &response_);
  if (status_ != ZX_OK)
    return status_;
  ::fidl::Decoder decoder_(std::move(response_));
  *out_y = ::fidl::DecodeAs<int64_t>(&decoder_, 0 + sizeof(fidl_message_header_t));
  return ZX_OK;
}
#endif  // __Fuchsia__

}  // namespace inheritance
}  // namespace test
