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

// fidl_experiment = output_index_json

#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_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;
}

extern "C" const fidl_type_t test_inheritance_SuperFooResponseTable;
const fidl_type_t* SuperFooResponse::FidlType = &test_inheritance_SuperFooResponseTable;

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

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

zx_status_t SuperFooResponse::Clone(SuperFooResponse* _result) const {
  zx_status_t _status = ::fidl::Clone(y, &_result->y);
  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_SuperFooResponseTable;

}  // namespace _internal

super::~super() = default;

const fidl_type_t* ::test::inheritance::super_RequestDecoder::GetType(uint64_t ordinal, bool* out_needs_response, bool* out_is_known) {
  *out_needs_response = false;
  *out_is_known = false;
  switch (ordinal) {
    case ::test::inheritance::internal::ksuper_foo_Ordinal:
      *out_is_known = true;
      *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_SuperFooResponseTable;
      ;
    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_SuperFooResponseTable);
}

}  // 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_SuperFooResponseTable;
    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;
  bool is_known;
  const fidl_type_t* request_type = ::test::inheritance::super_RequestDecoder::GetType(message.ordinal(), &needs_response, &is_known);

  if (!is_known) {
    return ZX_ERR_NOT_SUPPORTED;
  }

  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: {
      // Unknown ordinals are handled at the beginning of dispatching, so this
      // should be unreachable.
      ZX_PANIC("Unreachable: unknown ordinals handled earlier.");
    }
  }
  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_SuperFooResponseTable;
  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, bool* out_is_known) {
  *out_needs_response = false;
  *out_is_known = false;
  switch (ordinal) {
    case ::test::inheritance::internal::ksub_foo_Ordinal:
      *out_is_known = true;
      *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_SuperFooResponseTable;
      ;
    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_SuperFooResponseTable);
}

}  // 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_SuperFooResponseTable;
    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;
  bool is_known;
  const fidl_type_t* request_type = ::test::inheritance::sub_RequestDecoder::GetType(message.ordinal(), &needs_response, &is_known);

  if (!is_known) {
    return ZX_ERR_NOT_SUPPORTED;
  }

  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: {
      // Unknown ordinals are handled at the beginning of dispatching, so this
      // should be unreachable.
      ZX_PANIC("Unreachable: unknown ordinals handled earlier.");
    }
  }
  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_SuperFooResponseTable;
  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
