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

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

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

//
// Domain objects definitions
//
namespace test {
namespace inheritancewithrecursivedecl {
#ifdef __Fuchsia__

extern "C" const fidl_type_t test_inheritancewithrecursivedecl_ParentFirstRequestTable;
const fidl_type_t* ParentFirstRequest::FidlType = &test_inheritancewithrecursivedecl_ParentFirstRequestTable;

void ParentFirstRequest::Encode(::fidl::Encoder* _encoder, size_t _offset,
                                cpp17::optional<::fidl::HandleInformation> maybe_handle_info) {
  if (::fidl::IsMemcpyCompatible<ParentFirstRequest>::value) {
    memcpy(_encoder->template GetPtr<ParentFirstRequest>(_offset), this, sizeof(ParentFirstRequest));
  } else {
    ::fidl::Encode(_encoder, &request, _offset + 0, ::fidl::HandleInformation{
                                                        .object_type = ZX_OBJ_TYPE_CHANNEL,
                                                        .rights = ZX_DEFAULT_CHANNEL_RIGHTS,
                                                    });
  }
}

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

zx_status_t ParentFirstRequest::Clone(ParentFirstRequest* _result) const {
  zx_status_t _status = ::fidl::Clone(request, &_result->request);
  if (_status != ZX_OK)
    return _status;
  return ZX_OK;
}
#endif  // __Fuchsia__

#ifdef __Fuchsia__

extern "C" const fidl_type_t test_inheritancewithrecursivedecl_ChildSecondRequestTable;
const fidl_type_t* ChildSecondRequest::FidlType = &test_inheritancewithrecursivedecl_ChildSecondRequestTable;

void ChildSecondRequest::Encode(::fidl::Encoder* _encoder, size_t _offset,
                                cpp17::optional<::fidl::HandleInformation> maybe_handle_info) {
  if (::fidl::IsMemcpyCompatible<ChildSecondRequest>::value) {
    memcpy(_encoder->template GetPtr<ChildSecondRequest>(_offset), this, sizeof(ChildSecondRequest));
  } else {
    ::fidl::Encode(_encoder, &request, _offset + 0, ::fidl::HandleInformation{
                                                        .object_type = ZX_OBJ_TYPE_CHANNEL,
                                                        .rights = ZX_DEFAULT_CHANNEL_RIGHTS,
                                                    });
  }
}

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

zx_status_t ChildSecondRequest::Clone(ChildSecondRequest* _result) const {
  zx_status_t _status = ::fidl::Clone(request, &_result->request);
  if (_status != ZX_OK)
    return _status;
  return ZX_OK;
}
#endif  // __Fuchsia__

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

namespace _internal {
__LOCAL extern "C" const fidl_type_t test_inheritancewithrecursivedecl_ParentFirstRequestTable;

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

const fidl_type_t* ::test::inheritancewithrecursivedecl::Parent_RequestDecoder::GetType(uint64_t ordinal, bool* out_needs_response) {
  *out_needs_response = false;
  switch (ordinal) {
    case ::test::inheritancewithrecursivedecl::internal::kParent_First_Ordinal:
      return &::test::inheritancewithrecursivedecl::_internal::test_inheritancewithrecursivedecl_ParentFirstRequestTable;
      ;
    default:
      return nullptr;
  }
}

const fidl_type_t* Parent_ResponseDecoder::GetType(uint64_t ordinal) {
  switch (ordinal) {
    default:
      return nullptr;
  }
}

Parent_EventSender::~Parent_EventSender() = default;

Parent_Sync::~Parent_Sync() = default;

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

Parent_Proxy::~Parent_Proxy() = default;

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

void Parent_Proxy::First(::fidl::InterfaceRequest<::test::inheritancewithrecursivedecl::Parent> request) {
  ::fidl::MessageEncoder _encoder(::test::inheritancewithrecursivedecl::internal::kParent_First_Ordinal, ::test::inheritancewithrecursivedecl::internal::kParent_First_DynamicFlags);
  const fidl_type_t* req_type = &::test::inheritancewithrecursivedecl::_internal::test_inheritancewithrecursivedecl_ParentFirstRequestTable;
  controller_->Send(req_type, ::test::inheritancewithrecursivedecl::Parent_RequestEncoder::First(&_encoder, &request), nullptr);
}

Parent_Stub::Parent_Stub(::test::inheritancewithrecursivedecl::Parent_Stub::Parent_clazz* impl) : impl_(impl) {
  (void)impl_;
}

Parent_Stub::~Parent_Stub() = default;

namespace {

}  // namespace

zx_status_t Parent_Stub::Dispatch_(
    ::fidl::HLCPPIncomingMessage message,
    ::fidl::internal::PendingResponse response) {
  bool needs_response;
  const fidl_type_t* request_type = ::test::inheritancewithrecursivedecl::Parent_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::inheritancewithrecursivedecl::internal::kParent_First_Ordinal: {
      ::fidl::Decoder decoder(std::move(message));
      impl_->First(::fidl::DecodeAs<::fidl::InterfaceRequest<::test::inheritancewithrecursivedecl::Parent>>(&decoder, 0 + sizeof(fidl_message_header_t)));
      break;
    }
    default: {
      return ZX_ERR_NOT_SUPPORTED;
    }
  }
  return ZX_OK;
}

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

Parent_SyncProxy::~Parent_SyncProxy() = default;

zx_status_t Parent_SyncProxy::First(::fidl::InterfaceRequest<::test::inheritancewithrecursivedecl::Parent> request) {
  ::fidl::MessageEncoder _encoder(::test::inheritancewithrecursivedecl::internal::kParent_First_Ordinal, ::test::inheritancewithrecursivedecl::internal::kParent_First_DynamicFlags);
  const fidl_type_t* req_type = &::test::inheritancewithrecursivedecl::_internal::test_inheritancewithrecursivedecl_ParentFirstRequestTable;
  return proxy_.Send(req_type, ::test::inheritancewithrecursivedecl::Parent_RequestEncoder::First(&_encoder, &request));
}
#endif  // __Fuchsia__

#ifdef __Fuchsia__

namespace _internal {
__LOCAL extern "C" const fidl_type_t test_inheritancewithrecursivedecl_ChildSecondRequestTable;

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

const fidl_type_t* ::test::inheritancewithrecursivedecl::Child_RequestDecoder::GetType(uint64_t ordinal, bool* out_needs_response) {
  *out_needs_response = false;
  switch (ordinal) {
    case ::test::inheritancewithrecursivedecl::internal::kChild_First_Ordinal:
      return &::test::inheritancewithrecursivedecl::_internal::test_inheritancewithrecursivedecl_ParentFirstRequestTable;
      ;
    case ::test::inheritancewithrecursivedecl::internal::kChild_Second_Ordinal:
      return &::test::inheritancewithrecursivedecl::_internal::test_inheritancewithrecursivedecl_ChildSecondRequestTable;
      ;
    default:
      return nullptr;
  }
}

const fidl_type_t* Child_ResponseDecoder::GetType(uint64_t ordinal) {
  switch (ordinal) {
    default:
      return nullptr;
  }
}

Child_EventSender::~Child_EventSender() = default;

Child_Sync::~Child_Sync() = default;

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

Child_Proxy::~Child_Proxy() = default;

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

void Child_Proxy::First(::fidl::InterfaceRequest<::test::inheritancewithrecursivedecl::Parent> request) {
  ::fidl::MessageEncoder _encoder(::test::inheritancewithrecursivedecl::internal::kChild_First_Ordinal, ::test::inheritancewithrecursivedecl::internal::kChild_First_DynamicFlags);
  const fidl_type_t* req_type = &::test::inheritancewithrecursivedecl::_internal::test_inheritancewithrecursivedecl_ParentFirstRequestTable;
  controller_->Send(req_type, ::test::inheritancewithrecursivedecl::Child_RequestEncoder::First(&_encoder, &request), nullptr);
}
void Child_Proxy::Second(::fidl::InterfaceRequest<::test::inheritancewithrecursivedecl::Parent> request) {
  ::fidl::MessageEncoder _encoder(::test::inheritancewithrecursivedecl::internal::kChild_Second_Ordinal, ::test::inheritancewithrecursivedecl::internal::kChild_Second_DynamicFlags);
  const fidl_type_t* req_type = &::test::inheritancewithrecursivedecl::_internal::test_inheritancewithrecursivedecl_ChildSecondRequestTable;
  controller_->Send(req_type, ::test::inheritancewithrecursivedecl::Child_RequestEncoder::Second(&_encoder, &request), nullptr);
}

Child_Stub::Child_Stub(::test::inheritancewithrecursivedecl::Child_Stub::Child_clazz* impl) : impl_(impl) {
  (void)impl_;
}

Child_Stub::~Child_Stub() = default;

namespace {

}  // namespace

zx_status_t Child_Stub::Dispatch_(
    ::fidl::HLCPPIncomingMessage message,
    ::fidl::internal::PendingResponse response) {
  bool needs_response;
  const fidl_type_t* request_type = ::test::inheritancewithrecursivedecl::Child_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::inheritancewithrecursivedecl::internal::kChild_First_Ordinal: {
      ::fidl::Decoder decoder(std::move(message));
      impl_->First(::fidl::DecodeAs<::fidl::InterfaceRequest<::test::inheritancewithrecursivedecl::Parent>>(&decoder, 0 + sizeof(fidl_message_header_t)));
      break;
    }
    case ::test::inheritancewithrecursivedecl::internal::kChild_Second_Ordinal: {
      ::fidl::Decoder decoder(std::move(message));
      impl_->Second(::fidl::DecodeAs<::fidl::InterfaceRequest<::test::inheritancewithrecursivedecl::Parent>>(&decoder, 0 + sizeof(fidl_message_header_t)));
      break;
    }
    default: {
      return ZX_ERR_NOT_SUPPORTED;
    }
  }
  return ZX_OK;
}

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

Child_SyncProxy::~Child_SyncProxy() = default;

zx_status_t Child_SyncProxy::First(::fidl::InterfaceRequest<::test::inheritancewithrecursivedecl::Parent> request) {
  ::fidl::MessageEncoder _encoder(::test::inheritancewithrecursivedecl::internal::kChild_First_Ordinal, ::test::inheritancewithrecursivedecl::internal::kChild_First_DynamicFlags);
  const fidl_type_t* req_type = &::test::inheritancewithrecursivedecl::_internal::test_inheritancewithrecursivedecl_ParentFirstRequestTable;
  return proxy_.Send(req_type, ::test::inheritancewithrecursivedecl::Child_RequestEncoder::First(&_encoder, &request));
}

zx_status_t Child_SyncProxy::Second(::fidl::InterfaceRequest<::test::inheritancewithrecursivedecl::Parent> request) {
  ::fidl::MessageEncoder _encoder(::test::inheritancewithrecursivedecl::internal::kChild_Second_Ordinal, ::test::inheritancewithrecursivedecl::internal::kChild_Second_DynamicFlags);
  const fidl_type_t* req_type = &::test::inheritancewithrecursivedecl::_internal::test_inheritancewithrecursivedecl_ChildSecondRequestTable;
  return proxy_.Send(req_type, ::test::inheritancewithrecursivedecl::Child_RequestEncoder::Second(&_encoder, &request));
}
#endif  // __Fuchsia__

}  // namespace inheritancewithrecursivedecl
}  // namespace test
