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

#include <fuchsia/paver/llcpp/fidl.h>
#include <memory>

namespace llcpp {

namespace fuchsia {
namespace paver {

::llcpp::fuchsia::paver::ReadResult::ReadResult() {
  tag_ = Tag::Invalid;
}

::llcpp::fuchsia::paver::ReadResult::~ReadResult() {
  Destroy();
}

void ::llcpp::fuchsia::paver::ReadResult::Destroy() {
  switch (which()) {
  case Tag::kInfo:
    info_.~ReadInfo();
    break;
  default:
    break;
  }
  tag_ = Tag::Invalid;
}

void ::llcpp::fuchsia::paver::ReadResult::MoveImpl_(ReadResult&& other) {
  switch (other.which()) {
  case Tag::kErr:
    mutable_err() = std::move(other.mutable_err());
    break;
  case Tag::kEof:
    mutable_eof() = std::move(other.mutable_eof());
    break;
  case Tag::kInfo:
    mutable_info() = std::move(other.mutable_info());
    break;
  default:
    break;
  }
  other.Destroy();
}

void ::llcpp::fuchsia::paver::ReadResult::SizeAndOffsetAssertionHelper() {
  static_assert(offsetof(::llcpp::fuchsia::paver::ReadResult, err_) == 8);
  static_assert(offsetof(::llcpp::fuchsia::paver::ReadResult, eof_) == 8);
  static_assert(offsetof(::llcpp::fuchsia::paver::ReadResult, info_) == 8);
  static_assert(sizeof(::llcpp::fuchsia::paver::ReadResult) == ::llcpp::fuchsia::paver::ReadResult::PrimarySize);
}


int32_t& ::llcpp::fuchsia::paver::ReadResult::mutable_err() {
  if (which() != Tag::kErr) {
    Destroy();
    new (&err_) int32_t;
  }
  tag_ = Tag::kErr;
  return err_;
}

bool& ::llcpp::fuchsia::paver::ReadResult::mutable_eof() {
  if (which() != Tag::kEof) {
    Destroy();
    new (&eof_) bool;
  }
  tag_ = Tag::kEof;
  return eof_;
}

ReadInfo& ::llcpp::fuchsia::paver::ReadResult::mutable_info() {
  if (which() != Tag::kInfo) {
    Destroy();
    new (&info_) ReadInfo;
  }
  tag_ = Tag::kInfo;
  return info_;
}


namespace {

[[maybe_unused]]
constexpr uint64_t kPayloadStream_RegisterVmo_Ordinal = 272943321lu << 32;
extern "C" const fidl_type_t fuchsia_paver_PayloadStreamRegisterVmoRequestTable;
extern "C" const fidl_type_t fuchsia_paver_PayloadStreamRegisterVmoResponseTable;
[[maybe_unused]]
constexpr uint64_t kPayloadStream_ReadData_Ordinal = 741764662lu << 32;
extern "C" const fidl_type_t fuchsia_paver_PayloadStreamReadDataResponseTable;

}  // namespace

zx_status_t PayloadStream::SyncClient::RegisterVmo(::zx::vmo vmo, int32_t* out_status) {
  return PayloadStream::Call::RegisterVmo(zx::unowned_channel(this->channel_), std::move(vmo), out_status);
}

zx_status_t PayloadStream::Call::RegisterVmo(zx::unowned_channel _client_end, ::zx::vmo vmo, int32_t* out_status) {
  constexpr uint32_t _kWriteAllocSize = ::fidl::internal::ClampedMessageSize<RegisterVmoRequest>();
  FIDL_ALIGNDECL uint8_t _write_bytes[_kWriteAllocSize] = {};
  auto& _request = *reinterpret_cast<RegisterVmoRequest*>(_write_bytes);
  _request._hdr.ordinal = kPayloadStream_RegisterVmo_Ordinal;
  _request.vmo = std::move(vmo);
  ::fidl::BytePart _request_bytes(_write_bytes, _kWriteAllocSize, sizeof(RegisterVmoRequest));
  ::fidl::DecodedMessage<RegisterVmoRequest> _decoded_request(std::move(_request_bytes));
  auto _encode_request_result = ::fidl::Encode(std::move(_decoded_request));
  if (_encode_request_result.status != ZX_OK) {
    return _encode_request_result.status;
  }
  constexpr uint32_t _kReadAllocSize = ::fidl::internal::ClampedMessageSize<RegisterVmoResponse>();
  FIDL_ALIGNDECL uint8_t _read_bytes[_kReadAllocSize];
  ::fidl::BytePart _response_bytes(_read_bytes, _kReadAllocSize);
  auto _call_result = ::fidl::Call<RegisterVmoRequest, RegisterVmoResponse>(
    std::move(_client_end), std::move(_encode_request_result.message), std::move(_response_bytes));
  if (_call_result.status != ZX_OK) {
    return _call_result.status;
  }
  auto _decode_result = ::fidl::Decode(std::move(_call_result.message));
  if (_decode_result.status != ZX_OK) {
    return _decode_result.status;
  }
  auto& _response = *_decode_result.message.message();
  *out_status = std::move(_response.status);
  return ZX_OK;
}

::fidl::DecodeResult<PayloadStream::RegisterVmoResponse> PayloadStream::SyncClient::RegisterVmo(::fidl::BytePart _request_buffer, ::zx::vmo vmo, ::fidl::BytePart _response_buffer, int32_t* out_status) {
  return PayloadStream::Call::RegisterVmo(zx::unowned_channel(this->channel_), std::move(_request_buffer), std::move(vmo), std::move(_response_buffer), out_status);
}

::fidl::DecodeResult<PayloadStream::RegisterVmoResponse> PayloadStream::Call::RegisterVmo(zx::unowned_channel _client_end, ::fidl::BytePart _request_buffer, ::zx::vmo vmo, ::fidl::BytePart _response_buffer, int32_t* out_status) {
  if (_request_buffer.capacity() < RegisterVmoRequest::PrimarySize) {
    return ::fidl::DecodeResult<RegisterVmoResponse>(ZX_ERR_BUFFER_TOO_SMALL, ::fidl::internal::kErrorRequestBufferTooSmall);
  }
  auto& _request = *reinterpret_cast<RegisterVmoRequest*>(_request_buffer.data());
  _request._hdr.ordinal = kPayloadStream_RegisterVmo_Ordinal;
  _request.vmo = std::move(vmo);
  _request_buffer.set_actual(sizeof(RegisterVmoRequest));
  ::fidl::DecodedMessage<RegisterVmoRequest> _decoded_request(std::move(_request_buffer));
  auto _encode_request_result = ::fidl::Encode(std::move(_decoded_request));
  if (_encode_request_result.status != ZX_OK) {
    return ::fidl::DecodeResult<RegisterVmoResponse>(_encode_request_result.status, _encode_request_result.error);
  }
  auto _call_result = ::fidl::Call<RegisterVmoRequest, RegisterVmoResponse>(
    std::move(_client_end), std::move(_encode_request_result.message), std::move(_response_buffer));
  if (_call_result.status != ZX_OK) {
    return ::fidl::DecodeResult<RegisterVmoResponse>(_call_result.status, _call_result.error);
  }
  auto _decode_result = ::fidl::Decode(std::move(_call_result.message));
  if (_decode_result.status != ZX_OK) {
    return _decode_result;
  }
  auto& _response = *_decode_result.message.message();
  *out_status = std::move(_response.status);
  return _decode_result;
}

::fidl::DecodeResult<PayloadStream::RegisterVmoResponse> PayloadStream::SyncClient::RegisterVmo(::fidl::DecodedMessage<RegisterVmoRequest> params, ::fidl::BytePart response_buffer) {
  return PayloadStream::Call::RegisterVmo(zx::unowned_channel(this->channel_), std::move(params), std::move(response_buffer));
}

::fidl::DecodeResult<PayloadStream::RegisterVmoResponse> PayloadStream::Call::RegisterVmo(zx::unowned_channel _client_end, ::fidl::DecodedMessage<RegisterVmoRequest> params, ::fidl::BytePart response_buffer) {
  params.message()->_hdr = {};
  params.message()->_hdr.ordinal = kPayloadStream_RegisterVmo_Ordinal;
  auto _encode_request_result = ::fidl::Encode(std::move(params));
  if (_encode_request_result.status != ZX_OK) {
    return ::fidl::DecodeResult<PayloadStream::RegisterVmoResponse>(
      _encode_request_result.status,
      _encode_request_result.error,
      ::fidl::DecodedMessage<PayloadStream::RegisterVmoResponse>());
  }
  auto _call_result = ::fidl::Call<RegisterVmoRequest, RegisterVmoResponse>(
    std::move(_client_end), std::move(_encode_request_result.message), std::move(response_buffer));
  if (_call_result.status != ZX_OK) {
    return ::fidl::DecodeResult<PayloadStream::RegisterVmoResponse>(
      _call_result.status,
      _call_result.error,
      ::fidl::DecodedMessage<PayloadStream::RegisterVmoResponse>());
  }
  return ::fidl::Decode(std::move(_call_result.message));
}


zx_status_t PayloadStream::SyncClient::ReadData(ReadResult* out_result) {
  return PayloadStream::Call::ReadData(zx::unowned_channel(this->channel_), out_result);
}

zx_status_t PayloadStream::Call::ReadData(zx::unowned_channel _client_end, ReadResult* out_result) {
  constexpr uint32_t _kWriteAllocSize = ::fidl::internal::ClampedMessageSize<ReadDataRequest>();
  FIDL_ALIGNDECL uint8_t _write_bytes[_kWriteAllocSize] = {};
  auto& _request = *reinterpret_cast<ReadDataRequest*>(_write_bytes);
  _request._hdr.ordinal = kPayloadStream_ReadData_Ordinal;
  ::fidl::BytePart _request_bytes(_write_bytes, _kWriteAllocSize, sizeof(ReadDataRequest));
  ::fidl::DecodedMessage<ReadDataRequest> _decoded_request(std::move(_request_bytes));
  auto _encode_request_result = ::fidl::Encode(std::move(_decoded_request));
  if (_encode_request_result.status != ZX_OK) {
    return _encode_request_result.status;
  }
  constexpr uint32_t _kReadAllocSize = ::fidl::internal::ClampedMessageSize<ReadDataResponse>();
  FIDL_ALIGNDECL uint8_t _read_bytes[_kReadAllocSize];
  ::fidl::BytePart _response_bytes(_read_bytes, _kReadAllocSize);
  auto _call_result = ::fidl::Call<ReadDataRequest, ReadDataResponse>(
    std::move(_client_end), std::move(_encode_request_result.message), std::move(_response_bytes));
  if (_call_result.status != ZX_OK) {
    return _call_result.status;
  }
  auto _decode_result = ::fidl::Decode(std::move(_call_result.message));
  if (_decode_result.status != ZX_OK) {
    return _decode_result.status;
  }
  auto& _response = *_decode_result.message.message();
  *out_result = std::move(_response.result);
  return ZX_OK;
}

::fidl::DecodeResult<PayloadStream::ReadDataResponse> PayloadStream::SyncClient::ReadData(::fidl::BytePart _response_buffer, ReadResult* out_result) {
  return PayloadStream::Call::ReadData(zx::unowned_channel(this->channel_), std::move(_response_buffer), out_result);
}

::fidl::DecodeResult<PayloadStream::ReadDataResponse> PayloadStream::Call::ReadData(zx::unowned_channel _client_end, ::fidl::BytePart _response_buffer, ReadResult* out_result) {
  FIDL_ALIGNDECL uint8_t _write_bytes[sizeof(ReadDataRequest)] = {};
  ::fidl::BytePart _request_buffer(_write_bytes, sizeof(_write_bytes));
  auto& _request = *reinterpret_cast<ReadDataRequest*>(_request_buffer.data());
  _request._hdr.ordinal = kPayloadStream_ReadData_Ordinal;
  _request_buffer.set_actual(sizeof(ReadDataRequest));
  ::fidl::DecodedMessage<ReadDataRequest> _decoded_request(std::move(_request_buffer));
  auto _encode_request_result = ::fidl::Encode(std::move(_decoded_request));
  if (_encode_request_result.status != ZX_OK) {
    return ::fidl::DecodeResult<ReadDataResponse>(_encode_request_result.status, _encode_request_result.error);
  }
  auto _call_result = ::fidl::Call<ReadDataRequest, ReadDataResponse>(
    std::move(_client_end), std::move(_encode_request_result.message), std::move(_response_buffer));
  if (_call_result.status != ZX_OK) {
    return ::fidl::DecodeResult<ReadDataResponse>(_call_result.status, _call_result.error);
  }
  auto _decode_result = ::fidl::Decode(std::move(_call_result.message));
  if (_decode_result.status != ZX_OK) {
    return _decode_result;
  }
  auto& _response = *_decode_result.message.message();
  *out_result = std::move(_response.result);
  return _decode_result;
}

::fidl::DecodeResult<PayloadStream::ReadDataResponse> PayloadStream::SyncClient::ReadData(::fidl::BytePart response_buffer) {
  return PayloadStream::Call::ReadData(zx::unowned_channel(this->channel_), std::move(response_buffer));
}

::fidl::DecodeResult<PayloadStream::ReadDataResponse> PayloadStream::Call::ReadData(zx::unowned_channel _client_end, ::fidl::BytePart response_buffer) {
  FIDL_ALIGNDECL uint8_t _write_bytes[sizeof(ReadDataRequest)] = {};
  constexpr uint32_t _write_num_bytes = sizeof(ReadDataRequest);
  ::fidl::BytePart _request_buffer(_write_bytes, sizeof(_write_bytes), _write_num_bytes);
  ::fidl::DecodedMessage<ReadDataRequest> params(std::move(_request_buffer));
  params.message()->_hdr = {};
  params.message()->_hdr.ordinal = kPayloadStream_ReadData_Ordinal;
  auto _encode_request_result = ::fidl::Encode(std::move(params));
  if (_encode_request_result.status != ZX_OK) {
    return ::fidl::DecodeResult<PayloadStream::ReadDataResponse>(
      _encode_request_result.status,
      _encode_request_result.error,
      ::fidl::DecodedMessage<PayloadStream::ReadDataResponse>());
  }
  auto _call_result = ::fidl::Call<ReadDataRequest, ReadDataResponse>(
    std::move(_client_end), std::move(_encode_request_result.message), std::move(response_buffer));
  if (_call_result.status != ZX_OK) {
    return ::fidl::DecodeResult<PayloadStream::ReadDataResponse>(
      _call_result.status,
      _call_result.error,
      ::fidl::DecodedMessage<PayloadStream::ReadDataResponse>());
  }
  return ::fidl::Decode(std::move(_call_result.message));
}


bool PayloadStream::TryDispatch(Interface* impl, fidl_msg_t* msg, ::fidl::Transaction* txn) {
  if (msg->num_bytes < sizeof(fidl_message_header_t)) {
    zx_handle_close_many(msg->handles, msg->num_handles);
    txn->Close(ZX_ERR_INVALID_ARGS);
    return true;
  }
  fidl_message_header_t* hdr = reinterpret_cast<fidl_message_header_t*>(msg->bytes);
  switch (hdr->ordinal) {
    case kPayloadStream_RegisterVmo_Ordinal: {
      auto result = ::fidl::DecodeAs<RegisterVmoRequest>(msg);
      if (result.status != ZX_OK) {
        txn->Close(ZX_ERR_INVALID_ARGS);
        return true;
      }
      auto message = result.message.message();
      impl->RegisterVmo(std::move(message->vmo),
        Interface::RegisterVmoCompleter::Sync(txn));
      return true;
    }
    case kPayloadStream_ReadData_Ordinal: {
      auto result = ::fidl::DecodeAs<ReadDataRequest>(msg);
      if (result.status != ZX_OK) {
        txn->Close(ZX_ERR_INVALID_ARGS);
        return true;
      }
      impl->ReadData(
        Interface::ReadDataCompleter::Sync(txn));
      return true;
    }
    default: {
      return false;
    }
  }
}

bool PayloadStream::Dispatch(Interface* impl, fidl_msg_t* msg, ::fidl::Transaction* txn) {
  bool found = TryDispatch(impl, msg, txn);
  if (!found) {
    zx_handle_close_many(msg->handles, msg->num_handles);
    txn->Close(ZX_ERR_NOT_SUPPORTED);
  }
  return found;
}


void PayloadStream::Interface::RegisterVmoCompleterBase::Reply(int32_t status) {
  constexpr uint32_t _kWriteAllocSize = ::fidl::internal::ClampedMessageSize<RegisterVmoResponse>();
  FIDL_ALIGNDECL uint8_t _write_bytes[_kWriteAllocSize] = {};
  auto& _response = *reinterpret_cast<RegisterVmoResponse*>(_write_bytes);
  _response._hdr.ordinal = kPayloadStream_RegisterVmo_Ordinal;
  _response.status = std::move(status);
  ::fidl::BytePart _response_bytes(_write_bytes, _kWriteAllocSize, sizeof(RegisterVmoResponse));
  CompleterBase::SendReply(::fidl::DecodedMessage<RegisterVmoResponse>(std::move(_response_bytes)));
}

void PayloadStream::Interface::RegisterVmoCompleterBase::Reply(::fidl::BytePart _buffer, int32_t status) {
  if (_buffer.capacity() < RegisterVmoResponse::PrimarySize) {
    CompleterBase::Close(ZX_ERR_INTERNAL);
    return;
  }
  auto& _response = *reinterpret_cast<RegisterVmoResponse*>(_buffer.data());
  _response._hdr.ordinal = kPayloadStream_RegisterVmo_Ordinal;
  _response.status = std::move(status);
  _buffer.set_actual(sizeof(RegisterVmoResponse));
  CompleterBase::SendReply(::fidl::DecodedMessage<RegisterVmoResponse>(std::move(_buffer)));
}

void PayloadStream::Interface::RegisterVmoCompleterBase::Reply(::fidl::DecodedMessage<RegisterVmoResponse> params) {
  params.message()->_hdr = {};
  params.message()->_hdr.ordinal = kPayloadStream_RegisterVmo_Ordinal;
  CompleterBase::SendReply(std::move(params));
}


void PayloadStream::Interface::ReadDataCompleterBase::Reply(ReadResult result) {
  constexpr uint32_t _kWriteAllocSize = ::fidl::internal::ClampedMessageSize<ReadDataResponse>();
  FIDL_ALIGNDECL uint8_t _write_bytes[_kWriteAllocSize] = {};
  auto& _response = *reinterpret_cast<ReadDataResponse*>(_write_bytes);
  _response._hdr.ordinal = kPayloadStream_ReadData_Ordinal;
  _response.result = std::move(result);
  ::fidl::BytePart _response_bytes(_write_bytes, _kWriteAllocSize, sizeof(ReadDataResponse));
  CompleterBase::SendReply(::fidl::DecodedMessage<ReadDataResponse>(std::move(_response_bytes)));
}

void PayloadStream::Interface::ReadDataCompleterBase::Reply(::fidl::BytePart _buffer, ReadResult result) {
  if (_buffer.capacity() < ReadDataResponse::PrimarySize) {
    CompleterBase::Close(ZX_ERR_INTERNAL);
    return;
  }
  auto& _response = *reinterpret_cast<ReadDataResponse*>(_buffer.data());
  _response._hdr.ordinal = kPayloadStream_ReadData_Ordinal;
  _response.result = std::move(result);
  _buffer.set_actual(sizeof(ReadDataResponse));
  CompleterBase::SendReply(::fidl::DecodedMessage<ReadDataResponse>(std::move(_buffer)));
}

void PayloadStream::Interface::ReadDataCompleterBase::Reply(::fidl::DecodedMessage<ReadDataResponse> params) {
  params.message()->_hdr = {};
  params.message()->_hdr.ordinal = kPayloadStream_ReadData_Ordinal;
  CompleterBase::SendReply(std::move(params));
}


::llcpp::fuchsia::paver::Paver_QueryActiveConfiguration_Result::Paver_QueryActiveConfiguration_Result() {
  tag_ = Tag::Invalid;
}

::llcpp::fuchsia::paver::Paver_QueryActiveConfiguration_Result::~Paver_QueryActiveConfiguration_Result() {
  Destroy();
}

void ::llcpp::fuchsia::paver::Paver_QueryActiveConfiguration_Result::Destroy() {
  switch (which()) {
  case Tag::kResponse:
    response_.~Paver_QueryActiveConfiguration_Response();
    break;
  default:
    break;
  }
  tag_ = Tag::Invalid;
}

void ::llcpp::fuchsia::paver::Paver_QueryActiveConfiguration_Result::MoveImpl_(Paver_QueryActiveConfiguration_Result&& other) {
  switch (other.which()) {
  case Tag::kResponse:
    mutable_response() = std::move(other.mutable_response());
    break;
  case Tag::kErr:
    mutable_err() = std::move(other.mutable_err());
    break;
  default:
    break;
  }
  other.Destroy();
}

void ::llcpp::fuchsia::paver::Paver_QueryActiveConfiguration_Result::SizeAndOffsetAssertionHelper() {
  static_assert(offsetof(::llcpp::fuchsia::paver::Paver_QueryActiveConfiguration_Result, response_) == 4);
  static_assert(offsetof(::llcpp::fuchsia::paver::Paver_QueryActiveConfiguration_Result, err_) == 4);
  static_assert(sizeof(::llcpp::fuchsia::paver::Paver_QueryActiveConfiguration_Result) == ::llcpp::fuchsia::paver::Paver_QueryActiveConfiguration_Result::PrimarySize);
}


Paver_QueryActiveConfiguration_Response& ::llcpp::fuchsia::paver::Paver_QueryActiveConfiguration_Result::mutable_response() {
  if (which() != Tag::kResponse) {
    Destroy();
    new (&response_) Paver_QueryActiveConfiguration_Response;
  }
  tag_ = Tag::kResponse;
  return response_;
}

int32_t& ::llcpp::fuchsia::paver::Paver_QueryActiveConfiguration_Result::mutable_err() {
  if (which() != Tag::kErr) {
    Destroy();
    new (&err_) int32_t;
  }
  tag_ = Tag::kErr;
  return err_;
}


namespace {

[[maybe_unused]]
constexpr uint64_t kPaver_QueryActiveConfiguration_Ordinal = 1134945427lu << 32;
[[maybe_unused]]
constexpr uint64_t kPaver_SetActiveConfiguration_Ordinal = 604066686lu << 32;
extern "C" const fidl_type_t fuchsia_paver_PaverSetActiveConfigurationRequestTable;
extern "C" const fidl_type_t fuchsia_paver_PaverSetActiveConfigurationResponseTable;
[[maybe_unused]]
constexpr uint64_t kPaver_MarkActiveConfigurationSuccessful_Ordinal = 646268842lu << 32;
extern "C" const fidl_type_t fuchsia_paver_PaverMarkActiveConfigurationSuccessfulResponseTable;
[[maybe_unused]]
constexpr uint64_t kPaver_ForceRecoveryConfiguration_Ordinal = 959881446lu << 32;
extern "C" const fidl_type_t fuchsia_paver_PaverForceRecoveryConfigurationResponseTable;
[[maybe_unused]]
constexpr uint64_t kPaver_WriteAsset_Ordinal = 1780273052lu << 32;
extern "C" const fidl_type_t fuchsia_paver_PaverWriteAssetRequestTable;
extern "C" const fidl_type_t fuchsia_paver_PaverWriteAssetResponseTable;
[[maybe_unused]]
constexpr uint64_t kPaver_WriteVolumes_Ordinal = 1907609382lu << 32;
extern "C" const fidl_type_t fuchsia_paver_PaverWriteVolumesRequestTable;
extern "C" const fidl_type_t fuchsia_paver_PaverWriteVolumesResponseTable;
[[maybe_unused]]
constexpr uint64_t kPaver_WriteBootloader_Ordinal = 1265344886lu << 32;
extern "C" const fidl_type_t fuchsia_paver_PaverWriteBootloaderRequestTable;
extern "C" const fidl_type_t fuchsia_paver_PaverWriteBootloaderResponseTable;
[[maybe_unused]]
constexpr uint64_t kPaver_WriteDataFile_Ordinal = 2072261598lu << 32;
extern "C" const fidl_type_t fuchsia_paver_PaverWriteDataFileRequestTable;
extern "C" const fidl_type_t fuchsia_paver_PaverWriteDataFileResponseTable;
[[maybe_unused]]
constexpr uint64_t kPaver_WipeVolumes_Ordinal = 113153696lu << 32;
extern "C" const fidl_type_t fuchsia_paver_PaverWipeVolumesResponseTable;

}  // namespace

zx_status_t Paver::SyncClient::QueryActiveConfiguration(Paver_QueryActiveConfiguration_Result* out_result) {
  return Paver::Call::QueryActiveConfiguration(zx::unowned_channel(this->channel_), out_result);
}

zx_status_t Paver::Call::QueryActiveConfiguration(zx::unowned_channel _client_end, Paver_QueryActiveConfiguration_Result* out_result) {
  constexpr uint32_t _kWriteAllocSize = ::fidl::internal::ClampedMessageSize<QueryActiveConfigurationRequest>();
  FIDL_ALIGNDECL uint8_t _write_bytes[_kWriteAllocSize] = {};
  auto& _request = *reinterpret_cast<QueryActiveConfigurationRequest*>(_write_bytes);
  _request._hdr.ordinal = kPaver_QueryActiveConfiguration_Ordinal;
  ::fidl::BytePart _request_bytes(_write_bytes, _kWriteAllocSize, sizeof(QueryActiveConfigurationRequest));
  ::fidl::DecodedMessage<QueryActiveConfigurationRequest> _decoded_request(std::move(_request_bytes));
  auto _encode_request_result = ::fidl::Encode(std::move(_decoded_request));
  if (_encode_request_result.status != ZX_OK) {
    return _encode_request_result.status;
  }
  constexpr uint32_t _kReadAllocSize = ::fidl::internal::ClampedMessageSize<QueryActiveConfigurationResponse>();
  FIDL_ALIGNDECL uint8_t _read_bytes[_kReadAllocSize];
  ::fidl::BytePart _response_bytes(_read_bytes, _kReadAllocSize);
  auto _call_result = ::fidl::Call<QueryActiveConfigurationRequest, QueryActiveConfigurationResponse>(
    std::move(_client_end), std::move(_encode_request_result.message), std::move(_response_bytes));
  if (_call_result.status != ZX_OK) {
    return _call_result.status;
  }
  auto _decode_result = ::fidl::Decode(std::move(_call_result.message));
  if (_decode_result.status != ZX_OK) {
    return _decode_result.status;
  }
  auto& _response = *_decode_result.message.message();
  *out_result = std::move(_response.result);
  return ZX_OK;
}

::fidl::DecodeResult<Paver::QueryActiveConfigurationResponse> Paver::SyncClient::QueryActiveConfiguration(::fidl::BytePart _response_buffer, Paver_QueryActiveConfiguration_Result* out_result) {
  return Paver::Call::QueryActiveConfiguration(zx::unowned_channel(this->channel_), std::move(_response_buffer), out_result);
}

::fidl::DecodeResult<Paver::QueryActiveConfigurationResponse> Paver::Call::QueryActiveConfiguration(zx::unowned_channel _client_end, ::fidl::BytePart _response_buffer, Paver_QueryActiveConfiguration_Result* out_result) {
  FIDL_ALIGNDECL uint8_t _write_bytes[sizeof(QueryActiveConfigurationRequest)] = {};
  ::fidl::BytePart _request_buffer(_write_bytes, sizeof(_write_bytes));
  auto& _request = *reinterpret_cast<QueryActiveConfigurationRequest*>(_request_buffer.data());
  _request._hdr.ordinal = kPaver_QueryActiveConfiguration_Ordinal;
  _request_buffer.set_actual(sizeof(QueryActiveConfigurationRequest));
  ::fidl::DecodedMessage<QueryActiveConfigurationRequest> _decoded_request(std::move(_request_buffer));
  auto _encode_request_result = ::fidl::Encode(std::move(_decoded_request));
  if (_encode_request_result.status != ZX_OK) {
    return ::fidl::DecodeResult<QueryActiveConfigurationResponse>(_encode_request_result.status, _encode_request_result.error);
  }
  auto _call_result = ::fidl::Call<QueryActiveConfigurationRequest, QueryActiveConfigurationResponse>(
    std::move(_client_end), std::move(_encode_request_result.message), std::move(_response_buffer));
  if (_call_result.status != ZX_OK) {
    return ::fidl::DecodeResult<QueryActiveConfigurationResponse>(_call_result.status, _call_result.error);
  }
  auto _decode_result = ::fidl::Decode(std::move(_call_result.message));
  if (_decode_result.status != ZX_OK) {
    return _decode_result;
  }
  auto& _response = *_decode_result.message.message();
  *out_result = std::move(_response.result);
  return _decode_result;
}

::fidl::DecodeResult<Paver::QueryActiveConfigurationResponse> Paver::SyncClient::QueryActiveConfiguration(::fidl::BytePart response_buffer) {
  return Paver::Call::QueryActiveConfiguration(zx::unowned_channel(this->channel_), std::move(response_buffer));
}

::fidl::DecodeResult<Paver::QueryActiveConfigurationResponse> Paver::Call::QueryActiveConfiguration(zx::unowned_channel _client_end, ::fidl::BytePart response_buffer) {
  FIDL_ALIGNDECL uint8_t _write_bytes[sizeof(QueryActiveConfigurationRequest)] = {};
  constexpr uint32_t _write_num_bytes = sizeof(QueryActiveConfigurationRequest);
  ::fidl::BytePart _request_buffer(_write_bytes, sizeof(_write_bytes), _write_num_bytes);
  ::fidl::DecodedMessage<QueryActiveConfigurationRequest> params(std::move(_request_buffer));
  params.message()->_hdr = {};
  params.message()->_hdr.ordinal = kPaver_QueryActiveConfiguration_Ordinal;
  auto _encode_request_result = ::fidl::Encode(std::move(params));
  if (_encode_request_result.status != ZX_OK) {
    return ::fidl::DecodeResult<Paver::QueryActiveConfigurationResponse>(
      _encode_request_result.status,
      _encode_request_result.error,
      ::fidl::DecodedMessage<Paver::QueryActiveConfigurationResponse>());
  }
  auto _call_result = ::fidl::Call<QueryActiveConfigurationRequest, QueryActiveConfigurationResponse>(
    std::move(_client_end), std::move(_encode_request_result.message), std::move(response_buffer));
  if (_call_result.status != ZX_OK) {
    return ::fidl::DecodeResult<Paver::QueryActiveConfigurationResponse>(
      _call_result.status,
      _call_result.error,
      ::fidl::DecodedMessage<Paver::QueryActiveConfigurationResponse>());
  }
  return ::fidl::Decode(std::move(_call_result.message));
}


zx_status_t Paver::SyncClient::SetActiveConfiguration(Configuration configuration, int32_t* out_status) {
  return Paver::Call::SetActiveConfiguration(zx::unowned_channel(this->channel_), std::move(configuration), out_status);
}

zx_status_t Paver::Call::SetActiveConfiguration(zx::unowned_channel _client_end, Configuration configuration, int32_t* out_status) {
  constexpr uint32_t _kWriteAllocSize = ::fidl::internal::ClampedMessageSize<SetActiveConfigurationRequest>();
  FIDL_ALIGNDECL uint8_t _write_bytes[_kWriteAllocSize] = {};
  auto& _request = *reinterpret_cast<SetActiveConfigurationRequest*>(_write_bytes);
  _request._hdr.ordinal = kPaver_SetActiveConfiguration_Ordinal;
  _request.configuration = std::move(configuration);
  ::fidl::BytePart _request_bytes(_write_bytes, _kWriteAllocSize, sizeof(SetActiveConfigurationRequest));
  ::fidl::DecodedMessage<SetActiveConfigurationRequest> _decoded_request(std::move(_request_bytes));
  auto _encode_request_result = ::fidl::Encode(std::move(_decoded_request));
  if (_encode_request_result.status != ZX_OK) {
    return _encode_request_result.status;
  }
  constexpr uint32_t _kReadAllocSize = ::fidl::internal::ClampedMessageSize<SetActiveConfigurationResponse>();
  FIDL_ALIGNDECL uint8_t _read_bytes[_kReadAllocSize];
  ::fidl::BytePart _response_bytes(_read_bytes, _kReadAllocSize);
  auto _call_result = ::fidl::Call<SetActiveConfigurationRequest, SetActiveConfigurationResponse>(
    std::move(_client_end), std::move(_encode_request_result.message), std::move(_response_bytes));
  if (_call_result.status != ZX_OK) {
    return _call_result.status;
  }
  auto _decode_result = ::fidl::Decode(std::move(_call_result.message));
  if (_decode_result.status != ZX_OK) {
    return _decode_result.status;
  }
  auto& _response = *_decode_result.message.message();
  *out_status = std::move(_response.status);
  return ZX_OK;
}

::fidl::DecodeResult<Paver::SetActiveConfigurationResponse> Paver::SyncClient::SetActiveConfiguration(::fidl::BytePart _request_buffer, Configuration configuration, ::fidl::BytePart _response_buffer, int32_t* out_status) {
  return Paver::Call::SetActiveConfiguration(zx::unowned_channel(this->channel_), std::move(_request_buffer), std::move(configuration), std::move(_response_buffer), out_status);
}

::fidl::DecodeResult<Paver::SetActiveConfigurationResponse> Paver::Call::SetActiveConfiguration(zx::unowned_channel _client_end, ::fidl::BytePart _request_buffer, Configuration configuration, ::fidl::BytePart _response_buffer, int32_t* out_status) {
  if (_request_buffer.capacity() < SetActiveConfigurationRequest::PrimarySize) {
    return ::fidl::DecodeResult<SetActiveConfigurationResponse>(ZX_ERR_BUFFER_TOO_SMALL, ::fidl::internal::kErrorRequestBufferTooSmall);
  }
  auto& _request = *reinterpret_cast<SetActiveConfigurationRequest*>(_request_buffer.data());
  _request._hdr.ordinal = kPaver_SetActiveConfiguration_Ordinal;
  _request.configuration = std::move(configuration);
  _request_buffer.set_actual(sizeof(SetActiveConfigurationRequest));
  ::fidl::DecodedMessage<SetActiveConfigurationRequest> _decoded_request(std::move(_request_buffer));
  auto _encode_request_result = ::fidl::Encode(std::move(_decoded_request));
  if (_encode_request_result.status != ZX_OK) {
    return ::fidl::DecodeResult<SetActiveConfigurationResponse>(_encode_request_result.status, _encode_request_result.error);
  }
  auto _call_result = ::fidl::Call<SetActiveConfigurationRequest, SetActiveConfigurationResponse>(
    std::move(_client_end), std::move(_encode_request_result.message), std::move(_response_buffer));
  if (_call_result.status != ZX_OK) {
    return ::fidl::DecodeResult<SetActiveConfigurationResponse>(_call_result.status, _call_result.error);
  }
  auto _decode_result = ::fidl::Decode(std::move(_call_result.message));
  if (_decode_result.status != ZX_OK) {
    return _decode_result;
  }
  auto& _response = *_decode_result.message.message();
  *out_status = std::move(_response.status);
  return _decode_result;
}

::fidl::DecodeResult<Paver::SetActiveConfigurationResponse> Paver::SyncClient::SetActiveConfiguration(::fidl::DecodedMessage<SetActiveConfigurationRequest> params, ::fidl::BytePart response_buffer) {
  return Paver::Call::SetActiveConfiguration(zx::unowned_channel(this->channel_), std::move(params), std::move(response_buffer));
}

::fidl::DecodeResult<Paver::SetActiveConfigurationResponse> Paver::Call::SetActiveConfiguration(zx::unowned_channel _client_end, ::fidl::DecodedMessage<SetActiveConfigurationRequest> params, ::fidl::BytePart response_buffer) {
  params.message()->_hdr = {};
  params.message()->_hdr.ordinal = kPaver_SetActiveConfiguration_Ordinal;
  auto _encode_request_result = ::fidl::Encode(std::move(params));
  if (_encode_request_result.status != ZX_OK) {
    return ::fidl::DecodeResult<Paver::SetActiveConfigurationResponse>(
      _encode_request_result.status,
      _encode_request_result.error,
      ::fidl::DecodedMessage<Paver::SetActiveConfigurationResponse>());
  }
  auto _call_result = ::fidl::Call<SetActiveConfigurationRequest, SetActiveConfigurationResponse>(
    std::move(_client_end), std::move(_encode_request_result.message), std::move(response_buffer));
  if (_call_result.status != ZX_OK) {
    return ::fidl::DecodeResult<Paver::SetActiveConfigurationResponse>(
      _call_result.status,
      _call_result.error,
      ::fidl::DecodedMessage<Paver::SetActiveConfigurationResponse>());
  }
  return ::fidl::Decode(std::move(_call_result.message));
}


zx_status_t Paver::SyncClient::MarkActiveConfigurationSuccessful(int32_t* out_status) {
  return Paver::Call::MarkActiveConfigurationSuccessful(zx::unowned_channel(this->channel_), out_status);
}

zx_status_t Paver::Call::MarkActiveConfigurationSuccessful(zx::unowned_channel _client_end, int32_t* out_status) {
  constexpr uint32_t _kWriteAllocSize = ::fidl::internal::ClampedMessageSize<MarkActiveConfigurationSuccessfulRequest>();
  FIDL_ALIGNDECL uint8_t _write_bytes[_kWriteAllocSize] = {};
  auto& _request = *reinterpret_cast<MarkActiveConfigurationSuccessfulRequest*>(_write_bytes);
  _request._hdr.ordinal = kPaver_MarkActiveConfigurationSuccessful_Ordinal;
  ::fidl::BytePart _request_bytes(_write_bytes, _kWriteAllocSize, sizeof(MarkActiveConfigurationSuccessfulRequest));
  ::fidl::DecodedMessage<MarkActiveConfigurationSuccessfulRequest> _decoded_request(std::move(_request_bytes));
  auto _encode_request_result = ::fidl::Encode(std::move(_decoded_request));
  if (_encode_request_result.status != ZX_OK) {
    return _encode_request_result.status;
  }
  constexpr uint32_t _kReadAllocSize = ::fidl::internal::ClampedMessageSize<MarkActiveConfigurationSuccessfulResponse>();
  FIDL_ALIGNDECL uint8_t _read_bytes[_kReadAllocSize];
  ::fidl::BytePart _response_bytes(_read_bytes, _kReadAllocSize);
  auto _call_result = ::fidl::Call<MarkActiveConfigurationSuccessfulRequest, MarkActiveConfigurationSuccessfulResponse>(
    std::move(_client_end), std::move(_encode_request_result.message), std::move(_response_bytes));
  if (_call_result.status != ZX_OK) {
    return _call_result.status;
  }
  auto _decode_result = ::fidl::Decode(std::move(_call_result.message));
  if (_decode_result.status != ZX_OK) {
    return _decode_result.status;
  }
  auto& _response = *_decode_result.message.message();
  *out_status = std::move(_response.status);
  return ZX_OK;
}

::fidl::DecodeResult<Paver::MarkActiveConfigurationSuccessfulResponse> Paver::SyncClient::MarkActiveConfigurationSuccessful(::fidl::BytePart _response_buffer, int32_t* out_status) {
  return Paver::Call::MarkActiveConfigurationSuccessful(zx::unowned_channel(this->channel_), std::move(_response_buffer), out_status);
}

::fidl::DecodeResult<Paver::MarkActiveConfigurationSuccessfulResponse> Paver::Call::MarkActiveConfigurationSuccessful(zx::unowned_channel _client_end, ::fidl::BytePart _response_buffer, int32_t* out_status) {
  FIDL_ALIGNDECL uint8_t _write_bytes[sizeof(MarkActiveConfigurationSuccessfulRequest)] = {};
  ::fidl::BytePart _request_buffer(_write_bytes, sizeof(_write_bytes));
  auto& _request = *reinterpret_cast<MarkActiveConfigurationSuccessfulRequest*>(_request_buffer.data());
  _request._hdr.ordinal = kPaver_MarkActiveConfigurationSuccessful_Ordinal;
  _request_buffer.set_actual(sizeof(MarkActiveConfigurationSuccessfulRequest));
  ::fidl::DecodedMessage<MarkActiveConfigurationSuccessfulRequest> _decoded_request(std::move(_request_buffer));
  auto _encode_request_result = ::fidl::Encode(std::move(_decoded_request));
  if (_encode_request_result.status != ZX_OK) {
    return ::fidl::DecodeResult<MarkActiveConfigurationSuccessfulResponse>(_encode_request_result.status, _encode_request_result.error);
  }
  auto _call_result = ::fidl::Call<MarkActiveConfigurationSuccessfulRequest, MarkActiveConfigurationSuccessfulResponse>(
    std::move(_client_end), std::move(_encode_request_result.message), std::move(_response_buffer));
  if (_call_result.status != ZX_OK) {
    return ::fidl::DecodeResult<MarkActiveConfigurationSuccessfulResponse>(_call_result.status, _call_result.error);
  }
  auto _decode_result = ::fidl::Decode(std::move(_call_result.message));
  if (_decode_result.status != ZX_OK) {
    return _decode_result;
  }
  auto& _response = *_decode_result.message.message();
  *out_status = std::move(_response.status);
  return _decode_result;
}

::fidl::DecodeResult<Paver::MarkActiveConfigurationSuccessfulResponse> Paver::SyncClient::MarkActiveConfigurationSuccessful(::fidl::BytePart response_buffer) {
  return Paver::Call::MarkActiveConfigurationSuccessful(zx::unowned_channel(this->channel_), std::move(response_buffer));
}

::fidl::DecodeResult<Paver::MarkActiveConfigurationSuccessfulResponse> Paver::Call::MarkActiveConfigurationSuccessful(zx::unowned_channel _client_end, ::fidl::BytePart response_buffer) {
  FIDL_ALIGNDECL uint8_t _write_bytes[sizeof(MarkActiveConfigurationSuccessfulRequest)] = {};
  constexpr uint32_t _write_num_bytes = sizeof(MarkActiveConfigurationSuccessfulRequest);
  ::fidl::BytePart _request_buffer(_write_bytes, sizeof(_write_bytes), _write_num_bytes);
  ::fidl::DecodedMessage<MarkActiveConfigurationSuccessfulRequest> params(std::move(_request_buffer));
  params.message()->_hdr = {};
  params.message()->_hdr.ordinal = kPaver_MarkActiveConfigurationSuccessful_Ordinal;
  auto _encode_request_result = ::fidl::Encode(std::move(params));
  if (_encode_request_result.status != ZX_OK) {
    return ::fidl::DecodeResult<Paver::MarkActiveConfigurationSuccessfulResponse>(
      _encode_request_result.status,
      _encode_request_result.error,
      ::fidl::DecodedMessage<Paver::MarkActiveConfigurationSuccessfulResponse>());
  }
  auto _call_result = ::fidl::Call<MarkActiveConfigurationSuccessfulRequest, MarkActiveConfigurationSuccessfulResponse>(
    std::move(_client_end), std::move(_encode_request_result.message), std::move(response_buffer));
  if (_call_result.status != ZX_OK) {
    return ::fidl::DecodeResult<Paver::MarkActiveConfigurationSuccessfulResponse>(
      _call_result.status,
      _call_result.error,
      ::fidl::DecodedMessage<Paver::MarkActiveConfigurationSuccessfulResponse>());
  }
  return ::fidl::Decode(std::move(_call_result.message));
}


zx_status_t Paver::SyncClient::ForceRecoveryConfiguration(int32_t* out_status) {
  return Paver::Call::ForceRecoveryConfiguration(zx::unowned_channel(this->channel_), out_status);
}

zx_status_t Paver::Call::ForceRecoveryConfiguration(zx::unowned_channel _client_end, int32_t* out_status) {
  constexpr uint32_t _kWriteAllocSize = ::fidl::internal::ClampedMessageSize<ForceRecoveryConfigurationRequest>();
  FIDL_ALIGNDECL uint8_t _write_bytes[_kWriteAllocSize] = {};
  auto& _request = *reinterpret_cast<ForceRecoveryConfigurationRequest*>(_write_bytes);
  _request._hdr.ordinal = kPaver_ForceRecoveryConfiguration_Ordinal;
  ::fidl::BytePart _request_bytes(_write_bytes, _kWriteAllocSize, sizeof(ForceRecoveryConfigurationRequest));
  ::fidl::DecodedMessage<ForceRecoveryConfigurationRequest> _decoded_request(std::move(_request_bytes));
  auto _encode_request_result = ::fidl::Encode(std::move(_decoded_request));
  if (_encode_request_result.status != ZX_OK) {
    return _encode_request_result.status;
  }
  constexpr uint32_t _kReadAllocSize = ::fidl::internal::ClampedMessageSize<ForceRecoveryConfigurationResponse>();
  FIDL_ALIGNDECL uint8_t _read_bytes[_kReadAllocSize];
  ::fidl::BytePart _response_bytes(_read_bytes, _kReadAllocSize);
  auto _call_result = ::fidl::Call<ForceRecoveryConfigurationRequest, ForceRecoveryConfigurationResponse>(
    std::move(_client_end), std::move(_encode_request_result.message), std::move(_response_bytes));
  if (_call_result.status != ZX_OK) {
    return _call_result.status;
  }
  auto _decode_result = ::fidl::Decode(std::move(_call_result.message));
  if (_decode_result.status != ZX_OK) {
    return _decode_result.status;
  }
  auto& _response = *_decode_result.message.message();
  *out_status = std::move(_response.status);
  return ZX_OK;
}

::fidl::DecodeResult<Paver::ForceRecoveryConfigurationResponse> Paver::SyncClient::ForceRecoveryConfiguration(::fidl::BytePart _response_buffer, int32_t* out_status) {
  return Paver::Call::ForceRecoveryConfiguration(zx::unowned_channel(this->channel_), std::move(_response_buffer), out_status);
}

::fidl::DecodeResult<Paver::ForceRecoveryConfigurationResponse> Paver::Call::ForceRecoveryConfiguration(zx::unowned_channel _client_end, ::fidl::BytePart _response_buffer, int32_t* out_status) {
  FIDL_ALIGNDECL uint8_t _write_bytes[sizeof(ForceRecoveryConfigurationRequest)] = {};
  ::fidl::BytePart _request_buffer(_write_bytes, sizeof(_write_bytes));
  auto& _request = *reinterpret_cast<ForceRecoveryConfigurationRequest*>(_request_buffer.data());
  _request._hdr.ordinal = kPaver_ForceRecoveryConfiguration_Ordinal;
  _request_buffer.set_actual(sizeof(ForceRecoveryConfigurationRequest));
  ::fidl::DecodedMessage<ForceRecoveryConfigurationRequest> _decoded_request(std::move(_request_buffer));
  auto _encode_request_result = ::fidl::Encode(std::move(_decoded_request));
  if (_encode_request_result.status != ZX_OK) {
    return ::fidl::DecodeResult<ForceRecoveryConfigurationResponse>(_encode_request_result.status, _encode_request_result.error);
  }
  auto _call_result = ::fidl::Call<ForceRecoveryConfigurationRequest, ForceRecoveryConfigurationResponse>(
    std::move(_client_end), std::move(_encode_request_result.message), std::move(_response_buffer));
  if (_call_result.status != ZX_OK) {
    return ::fidl::DecodeResult<ForceRecoveryConfigurationResponse>(_call_result.status, _call_result.error);
  }
  auto _decode_result = ::fidl::Decode(std::move(_call_result.message));
  if (_decode_result.status != ZX_OK) {
    return _decode_result;
  }
  auto& _response = *_decode_result.message.message();
  *out_status = std::move(_response.status);
  return _decode_result;
}

::fidl::DecodeResult<Paver::ForceRecoveryConfigurationResponse> Paver::SyncClient::ForceRecoveryConfiguration(::fidl::BytePart response_buffer) {
  return Paver::Call::ForceRecoveryConfiguration(zx::unowned_channel(this->channel_), std::move(response_buffer));
}

::fidl::DecodeResult<Paver::ForceRecoveryConfigurationResponse> Paver::Call::ForceRecoveryConfiguration(zx::unowned_channel _client_end, ::fidl::BytePart response_buffer) {
  FIDL_ALIGNDECL uint8_t _write_bytes[sizeof(ForceRecoveryConfigurationRequest)] = {};
  constexpr uint32_t _write_num_bytes = sizeof(ForceRecoveryConfigurationRequest);
  ::fidl::BytePart _request_buffer(_write_bytes, sizeof(_write_bytes), _write_num_bytes);
  ::fidl::DecodedMessage<ForceRecoveryConfigurationRequest> params(std::move(_request_buffer));
  params.message()->_hdr = {};
  params.message()->_hdr.ordinal = kPaver_ForceRecoveryConfiguration_Ordinal;
  auto _encode_request_result = ::fidl::Encode(std::move(params));
  if (_encode_request_result.status != ZX_OK) {
    return ::fidl::DecodeResult<Paver::ForceRecoveryConfigurationResponse>(
      _encode_request_result.status,
      _encode_request_result.error,
      ::fidl::DecodedMessage<Paver::ForceRecoveryConfigurationResponse>());
  }
  auto _call_result = ::fidl::Call<ForceRecoveryConfigurationRequest, ForceRecoveryConfigurationResponse>(
    std::move(_client_end), std::move(_encode_request_result.message), std::move(response_buffer));
  if (_call_result.status != ZX_OK) {
    return ::fidl::DecodeResult<Paver::ForceRecoveryConfigurationResponse>(
      _call_result.status,
      _call_result.error,
      ::fidl::DecodedMessage<Paver::ForceRecoveryConfigurationResponse>());
  }
  return ::fidl::Decode(std::move(_call_result.message));
}


zx_status_t Paver::SyncClient::WriteAsset(Configuration configuration, Asset asset, ::llcpp::fuchsia::mem::Buffer payload, int32_t* out_status) {
  return Paver::Call::WriteAsset(zx::unowned_channel(this->channel_), std::move(configuration), std::move(asset), std::move(payload), out_status);
}

zx_status_t Paver::Call::WriteAsset(zx::unowned_channel _client_end, Configuration configuration, Asset asset, ::llcpp::fuchsia::mem::Buffer payload, int32_t* out_status) {
  constexpr uint32_t _kWriteAllocSize = ::fidl::internal::ClampedMessageSize<WriteAssetRequest>();
  FIDL_ALIGNDECL uint8_t _write_bytes[_kWriteAllocSize] = {};
  auto& _request = *reinterpret_cast<WriteAssetRequest*>(_write_bytes);
  _request._hdr.ordinal = kPaver_WriteAsset_Ordinal;
  _request.configuration = std::move(configuration);
  _request.asset = std::move(asset);
  _request.payload = std::move(payload);
  ::fidl::BytePart _request_bytes(_write_bytes, _kWriteAllocSize, sizeof(WriteAssetRequest));
  ::fidl::DecodedMessage<WriteAssetRequest> _decoded_request(std::move(_request_bytes));
  auto _encode_request_result = ::fidl::Encode(std::move(_decoded_request));
  if (_encode_request_result.status != ZX_OK) {
    return _encode_request_result.status;
  }
  constexpr uint32_t _kReadAllocSize = ::fidl::internal::ClampedMessageSize<WriteAssetResponse>();
  FIDL_ALIGNDECL uint8_t _read_bytes[_kReadAllocSize];
  ::fidl::BytePart _response_bytes(_read_bytes, _kReadAllocSize);
  auto _call_result = ::fidl::Call<WriteAssetRequest, WriteAssetResponse>(
    std::move(_client_end), std::move(_encode_request_result.message), std::move(_response_bytes));
  if (_call_result.status != ZX_OK) {
    return _call_result.status;
  }
  auto _decode_result = ::fidl::Decode(std::move(_call_result.message));
  if (_decode_result.status != ZX_OK) {
    return _decode_result.status;
  }
  auto& _response = *_decode_result.message.message();
  *out_status = std::move(_response.status);
  return ZX_OK;
}

::fidl::DecodeResult<Paver::WriteAssetResponse> Paver::SyncClient::WriteAsset(::fidl::BytePart _request_buffer, Configuration configuration, Asset asset, ::llcpp::fuchsia::mem::Buffer payload, ::fidl::BytePart _response_buffer, int32_t* out_status) {
  return Paver::Call::WriteAsset(zx::unowned_channel(this->channel_), std::move(_request_buffer), std::move(configuration), std::move(asset), std::move(payload), std::move(_response_buffer), out_status);
}

::fidl::DecodeResult<Paver::WriteAssetResponse> Paver::Call::WriteAsset(zx::unowned_channel _client_end, ::fidl::BytePart _request_buffer, Configuration configuration, Asset asset, ::llcpp::fuchsia::mem::Buffer payload, ::fidl::BytePart _response_buffer, int32_t* out_status) {
  if (_request_buffer.capacity() < WriteAssetRequest::PrimarySize) {
    return ::fidl::DecodeResult<WriteAssetResponse>(ZX_ERR_BUFFER_TOO_SMALL, ::fidl::internal::kErrorRequestBufferTooSmall);
  }
  auto& _request = *reinterpret_cast<WriteAssetRequest*>(_request_buffer.data());
  _request._hdr.ordinal = kPaver_WriteAsset_Ordinal;
  _request.configuration = std::move(configuration);
  _request.asset = std::move(asset);
  _request.payload = std::move(payload);
  _request_buffer.set_actual(sizeof(WriteAssetRequest));
  ::fidl::DecodedMessage<WriteAssetRequest> _decoded_request(std::move(_request_buffer));
  auto _encode_request_result = ::fidl::Encode(std::move(_decoded_request));
  if (_encode_request_result.status != ZX_OK) {
    return ::fidl::DecodeResult<WriteAssetResponse>(_encode_request_result.status, _encode_request_result.error);
  }
  auto _call_result = ::fidl::Call<WriteAssetRequest, WriteAssetResponse>(
    std::move(_client_end), std::move(_encode_request_result.message), std::move(_response_buffer));
  if (_call_result.status != ZX_OK) {
    return ::fidl::DecodeResult<WriteAssetResponse>(_call_result.status, _call_result.error);
  }
  auto _decode_result = ::fidl::Decode(std::move(_call_result.message));
  if (_decode_result.status != ZX_OK) {
    return _decode_result;
  }
  auto& _response = *_decode_result.message.message();
  *out_status = std::move(_response.status);
  return _decode_result;
}

::fidl::DecodeResult<Paver::WriteAssetResponse> Paver::SyncClient::WriteAsset(::fidl::DecodedMessage<WriteAssetRequest> params, ::fidl::BytePart response_buffer) {
  return Paver::Call::WriteAsset(zx::unowned_channel(this->channel_), std::move(params), std::move(response_buffer));
}

::fidl::DecodeResult<Paver::WriteAssetResponse> Paver::Call::WriteAsset(zx::unowned_channel _client_end, ::fidl::DecodedMessage<WriteAssetRequest> params, ::fidl::BytePart response_buffer) {
  params.message()->_hdr = {};
  params.message()->_hdr.ordinal = kPaver_WriteAsset_Ordinal;
  auto _encode_request_result = ::fidl::Encode(std::move(params));
  if (_encode_request_result.status != ZX_OK) {
    return ::fidl::DecodeResult<Paver::WriteAssetResponse>(
      _encode_request_result.status,
      _encode_request_result.error,
      ::fidl::DecodedMessage<Paver::WriteAssetResponse>());
  }
  auto _call_result = ::fidl::Call<WriteAssetRequest, WriteAssetResponse>(
    std::move(_client_end), std::move(_encode_request_result.message), std::move(response_buffer));
  if (_call_result.status != ZX_OK) {
    return ::fidl::DecodeResult<Paver::WriteAssetResponse>(
      _call_result.status,
      _call_result.error,
      ::fidl::DecodedMessage<Paver::WriteAssetResponse>());
  }
  return ::fidl::Decode(std::move(_call_result.message));
}


zx_status_t Paver::SyncClient::WriteVolumes(::zx::channel payload, int32_t* out_status) {
  return Paver::Call::WriteVolumes(zx::unowned_channel(this->channel_), std::move(payload), out_status);
}

zx_status_t Paver::Call::WriteVolumes(zx::unowned_channel _client_end, ::zx::channel payload, int32_t* out_status) {
  constexpr uint32_t _kWriteAllocSize = ::fidl::internal::ClampedMessageSize<WriteVolumesRequest>();
  FIDL_ALIGNDECL uint8_t _write_bytes[_kWriteAllocSize] = {};
  auto& _request = *reinterpret_cast<WriteVolumesRequest*>(_write_bytes);
  _request._hdr.ordinal = kPaver_WriteVolumes_Ordinal;
  _request.payload = std::move(payload);
  ::fidl::BytePart _request_bytes(_write_bytes, _kWriteAllocSize, sizeof(WriteVolumesRequest));
  ::fidl::DecodedMessage<WriteVolumesRequest> _decoded_request(std::move(_request_bytes));
  auto _encode_request_result = ::fidl::Encode(std::move(_decoded_request));
  if (_encode_request_result.status != ZX_OK) {
    return _encode_request_result.status;
  }
  constexpr uint32_t _kReadAllocSize = ::fidl::internal::ClampedMessageSize<WriteVolumesResponse>();
  FIDL_ALIGNDECL uint8_t _read_bytes[_kReadAllocSize];
  ::fidl::BytePart _response_bytes(_read_bytes, _kReadAllocSize);
  auto _call_result = ::fidl::Call<WriteVolumesRequest, WriteVolumesResponse>(
    std::move(_client_end), std::move(_encode_request_result.message), std::move(_response_bytes));
  if (_call_result.status != ZX_OK) {
    return _call_result.status;
  }
  auto _decode_result = ::fidl::Decode(std::move(_call_result.message));
  if (_decode_result.status != ZX_OK) {
    return _decode_result.status;
  }
  auto& _response = *_decode_result.message.message();
  *out_status = std::move(_response.status);
  return ZX_OK;
}

::fidl::DecodeResult<Paver::WriteVolumesResponse> Paver::SyncClient::WriteVolumes(::fidl::BytePart _request_buffer, ::zx::channel payload, ::fidl::BytePart _response_buffer, int32_t* out_status) {
  return Paver::Call::WriteVolumes(zx::unowned_channel(this->channel_), std::move(_request_buffer), std::move(payload), std::move(_response_buffer), out_status);
}

::fidl::DecodeResult<Paver::WriteVolumesResponse> Paver::Call::WriteVolumes(zx::unowned_channel _client_end, ::fidl::BytePart _request_buffer, ::zx::channel payload, ::fidl::BytePart _response_buffer, int32_t* out_status) {
  if (_request_buffer.capacity() < WriteVolumesRequest::PrimarySize) {
    return ::fidl::DecodeResult<WriteVolumesResponse>(ZX_ERR_BUFFER_TOO_SMALL, ::fidl::internal::kErrorRequestBufferTooSmall);
  }
  auto& _request = *reinterpret_cast<WriteVolumesRequest*>(_request_buffer.data());
  _request._hdr.ordinal = kPaver_WriteVolumes_Ordinal;
  _request.payload = std::move(payload);
  _request_buffer.set_actual(sizeof(WriteVolumesRequest));
  ::fidl::DecodedMessage<WriteVolumesRequest> _decoded_request(std::move(_request_buffer));
  auto _encode_request_result = ::fidl::Encode(std::move(_decoded_request));
  if (_encode_request_result.status != ZX_OK) {
    return ::fidl::DecodeResult<WriteVolumesResponse>(_encode_request_result.status, _encode_request_result.error);
  }
  auto _call_result = ::fidl::Call<WriteVolumesRequest, WriteVolumesResponse>(
    std::move(_client_end), std::move(_encode_request_result.message), std::move(_response_buffer));
  if (_call_result.status != ZX_OK) {
    return ::fidl::DecodeResult<WriteVolumesResponse>(_call_result.status, _call_result.error);
  }
  auto _decode_result = ::fidl::Decode(std::move(_call_result.message));
  if (_decode_result.status != ZX_OK) {
    return _decode_result;
  }
  auto& _response = *_decode_result.message.message();
  *out_status = std::move(_response.status);
  return _decode_result;
}

::fidl::DecodeResult<Paver::WriteVolumesResponse> Paver::SyncClient::WriteVolumes(::fidl::DecodedMessage<WriteVolumesRequest> params, ::fidl::BytePart response_buffer) {
  return Paver::Call::WriteVolumes(zx::unowned_channel(this->channel_), std::move(params), std::move(response_buffer));
}

::fidl::DecodeResult<Paver::WriteVolumesResponse> Paver::Call::WriteVolumes(zx::unowned_channel _client_end, ::fidl::DecodedMessage<WriteVolumesRequest> params, ::fidl::BytePart response_buffer) {
  params.message()->_hdr = {};
  params.message()->_hdr.ordinal = kPaver_WriteVolumes_Ordinal;
  auto _encode_request_result = ::fidl::Encode(std::move(params));
  if (_encode_request_result.status != ZX_OK) {
    return ::fidl::DecodeResult<Paver::WriteVolumesResponse>(
      _encode_request_result.status,
      _encode_request_result.error,
      ::fidl::DecodedMessage<Paver::WriteVolumesResponse>());
  }
  auto _call_result = ::fidl::Call<WriteVolumesRequest, WriteVolumesResponse>(
    std::move(_client_end), std::move(_encode_request_result.message), std::move(response_buffer));
  if (_call_result.status != ZX_OK) {
    return ::fidl::DecodeResult<Paver::WriteVolumesResponse>(
      _call_result.status,
      _call_result.error,
      ::fidl::DecodedMessage<Paver::WriteVolumesResponse>());
  }
  return ::fidl::Decode(std::move(_call_result.message));
}


zx_status_t Paver::SyncClient::WriteBootloader(::llcpp::fuchsia::mem::Buffer payload, int32_t* out_status) {
  return Paver::Call::WriteBootloader(zx::unowned_channel(this->channel_), std::move(payload), out_status);
}

zx_status_t Paver::Call::WriteBootloader(zx::unowned_channel _client_end, ::llcpp::fuchsia::mem::Buffer payload, int32_t* out_status) {
  constexpr uint32_t _kWriteAllocSize = ::fidl::internal::ClampedMessageSize<WriteBootloaderRequest>();
  FIDL_ALIGNDECL uint8_t _write_bytes[_kWriteAllocSize] = {};
  auto& _request = *reinterpret_cast<WriteBootloaderRequest*>(_write_bytes);
  _request._hdr.ordinal = kPaver_WriteBootloader_Ordinal;
  _request.payload = std::move(payload);
  ::fidl::BytePart _request_bytes(_write_bytes, _kWriteAllocSize, sizeof(WriteBootloaderRequest));
  ::fidl::DecodedMessage<WriteBootloaderRequest> _decoded_request(std::move(_request_bytes));
  auto _encode_request_result = ::fidl::Encode(std::move(_decoded_request));
  if (_encode_request_result.status != ZX_OK) {
    return _encode_request_result.status;
  }
  constexpr uint32_t _kReadAllocSize = ::fidl::internal::ClampedMessageSize<WriteBootloaderResponse>();
  FIDL_ALIGNDECL uint8_t _read_bytes[_kReadAllocSize];
  ::fidl::BytePart _response_bytes(_read_bytes, _kReadAllocSize);
  auto _call_result = ::fidl::Call<WriteBootloaderRequest, WriteBootloaderResponse>(
    std::move(_client_end), std::move(_encode_request_result.message), std::move(_response_bytes));
  if (_call_result.status != ZX_OK) {
    return _call_result.status;
  }
  auto _decode_result = ::fidl::Decode(std::move(_call_result.message));
  if (_decode_result.status != ZX_OK) {
    return _decode_result.status;
  }
  auto& _response = *_decode_result.message.message();
  *out_status = std::move(_response.status);
  return ZX_OK;
}

::fidl::DecodeResult<Paver::WriteBootloaderResponse> Paver::SyncClient::WriteBootloader(::fidl::BytePart _request_buffer, ::llcpp::fuchsia::mem::Buffer payload, ::fidl::BytePart _response_buffer, int32_t* out_status) {
  return Paver::Call::WriteBootloader(zx::unowned_channel(this->channel_), std::move(_request_buffer), std::move(payload), std::move(_response_buffer), out_status);
}

::fidl::DecodeResult<Paver::WriteBootloaderResponse> Paver::Call::WriteBootloader(zx::unowned_channel _client_end, ::fidl::BytePart _request_buffer, ::llcpp::fuchsia::mem::Buffer payload, ::fidl::BytePart _response_buffer, int32_t* out_status) {
  if (_request_buffer.capacity() < WriteBootloaderRequest::PrimarySize) {
    return ::fidl::DecodeResult<WriteBootloaderResponse>(ZX_ERR_BUFFER_TOO_SMALL, ::fidl::internal::kErrorRequestBufferTooSmall);
  }
  auto& _request = *reinterpret_cast<WriteBootloaderRequest*>(_request_buffer.data());
  _request._hdr.ordinal = kPaver_WriteBootloader_Ordinal;
  _request.payload = std::move(payload);
  _request_buffer.set_actual(sizeof(WriteBootloaderRequest));
  ::fidl::DecodedMessage<WriteBootloaderRequest> _decoded_request(std::move(_request_buffer));
  auto _encode_request_result = ::fidl::Encode(std::move(_decoded_request));
  if (_encode_request_result.status != ZX_OK) {
    return ::fidl::DecodeResult<WriteBootloaderResponse>(_encode_request_result.status, _encode_request_result.error);
  }
  auto _call_result = ::fidl::Call<WriteBootloaderRequest, WriteBootloaderResponse>(
    std::move(_client_end), std::move(_encode_request_result.message), std::move(_response_buffer));
  if (_call_result.status != ZX_OK) {
    return ::fidl::DecodeResult<WriteBootloaderResponse>(_call_result.status, _call_result.error);
  }
  auto _decode_result = ::fidl::Decode(std::move(_call_result.message));
  if (_decode_result.status != ZX_OK) {
    return _decode_result;
  }
  auto& _response = *_decode_result.message.message();
  *out_status = std::move(_response.status);
  return _decode_result;
}

::fidl::DecodeResult<Paver::WriteBootloaderResponse> Paver::SyncClient::WriteBootloader(::fidl::DecodedMessage<WriteBootloaderRequest> params, ::fidl::BytePart response_buffer) {
  return Paver::Call::WriteBootloader(zx::unowned_channel(this->channel_), std::move(params), std::move(response_buffer));
}

::fidl::DecodeResult<Paver::WriteBootloaderResponse> Paver::Call::WriteBootloader(zx::unowned_channel _client_end, ::fidl::DecodedMessage<WriteBootloaderRequest> params, ::fidl::BytePart response_buffer) {
  params.message()->_hdr = {};
  params.message()->_hdr.ordinal = kPaver_WriteBootloader_Ordinal;
  auto _encode_request_result = ::fidl::Encode(std::move(params));
  if (_encode_request_result.status != ZX_OK) {
    return ::fidl::DecodeResult<Paver::WriteBootloaderResponse>(
      _encode_request_result.status,
      _encode_request_result.error,
      ::fidl::DecodedMessage<Paver::WriteBootloaderResponse>());
  }
  auto _call_result = ::fidl::Call<WriteBootloaderRequest, WriteBootloaderResponse>(
    std::move(_client_end), std::move(_encode_request_result.message), std::move(response_buffer));
  if (_call_result.status != ZX_OK) {
    return ::fidl::DecodeResult<Paver::WriteBootloaderResponse>(
      _call_result.status,
      _call_result.error,
      ::fidl::DecodedMessage<Paver::WriteBootloaderResponse>());
  }
  return ::fidl::Decode(std::move(_call_result.message));
}


zx_status_t Paver::SyncClient::WriteDataFile(::fidl::StringView filename, ::llcpp::fuchsia::mem::Buffer payload, int32_t* out_status) {
  return Paver::Call::WriteDataFile(zx::unowned_channel(this->channel_), std::move(filename), std::move(payload), out_status);
}

zx_status_t Paver::Call::WriteDataFile(zx::unowned_channel _client_end, ::fidl::StringView filename, ::llcpp::fuchsia::mem::Buffer payload, int32_t* out_status) {
  constexpr uint32_t _kWriteAllocSize = ::fidl::internal::ClampedMessageSize<WriteDataFileRequest>();
  std::unique_ptr<uint8_t[]> _write_bytes_unique_ptr(new uint8_t[_kWriteAllocSize]);
  uint8_t* _write_bytes = _write_bytes_unique_ptr.get();
  WriteDataFileRequest _request = {};
  _request._hdr.ordinal = kPaver_WriteDataFile_Ordinal;
  _request.filename = std::move(filename);
  _request.payload = std::move(payload);
  auto _linearize_result = ::fidl::Linearize(&_request, ::fidl::BytePart(_write_bytes,
                                                                         _kWriteAllocSize));
  if (_linearize_result.status != ZX_OK) {
    return _linearize_result.status;
  }
  ::fidl::DecodedMessage<WriteDataFileRequest> _decoded_request = std::move(_linearize_result.message);
  auto _encode_request_result = ::fidl::Encode(std::move(_decoded_request));
  if (_encode_request_result.status != ZX_OK) {
    return _encode_request_result.status;
  }
  constexpr uint32_t _kReadAllocSize = ::fidl::internal::ClampedMessageSize<WriteDataFileResponse>();
  FIDL_ALIGNDECL uint8_t _read_bytes[_kReadAllocSize];
  ::fidl::BytePart _response_bytes(_read_bytes, _kReadAllocSize);
  auto _call_result = ::fidl::Call<WriteDataFileRequest, WriteDataFileResponse>(
    std::move(_client_end), std::move(_encode_request_result.message), std::move(_response_bytes));
  if (_call_result.status != ZX_OK) {
    return _call_result.status;
  }
  auto _decode_result = ::fidl::Decode(std::move(_call_result.message));
  if (_decode_result.status != ZX_OK) {
    return _decode_result.status;
  }
  auto& _response = *_decode_result.message.message();
  *out_status = std::move(_response.status);
  return ZX_OK;
}

::fidl::DecodeResult<Paver::WriteDataFileResponse> Paver::SyncClient::WriteDataFile(::fidl::BytePart _request_buffer, ::fidl::StringView filename, ::llcpp::fuchsia::mem::Buffer payload, ::fidl::BytePart _response_buffer, int32_t* out_status) {
  return Paver::Call::WriteDataFile(zx::unowned_channel(this->channel_), std::move(_request_buffer), std::move(filename), std::move(payload), std::move(_response_buffer), out_status);
}

::fidl::DecodeResult<Paver::WriteDataFileResponse> Paver::Call::WriteDataFile(zx::unowned_channel _client_end, ::fidl::BytePart _request_buffer, ::fidl::StringView filename, ::llcpp::fuchsia::mem::Buffer payload, ::fidl::BytePart _response_buffer, int32_t* out_status) {
  if (_request_buffer.capacity() < WriteDataFileRequest::PrimarySize) {
    return ::fidl::DecodeResult<WriteDataFileResponse>(ZX_ERR_BUFFER_TOO_SMALL, ::fidl::internal::kErrorRequestBufferTooSmall);
  }
  WriteDataFileRequest _request = {};
  _request._hdr.ordinal = kPaver_WriteDataFile_Ordinal;
  _request.filename = std::move(filename);
  _request.payload = std::move(payload);
  auto _linearize_result = ::fidl::Linearize(&_request, std::move(_request_buffer));
  if (_linearize_result.status != ZX_OK) {
    return ::fidl::DecodeResult<WriteDataFileResponse>(_linearize_result.status, _linearize_result.error);
  }
  ::fidl::DecodedMessage<WriteDataFileRequest> _decoded_request = std::move(_linearize_result.message);
  auto _encode_request_result = ::fidl::Encode(std::move(_decoded_request));
  if (_encode_request_result.status != ZX_OK) {
    return ::fidl::DecodeResult<WriteDataFileResponse>(_encode_request_result.status, _encode_request_result.error);
  }
  auto _call_result = ::fidl::Call<WriteDataFileRequest, WriteDataFileResponse>(
    std::move(_client_end), std::move(_encode_request_result.message), std::move(_response_buffer));
  if (_call_result.status != ZX_OK) {
    return ::fidl::DecodeResult<WriteDataFileResponse>(_call_result.status, _call_result.error);
  }
  auto _decode_result = ::fidl::Decode(std::move(_call_result.message));
  if (_decode_result.status != ZX_OK) {
    return _decode_result;
  }
  auto& _response = *_decode_result.message.message();
  *out_status = std::move(_response.status);
  return _decode_result;
}

::fidl::DecodeResult<Paver::WriteDataFileResponse> Paver::SyncClient::WriteDataFile(::fidl::DecodedMessage<WriteDataFileRequest> params, ::fidl::BytePart response_buffer) {
  return Paver::Call::WriteDataFile(zx::unowned_channel(this->channel_), std::move(params), std::move(response_buffer));
}

::fidl::DecodeResult<Paver::WriteDataFileResponse> Paver::Call::WriteDataFile(zx::unowned_channel _client_end, ::fidl::DecodedMessage<WriteDataFileRequest> params, ::fidl::BytePart response_buffer) {
  params.message()->_hdr = {};
  params.message()->_hdr.ordinal = kPaver_WriteDataFile_Ordinal;
  auto _encode_request_result = ::fidl::Encode(std::move(params));
  if (_encode_request_result.status != ZX_OK) {
    return ::fidl::DecodeResult<Paver::WriteDataFileResponse>(
      _encode_request_result.status,
      _encode_request_result.error,
      ::fidl::DecodedMessage<Paver::WriteDataFileResponse>());
  }
  auto _call_result = ::fidl::Call<WriteDataFileRequest, WriteDataFileResponse>(
    std::move(_client_end), std::move(_encode_request_result.message), std::move(response_buffer));
  if (_call_result.status != ZX_OK) {
    return ::fidl::DecodeResult<Paver::WriteDataFileResponse>(
      _call_result.status,
      _call_result.error,
      ::fidl::DecodedMessage<Paver::WriteDataFileResponse>());
  }
  return ::fidl::Decode(std::move(_call_result.message));
}


zx_status_t Paver::SyncClient::WipeVolumes(int32_t* out_status) {
  return Paver::Call::WipeVolumes(zx::unowned_channel(this->channel_), out_status);
}

zx_status_t Paver::Call::WipeVolumes(zx::unowned_channel _client_end, int32_t* out_status) {
  constexpr uint32_t _kWriteAllocSize = ::fidl::internal::ClampedMessageSize<WipeVolumesRequest>();
  FIDL_ALIGNDECL uint8_t _write_bytes[_kWriteAllocSize] = {};
  auto& _request = *reinterpret_cast<WipeVolumesRequest*>(_write_bytes);
  _request._hdr.ordinal = kPaver_WipeVolumes_Ordinal;
  ::fidl::BytePart _request_bytes(_write_bytes, _kWriteAllocSize, sizeof(WipeVolumesRequest));
  ::fidl::DecodedMessage<WipeVolumesRequest> _decoded_request(std::move(_request_bytes));
  auto _encode_request_result = ::fidl::Encode(std::move(_decoded_request));
  if (_encode_request_result.status != ZX_OK) {
    return _encode_request_result.status;
  }
  constexpr uint32_t _kReadAllocSize = ::fidl::internal::ClampedMessageSize<WipeVolumesResponse>();
  FIDL_ALIGNDECL uint8_t _read_bytes[_kReadAllocSize];
  ::fidl::BytePart _response_bytes(_read_bytes, _kReadAllocSize);
  auto _call_result = ::fidl::Call<WipeVolumesRequest, WipeVolumesResponse>(
    std::move(_client_end), std::move(_encode_request_result.message), std::move(_response_bytes));
  if (_call_result.status != ZX_OK) {
    return _call_result.status;
  }
  auto _decode_result = ::fidl::Decode(std::move(_call_result.message));
  if (_decode_result.status != ZX_OK) {
    return _decode_result.status;
  }
  auto& _response = *_decode_result.message.message();
  *out_status = std::move(_response.status);
  return ZX_OK;
}

::fidl::DecodeResult<Paver::WipeVolumesResponse> Paver::SyncClient::WipeVolumes(::fidl::BytePart _response_buffer, int32_t* out_status) {
  return Paver::Call::WipeVolumes(zx::unowned_channel(this->channel_), std::move(_response_buffer), out_status);
}

::fidl::DecodeResult<Paver::WipeVolumesResponse> Paver::Call::WipeVolumes(zx::unowned_channel _client_end, ::fidl::BytePart _response_buffer, int32_t* out_status) {
  FIDL_ALIGNDECL uint8_t _write_bytes[sizeof(WipeVolumesRequest)] = {};
  ::fidl::BytePart _request_buffer(_write_bytes, sizeof(_write_bytes));
  auto& _request = *reinterpret_cast<WipeVolumesRequest*>(_request_buffer.data());
  _request._hdr.ordinal = kPaver_WipeVolumes_Ordinal;
  _request_buffer.set_actual(sizeof(WipeVolumesRequest));
  ::fidl::DecodedMessage<WipeVolumesRequest> _decoded_request(std::move(_request_buffer));
  auto _encode_request_result = ::fidl::Encode(std::move(_decoded_request));
  if (_encode_request_result.status != ZX_OK) {
    return ::fidl::DecodeResult<WipeVolumesResponse>(_encode_request_result.status, _encode_request_result.error);
  }
  auto _call_result = ::fidl::Call<WipeVolumesRequest, WipeVolumesResponse>(
    std::move(_client_end), std::move(_encode_request_result.message), std::move(_response_buffer));
  if (_call_result.status != ZX_OK) {
    return ::fidl::DecodeResult<WipeVolumesResponse>(_call_result.status, _call_result.error);
  }
  auto _decode_result = ::fidl::Decode(std::move(_call_result.message));
  if (_decode_result.status != ZX_OK) {
    return _decode_result;
  }
  auto& _response = *_decode_result.message.message();
  *out_status = std::move(_response.status);
  return _decode_result;
}

::fidl::DecodeResult<Paver::WipeVolumesResponse> Paver::SyncClient::WipeVolumes(::fidl::BytePart response_buffer) {
  return Paver::Call::WipeVolumes(zx::unowned_channel(this->channel_), std::move(response_buffer));
}

::fidl::DecodeResult<Paver::WipeVolumesResponse> Paver::Call::WipeVolumes(zx::unowned_channel _client_end, ::fidl::BytePart response_buffer) {
  FIDL_ALIGNDECL uint8_t _write_bytes[sizeof(WipeVolumesRequest)] = {};
  constexpr uint32_t _write_num_bytes = sizeof(WipeVolumesRequest);
  ::fidl::BytePart _request_buffer(_write_bytes, sizeof(_write_bytes), _write_num_bytes);
  ::fidl::DecodedMessage<WipeVolumesRequest> params(std::move(_request_buffer));
  params.message()->_hdr = {};
  params.message()->_hdr.ordinal = kPaver_WipeVolumes_Ordinal;
  auto _encode_request_result = ::fidl::Encode(std::move(params));
  if (_encode_request_result.status != ZX_OK) {
    return ::fidl::DecodeResult<Paver::WipeVolumesResponse>(
      _encode_request_result.status,
      _encode_request_result.error,
      ::fidl::DecodedMessage<Paver::WipeVolumesResponse>());
  }
  auto _call_result = ::fidl::Call<WipeVolumesRequest, WipeVolumesResponse>(
    std::move(_client_end), std::move(_encode_request_result.message), std::move(response_buffer));
  if (_call_result.status != ZX_OK) {
    return ::fidl::DecodeResult<Paver::WipeVolumesResponse>(
      _call_result.status,
      _call_result.error,
      ::fidl::DecodedMessage<Paver::WipeVolumesResponse>());
  }
  return ::fidl::Decode(std::move(_call_result.message));
}


bool Paver::TryDispatch(Interface* impl, fidl_msg_t* msg, ::fidl::Transaction* txn) {
  if (msg->num_bytes < sizeof(fidl_message_header_t)) {
    zx_handle_close_many(msg->handles, msg->num_handles);
    txn->Close(ZX_ERR_INVALID_ARGS);
    return true;
  }
  fidl_message_header_t* hdr = reinterpret_cast<fidl_message_header_t*>(msg->bytes);
  switch (hdr->ordinal) {
    case kPaver_QueryActiveConfiguration_Ordinal: {
      auto result = ::fidl::DecodeAs<QueryActiveConfigurationRequest>(msg);
      if (result.status != ZX_OK) {
        txn->Close(ZX_ERR_INVALID_ARGS);
        return true;
      }
      impl->QueryActiveConfiguration(
        Interface::QueryActiveConfigurationCompleter::Sync(txn));
      return true;
    }
    case kPaver_SetActiveConfiguration_Ordinal: {
      auto result = ::fidl::DecodeAs<SetActiveConfigurationRequest>(msg);
      if (result.status != ZX_OK) {
        txn->Close(ZX_ERR_INVALID_ARGS);
        return true;
      }
      auto message = result.message.message();
      impl->SetActiveConfiguration(std::move(message->configuration),
        Interface::SetActiveConfigurationCompleter::Sync(txn));
      return true;
    }
    case kPaver_MarkActiveConfigurationSuccessful_Ordinal: {
      auto result = ::fidl::DecodeAs<MarkActiveConfigurationSuccessfulRequest>(msg);
      if (result.status != ZX_OK) {
        txn->Close(ZX_ERR_INVALID_ARGS);
        return true;
      }
      impl->MarkActiveConfigurationSuccessful(
        Interface::MarkActiveConfigurationSuccessfulCompleter::Sync(txn));
      return true;
    }
    case kPaver_ForceRecoveryConfiguration_Ordinal: {
      auto result = ::fidl::DecodeAs<ForceRecoveryConfigurationRequest>(msg);
      if (result.status != ZX_OK) {
        txn->Close(ZX_ERR_INVALID_ARGS);
        return true;
      }
      impl->ForceRecoveryConfiguration(
        Interface::ForceRecoveryConfigurationCompleter::Sync(txn));
      return true;
    }
    case kPaver_WriteAsset_Ordinal: {
      auto result = ::fidl::DecodeAs<WriteAssetRequest>(msg);
      if (result.status != ZX_OK) {
        txn->Close(ZX_ERR_INVALID_ARGS);
        return true;
      }
      auto message = result.message.message();
      impl->WriteAsset(std::move(message->configuration), std::move(message->asset), std::move(message->payload),
        Interface::WriteAssetCompleter::Sync(txn));
      return true;
    }
    case kPaver_WriteVolumes_Ordinal: {
      auto result = ::fidl::DecodeAs<WriteVolumesRequest>(msg);
      if (result.status != ZX_OK) {
        txn->Close(ZX_ERR_INVALID_ARGS);
        return true;
      }
      auto message = result.message.message();
      impl->WriteVolumes(std::move(message->payload),
        Interface::WriteVolumesCompleter::Sync(txn));
      return true;
    }
    case kPaver_WriteBootloader_Ordinal: {
      auto result = ::fidl::DecodeAs<WriteBootloaderRequest>(msg);
      if (result.status != ZX_OK) {
        txn->Close(ZX_ERR_INVALID_ARGS);
        return true;
      }
      auto message = result.message.message();
      impl->WriteBootloader(std::move(message->payload),
        Interface::WriteBootloaderCompleter::Sync(txn));
      return true;
    }
    case kPaver_WriteDataFile_Ordinal: {
      auto result = ::fidl::DecodeAs<WriteDataFileRequest>(msg);
      if (result.status != ZX_OK) {
        txn->Close(ZX_ERR_INVALID_ARGS);
        return true;
      }
      auto message = result.message.message();
      impl->WriteDataFile(std::move(message->filename), std::move(message->payload),
        Interface::WriteDataFileCompleter::Sync(txn));
      return true;
    }
    case kPaver_WipeVolumes_Ordinal: {
      auto result = ::fidl::DecodeAs<WipeVolumesRequest>(msg);
      if (result.status != ZX_OK) {
        txn->Close(ZX_ERR_INVALID_ARGS);
        return true;
      }
      impl->WipeVolumes(
        Interface::WipeVolumesCompleter::Sync(txn));
      return true;
    }
    default: {
      return false;
    }
  }
}

bool Paver::Dispatch(Interface* impl, fidl_msg_t* msg, ::fidl::Transaction* txn) {
  bool found = TryDispatch(impl, msg, txn);
  if (!found) {
    zx_handle_close_many(msg->handles, msg->num_handles);
    txn->Close(ZX_ERR_NOT_SUPPORTED);
  }
  return found;
}


void Paver::Interface::QueryActiveConfigurationCompleterBase::Reply(Paver_QueryActiveConfiguration_Result result) {
  constexpr uint32_t _kWriteAllocSize = ::fidl::internal::ClampedMessageSize<QueryActiveConfigurationResponse>();
  FIDL_ALIGNDECL uint8_t _write_bytes[_kWriteAllocSize] = {};
  auto& _response = *reinterpret_cast<QueryActiveConfigurationResponse*>(_write_bytes);
  _response._hdr.ordinal = kPaver_QueryActiveConfiguration_Ordinal;
  _response.result = std::move(result);
  ::fidl::BytePart _response_bytes(_write_bytes, _kWriteAllocSize, sizeof(QueryActiveConfigurationResponse));
  CompleterBase::SendReply(::fidl::DecodedMessage<QueryActiveConfigurationResponse>(std::move(_response_bytes)));
}

void Paver::Interface::QueryActiveConfigurationCompleterBase::Reply(::fidl::BytePart _buffer, Paver_QueryActiveConfiguration_Result result) {
  if (_buffer.capacity() < QueryActiveConfigurationResponse::PrimarySize) {
    CompleterBase::Close(ZX_ERR_INTERNAL);
    return;
  }
  auto& _response = *reinterpret_cast<QueryActiveConfigurationResponse*>(_buffer.data());
  _response._hdr.ordinal = kPaver_QueryActiveConfiguration_Ordinal;
  _response.result = std::move(result);
  _buffer.set_actual(sizeof(QueryActiveConfigurationResponse));
  CompleterBase::SendReply(::fidl::DecodedMessage<QueryActiveConfigurationResponse>(std::move(_buffer)));
}

void Paver::Interface::QueryActiveConfigurationCompleterBase::Reply(::fidl::DecodedMessage<QueryActiveConfigurationResponse> params) {
  params.message()->_hdr = {};
  params.message()->_hdr.ordinal = kPaver_QueryActiveConfiguration_Ordinal;
  CompleterBase::SendReply(std::move(params));
}


void Paver::Interface::SetActiveConfigurationCompleterBase::Reply(int32_t status) {
  constexpr uint32_t _kWriteAllocSize = ::fidl::internal::ClampedMessageSize<SetActiveConfigurationResponse>();
  FIDL_ALIGNDECL uint8_t _write_bytes[_kWriteAllocSize] = {};
  auto& _response = *reinterpret_cast<SetActiveConfigurationResponse*>(_write_bytes);
  _response._hdr.ordinal = kPaver_SetActiveConfiguration_Ordinal;
  _response.status = std::move(status);
  ::fidl::BytePart _response_bytes(_write_bytes, _kWriteAllocSize, sizeof(SetActiveConfigurationResponse));
  CompleterBase::SendReply(::fidl::DecodedMessage<SetActiveConfigurationResponse>(std::move(_response_bytes)));
}

void Paver::Interface::SetActiveConfigurationCompleterBase::Reply(::fidl::BytePart _buffer, int32_t status) {
  if (_buffer.capacity() < SetActiveConfigurationResponse::PrimarySize) {
    CompleterBase::Close(ZX_ERR_INTERNAL);
    return;
  }
  auto& _response = *reinterpret_cast<SetActiveConfigurationResponse*>(_buffer.data());
  _response._hdr.ordinal = kPaver_SetActiveConfiguration_Ordinal;
  _response.status = std::move(status);
  _buffer.set_actual(sizeof(SetActiveConfigurationResponse));
  CompleterBase::SendReply(::fidl::DecodedMessage<SetActiveConfigurationResponse>(std::move(_buffer)));
}

void Paver::Interface::SetActiveConfigurationCompleterBase::Reply(::fidl::DecodedMessage<SetActiveConfigurationResponse> params) {
  params.message()->_hdr = {};
  params.message()->_hdr.ordinal = kPaver_SetActiveConfiguration_Ordinal;
  CompleterBase::SendReply(std::move(params));
}


void Paver::Interface::MarkActiveConfigurationSuccessfulCompleterBase::Reply(int32_t status) {
  constexpr uint32_t _kWriteAllocSize = ::fidl::internal::ClampedMessageSize<MarkActiveConfigurationSuccessfulResponse>();
  FIDL_ALIGNDECL uint8_t _write_bytes[_kWriteAllocSize] = {};
  auto& _response = *reinterpret_cast<MarkActiveConfigurationSuccessfulResponse*>(_write_bytes);
  _response._hdr.ordinal = kPaver_MarkActiveConfigurationSuccessful_Ordinal;
  _response.status = std::move(status);
  ::fidl::BytePart _response_bytes(_write_bytes, _kWriteAllocSize, sizeof(MarkActiveConfigurationSuccessfulResponse));
  CompleterBase::SendReply(::fidl::DecodedMessage<MarkActiveConfigurationSuccessfulResponse>(std::move(_response_bytes)));
}

void Paver::Interface::MarkActiveConfigurationSuccessfulCompleterBase::Reply(::fidl::BytePart _buffer, int32_t status) {
  if (_buffer.capacity() < MarkActiveConfigurationSuccessfulResponse::PrimarySize) {
    CompleterBase::Close(ZX_ERR_INTERNAL);
    return;
  }
  auto& _response = *reinterpret_cast<MarkActiveConfigurationSuccessfulResponse*>(_buffer.data());
  _response._hdr.ordinal = kPaver_MarkActiveConfigurationSuccessful_Ordinal;
  _response.status = std::move(status);
  _buffer.set_actual(sizeof(MarkActiveConfigurationSuccessfulResponse));
  CompleterBase::SendReply(::fidl::DecodedMessage<MarkActiveConfigurationSuccessfulResponse>(std::move(_buffer)));
}

void Paver::Interface::MarkActiveConfigurationSuccessfulCompleterBase::Reply(::fidl::DecodedMessage<MarkActiveConfigurationSuccessfulResponse> params) {
  params.message()->_hdr = {};
  params.message()->_hdr.ordinal = kPaver_MarkActiveConfigurationSuccessful_Ordinal;
  CompleterBase::SendReply(std::move(params));
}


void Paver::Interface::ForceRecoveryConfigurationCompleterBase::Reply(int32_t status) {
  constexpr uint32_t _kWriteAllocSize = ::fidl::internal::ClampedMessageSize<ForceRecoveryConfigurationResponse>();
  FIDL_ALIGNDECL uint8_t _write_bytes[_kWriteAllocSize] = {};
  auto& _response = *reinterpret_cast<ForceRecoveryConfigurationResponse*>(_write_bytes);
  _response._hdr.ordinal = kPaver_ForceRecoveryConfiguration_Ordinal;
  _response.status = std::move(status);
  ::fidl::BytePart _response_bytes(_write_bytes, _kWriteAllocSize, sizeof(ForceRecoveryConfigurationResponse));
  CompleterBase::SendReply(::fidl::DecodedMessage<ForceRecoveryConfigurationResponse>(std::move(_response_bytes)));
}

void Paver::Interface::ForceRecoveryConfigurationCompleterBase::Reply(::fidl::BytePart _buffer, int32_t status) {
  if (_buffer.capacity() < ForceRecoveryConfigurationResponse::PrimarySize) {
    CompleterBase::Close(ZX_ERR_INTERNAL);
    return;
  }
  auto& _response = *reinterpret_cast<ForceRecoveryConfigurationResponse*>(_buffer.data());
  _response._hdr.ordinal = kPaver_ForceRecoveryConfiguration_Ordinal;
  _response.status = std::move(status);
  _buffer.set_actual(sizeof(ForceRecoveryConfigurationResponse));
  CompleterBase::SendReply(::fidl::DecodedMessage<ForceRecoveryConfigurationResponse>(std::move(_buffer)));
}

void Paver::Interface::ForceRecoveryConfigurationCompleterBase::Reply(::fidl::DecodedMessage<ForceRecoveryConfigurationResponse> params) {
  params.message()->_hdr = {};
  params.message()->_hdr.ordinal = kPaver_ForceRecoveryConfiguration_Ordinal;
  CompleterBase::SendReply(std::move(params));
}


void Paver::Interface::WriteAssetCompleterBase::Reply(int32_t status) {
  constexpr uint32_t _kWriteAllocSize = ::fidl::internal::ClampedMessageSize<WriteAssetResponse>();
  FIDL_ALIGNDECL uint8_t _write_bytes[_kWriteAllocSize] = {};
  auto& _response = *reinterpret_cast<WriteAssetResponse*>(_write_bytes);
  _response._hdr.ordinal = kPaver_WriteAsset_Ordinal;
  _response.status = std::move(status);
  ::fidl::BytePart _response_bytes(_write_bytes, _kWriteAllocSize, sizeof(WriteAssetResponse));
  CompleterBase::SendReply(::fidl::DecodedMessage<WriteAssetResponse>(std::move(_response_bytes)));
}

void Paver::Interface::WriteAssetCompleterBase::Reply(::fidl::BytePart _buffer, int32_t status) {
  if (_buffer.capacity() < WriteAssetResponse::PrimarySize) {
    CompleterBase::Close(ZX_ERR_INTERNAL);
    return;
  }
  auto& _response = *reinterpret_cast<WriteAssetResponse*>(_buffer.data());
  _response._hdr.ordinal = kPaver_WriteAsset_Ordinal;
  _response.status = std::move(status);
  _buffer.set_actual(sizeof(WriteAssetResponse));
  CompleterBase::SendReply(::fidl::DecodedMessage<WriteAssetResponse>(std::move(_buffer)));
}

void Paver::Interface::WriteAssetCompleterBase::Reply(::fidl::DecodedMessage<WriteAssetResponse> params) {
  params.message()->_hdr = {};
  params.message()->_hdr.ordinal = kPaver_WriteAsset_Ordinal;
  CompleterBase::SendReply(std::move(params));
}


void Paver::Interface::WriteVolumesCompleterBase::Reply(int32_t status) {
  constexpr uint32_t _kWriteAllocSize = ::fidl::internal::ClampedMessageSize<WriteVolumesResponse>();
  FIDL_ALIGNDECL uint8_t _write_bytes[_kWriteAllocSize] = {};
  auto& _response = *reinterpret_cast<WriteVolumesResponse*>(_write_bytes);
  _response._hdr.ordinal = kPaver_WriteVolumes_Ordinal;
  _response.status = std::move(status);
  ::fidl::BytePart _response_bytes(_write_bytes, _kWriteAllocSize, sizeof(WriteVolumesResponse));
  CompleterBase::SendReply(::fidl::DecodedMessage<WriteVolumesResponse>(std::move(_response_bytes)));
}

void Paver::Interface::WriteVolumesCompleterBase::Reply(::fidl::BytePart _buffer, int32_t status) {
  if (_buffer.capacity() < WriteVolumesResponse::PrimarySize) {
    CompleterBase::Close(ZX_ERR_INTERNAL);
    return;
  }
  auto& _response = *reinterpret_cast<WriteVolumesResponse*>(_buffer.data());
  _response._hdr.ordinal = kPaver_WriteVolumes_Ordinal;
  _response.status = std::move(status);
  _buffer.set_actual(sizeof(WriteVolumesResponse));
  CompleterBase::SendReply(::fidl::DecodedMessage<WriteVolumesResponse>(std::move(_buffer)));
}

void Paver::Interface::WriteVolumesCompleterBase::Reply(::fidl::DecodedMessage<WriteVolumesResponse> params) {
  params.message()->_hdr = {};
  params.message()->_hdr.ordinal = kPaver_WriteVolumes_Ordinal;
  CompleterBase::SendReply(std::move(params));
}


void Paver::Interface::WriteBootloaderCompleterBase::Reply(int32_t status) {
  constexpr uint32_t _kWriteAllocSize = ::fidl::internal::ClampedMessageSize<WriteBootloaderResponse>();
  FIDL_ALIGNDECL uint8_t _write_bytes[_kWriteAllocSize] = {};
  auto& _response = *reinterpret_cast<WriteBootloaderResponse*>(_write_bytes);
  _response._hdr.ordinal = kPaver_WriteBootloader_Ordinal;
  _response.status = std::move(status);
  ::fidl::BytePart _response_bytes(_write_bytes, _kWriteAllocSize, sizeof(WriteBootloaderResponse));
  CompleterBase::SendReply(::fidl::DecodedMessage<WriteBootloaderResponse>(std::move(_response_bytes)));
}

void Paver::Interface::WriteBootloaderCompleterBase::Reply(::fidl::BytePart _buffer, int32_t status) {
  if (_buffer.capacity() < WriteBootloaderResponse::PrimarySize) {
    CompleterBase::Close(ZX_ERR_INTERNAL);
    return;
  }
  auto& _response = *reinterpret_cast<WriteBootloaderResponse*>(_buffer.data());
  _response._hdr.ordinal = kPaver_WriteBootloader_Ordinal;
  _response.status = std::move(status);
  _buffer.set_actual(sizeof(WriteBootloaderResponse));
  CompleterBase::SendReply(::fidl::DecodedMessage<WriteBootloaderResponse>(std::move(_buffer)));
}

void Paver::Interface::WriteBootloaderCompleterBase::Reply(::fidl::DecodedMessage<WriteBootloaderResponse> params) {
  params.message()->_hdr = {};
  params.message()->_hdr.ordinal = kPaver_WriteBootloader_Ordinal;
  CompleterBase::SendReply(std::move(params));
}


void Paver::Interface::WriteDataFileCompleterBase::Reply(int32_t status) {
  constexpr uint32_t _kWriteAllocSize = ::fidl::internal::ClampedMessageSize<WriteDataFileResponse>();
  FIDL_ALIGNDECL uint8_t _write_bytes[_kWriteAllocSize] = {};
  auto& _response = *reinterpret_cast<WriteDataFileResponse*>(_write_bytes);
  _response._hdr.ordinal = kPaver_WriteDataFile_Ordinal;
  _response.status = std::move(status);
  ::fidl::BytePart _response_bytes(_write_bytes, _kWriteAllocSize, sizeof(WriteDataFileResponse));
  CompleterBase::SendReply(::fidl::DecodedMessage<WriteDataFileResponse>(std::move(_response_bytes)));
}

void Paver::Interface::WriteDataFileCompleterBase::Reply(::fidl::BytePart _buffer, int32_t status) {
  if (_buffer.capacity() < WriteDataFileResponse::PrimarySize) {
    CompleterBase::Close(ZX_ERR_INTERNAL);
    return;
  }
  auto& _response = *reinterpret_cast<WriteDataFileResponse*>(_buffer.data());
  _response._hdr.ordinal = kPaver_WriteDataFile_Ordinal;
  _response.status = std::move(status);
  _buffer.set_actual(sizeof(WriteDataFileResponse));
  CompleterBase::SendReply(::fidl::DecodedMessage<WriteDataFileResponse>(std::move(_buffer)));
}

void Paver::Interface::WriteDataFileCompleterBase::Reply(::fidl::DecodedMessage<WriteDataFileResponse> params) {
  params.message()->_hdr = {};
  params.message()->_hdr.ordinal = kPaver_WriteDataFile_Ordinal;
  CompleterBase::SendReply(std::move(params));
}


void Paver::Interface::WipeVolumesCompleterBase::Reply(int32_t status) {
  constexpr uint32_t _kWriteAllocSize = ::fidl::internal::ClampedMessageSize<WipeVolumesResponse>();
  FIDL_ALIGNDECL uint8_t _write_bytes[_kWriteAllocSize] = {};
  auto& _response = *reinterpret_cast<WipeVolumesResponse*>(_write_bytes);
  _response._hdr.ordinal = kPaver_WipeVolumes_Ordinal;
  _response.status = std::move(status);
  ::fidl::BytePart _response_bytes(_write_bytes, _kWriteAllocSize, sizeof(WipeVolumesResponse));
  CompleterBase::SendReply(::fidl::DecodedMessage<WipeVolumesResponse>(std::move(_response_bytes)));
}

void Paver::Interface::WipeVolumesCompleterBase::Reply(::fidl::BytePart _buffer, int32_t status) {
  if (_buffer.capacity() < WipeVolumesResponse::PrimarySize) {
    CompleterBase::Close(ZX_ERR_INTERNAL);
    return;
  }
  auto& _response = *reinterpret_cast<WipeVolumesResponse*>(_buffer.data());
  _response._hdr.ordinal = kPaver_WipeVolumes_Ordinal;
  _response.status = std::move(status);
  _buffer.set_actual(sizeof(WipeVolumesResponse));
  CompleterBase::SendReply(::fidl::DecodedMessage<WipeVolumesResponse>(std::move(_buffer)));
}

void Paver::Interface::WipeVolumesCompleterBase::Reply(::fidl::DecodedMessage<WipeVolumesResponse> params) {
  params.message()->_hdr = {};
  params.message()->_hdr.ordinal = kPaver_WipeVolumes_Ordinal;
  CompleterBase::SendReply(std::move(params));
}


}  // namespace paver
}  // namespace fuchsia
}  // namespace llcpp
