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

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

namespace llcpp {

namespace fuchsia {
namespace device {

::llcpp::fuchsia::device::NameProvider_GetDeviceName_Result::NameProvider_GetDeviceName_Result() {
  tag_ = Tag::Invalid;
}

::llcpp::fuchsia::device::NameProvider_GetDeviceName_Result::~NameProvider_GetDeviceName_Result() {
  Destroy();
}

void ::llcpp::fuchsia::device::NameProvider_GetDeviceName_Result::Destroy() {
  switch (which()) {
  case Tag::kResponse:
    response_.~NameProvider_GetDeviceName_Response();
    break;
  default:
    break;
  }
  tag_ = Tag::Invalid;
}

void ::llcpp::fuchsia::device::NameProvider_GetDeviceName_Result::MoveImpl_(NameProvider_GetDeviceName_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::device::NameProvider_GetDeviceName_Result::SizeAndOffsetAssertionHelper() {
  static_assert(offsetof(::llcpp::fuchsia::device::NameProvider_GetDeviceName_Result, response_) == 8);
  static_assert(offsetof(::llcpp::fuchsia::device::NameProvider_GetDeviceName_Result, err_) == 8);
  static_assert(sizeof(::llcpp::fuchsia::device::NameProvider_GetDeviceName_Result) == ::llcpp::fuchsia::device::NameProvider_GetDeviceName_Result::PrimarySize);
}


NameProvider_GetDeviceName_Response& ::llcpp::fuchsia::device::NameProvider_GetDeviceName_Result::mutable_response() {
  if (which() != Tag::kResponse) {
    Destroy();
    new (&response_) NameProvider_GetDeviceName_Response;
  }
  tag_ = Tag::kResponse;
  return response_;
}

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


namespace {

[[maybe_unused]]
constexpr uint64_t kNameProvider_GetDeviceName_Ordinal = 0x980ac2500000000lu;
[[maybe_unused]]
constexpr uint64_t kNameProvider_GetDeviceName_GenOrdinal = 0x6030de8d2052b2celu;
extern "C" const fidl_type_t fuchsia_device_NameProviderGetDeviceNameResponseTable;

}  // namespace
template <>
NameProvider::ResultOf::GetDeviceName_Impl<NameProvider::GetDeviceNameResponse>::GetDeviceName_Impl(zx::unowned_channel _client_end) {
  constexpr uint32_t _kWriteAllocSize = ::fidl::internal::ClampedMessageSize<GetDeviceNameRequest, ::fidl::MessageDirection::kSending>();
  ::fidl::internal::AlignedBuffer<_kWriteAllocSize> _write_bytes_inlined;
  auto& _write_bytes_array = _write_bytes_inlined;
  uint8_t* _write_bytes = _write_bytes_array.view().data();
  memset(_write_bytes, 0, GetDeviceNameRequest::PrimarySize);
  ::fidl::BytePart _request_bytes(_write_bytes, _kWriteAllocSize, sizeof(GetDeviceNameRequest));
  ::fidl::DecodedMessage<GetDeviceNameRequest> _decoded_request(std::move(_request_bytes));
  Super::SetResult(
      NameProvider::InPlace::GetDeviceName(std::move(_client_end), Super::response_buffer()));
}

NameProvider::ResultOf::GetDeviceName NameProvider::SyncClient::GetDeviceName() {
  return ResultOf::GetDeviceName(zx::unowned_channel(this->channel_));
}

NameProvider::ResultOf::GetDeviceName NameProvider::Call::GetDeviceName(zx::unowned_channel _client_end) {
  return ResultOf::GetDeviceName(std::move(_client_end));
}

template <>
NameProvider::UnownedResultOf::GetDeviceName_Impl<NameProvider::GetDeviceNameResponse>::GetDeviceName_Impl(zx::unowned_channel _client_end, ::fidl::BytePart _response_buffer) {
  FIDL_ALIGNDECL uint8_t _write_bytes[sizeof(GetDeviceNameRequest)] = {};
  ::fidl::BytePart _request_buffer(_write_bytes, sizeof(_write_bytes));
  memset(_request_buffer.data(), 0, GetDeviceNameRequest::PrimarySize);
  _request_buffer.set_actual(sizeof(GetDeviceNameRequest));
  ::fidl::DecodedMessage<GetDeviceNameRequest> _decoded_request(std::move(_request_buffer));
  Super::SetResult(
      NameProvider::InPlace::GetDeviceName(std::move(_client_end), std::move(_response_buffer)));
}

NameProvider::UnownedResultOf::GetDeviceName NameProvider::SyncClient::GetDeviceName(::fidl::BytePart _response_buffer) {
  return UnownedResultOf::GetDeviceName(zx::unowned_channel(this->channel_), std::move(_response_buffer));
}

NameProvider::UnownedResultOf::GetDeviceName NameProvider::Call::GetDeviceName(zx::unowned_channel _client_end, ::fidl::BytePart _response_buffer) {
  return UnownedResultOf::GetDeviceName(std::move(_client_end), std::move(_response_buffer));
}

::fidl::DecodeResult<NameProvider::GetDeviceNameResponse> NameProvider::InPlace::GetDeviceName(zx::unowned_channel _client_end, ::fidl::BytePart response_buffer) {
  constexpr uint32_t _write_num_bytes = sizeof(GetDeviceNameRequest);
  ::fidl::internal::AlignedBuffer<_write_num_bytes> _write_bytes;
  ::fidl::BytePart _request_buffer = _write_bytes.view();
  _request_buffer.set_actual(_write_num_bytes);
  ::fidl::DecodedMessage<GetDeviceNameRequest> params(std::move(_request_buffer));
  params.message()->_hdr = {};
  params.message()->_hdr.ordinal = kNameProvider_GetDeviceName_Ordinal;
  auto _encode_request_result = ::fidl::Encode(std::move(params));
  if (_encode_request_result.status != ZX_OK) {
    return ::fidl::DecodeResult<NameProvider::GetDeviceNameResponse>::FromFailure(
        std::move(_encode_request_result));
  }
  auto _call_result = ::fidl::Call<GetDeviceNameRequest, GetDeviceNameResponse>(
    std::move(_client_end), std::move(_encode_request_result.message), std::move(response_buffer));
  if (_call_result.status != ZX_OK) {
    return ::fidl::DecodeResult<NameProvider::GetDeviceNameResponse>::FromFailure(
        std::move(_call_result));
  }
  return ::fidl::Decode(std::move(_call_result.message));
}


bool NameProvider::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 kNameProvider_GetDeviceName_Ordinal:
    case kNameProvider_GetDeviceName_GenOrdinal:
    {
      auto result = ::fidl::DecodeAs<GetDeviceNameRequest>(msg);
      if (result.status != ZX_OK) {
        txn->Close(ZX_ERR_INVALID_ARGS);
        return true;
      }
      impl->GetDeviceName(
        Interface::GetDeviceNameCompleter::Sync(txn));
      return true;
    }
    default: {
      return false;
    }
  }
}

bool NameProvider::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 NameProvider::Interface::GetDeviceNameCompleterBase::Reply(NameProvider_GetDeviceName_Result result) {
  constexpr uint32_t _kWriteAllocSize = ::fidl::internal::ClampedMessageSize<GetDeviceNameResponse, ::fidl::MessageDirection::kSending>();
  FIDL_ALIGNDECL uint8_t _write_bytes[_kWriteAllocSize];
  GetDeviceNameResponse _response = {};
  _response._hdr.ordinal = kNameProvider_GetDeviceName_Ordinal;
  _response.result = std::move(result);
  auto _linearize_result = ::fidl::Linearize(&_response, ::fidl::BytePart(_write_bytes,
                                                                          _kWriteAllocSize));
  if (_linearize_result.status != ZX_OK) {
    CompleterBase::Close(ZX_ERR_INTERNAL);
    return;
  }
  CompleterBase::SendReply(std::move(_linearize_result.message));
}
void NameProvider::Interface::GetDeviceNameCompleterBase::ReplySuccess(::fidl::StringView name) {
  NameProvider_GetDeviceName_Response response;
  response.name = std::move(name);

  Reply(NameProvider_GetDeviceName_Result::WithResponse(std::move(response)));
}
void NameProvider::Interface::GetDeviceNameCompleterBase::ReplyError(int32_t error) {
  Reply(NameProvider_GetDeviceName_Result::WithErr(std::move(error)));
}

void NameProvider::Interface::GetDeviceNameCompleterBase::Reply(::fidl::BytePart _buffer, NameProvider_GetDeviceName_Result result) {
  if (_buffer.capacity() < GetDeviceNameResponse::PrimarySize) {
    CompleterBase::Close(ZX_ERR_INTERNAL);
    return;
  }
  GetDeviceNameResponse _response = {};
  _response._hdr.ordinal = kNameProvider_GetDeviceName_Ordinal;
  _response.result = std::move(result);
  auto _linearize_result = ::fidl::Linearize(&_response, std::move(_buffer));
  if (_linearize_result.status != ZX_OK) {
    CompleterBase::Close(ZX_ERR_INTERNAL);
    return;
  }
  CompleterBase::SendReply(std::move(_linearize_result.message));
}
void NameProvider::Interface::GetDeviceNameCompleterBase::ReplySuccess(::fidl::BytePart _buffer, ::fidl::StringView name) {
  NameProvider_GetDeviceName_Response response;
  response.name = std::move(name);

  Reply(std::move(_buffer), NameProvider_GetDeviceName_Result::WithResponse(std::move(response)));
}

void NameProvider::Interface::GetDeviceNameCompleterBase::Reply(::fidl::DecodedMessage<GetDeviceNameResponse> params) {
  params.message()->_hdr = {};
  params.message()->_hdr.ordinal = kNameProvider_GetDeviceName_Ordinal;
  CompleterBase::SendReply(std::move(params));
}


::llcpp::fuchsia::device::Controller_GetPowerStateMapping_Result::Controller_GetPowerStateMapping_Result() {
  tag_ = Tag::Invalid;
}

::llcpp::fuchsia::device::Controller_GetPowerStateMapping_Result::~Controller_GetPowerStateMapping_Result() {
  Destroy();
}

void ::llcpp::fuchsia::device::Controller_GetPowerStateMapping_Result::Destroy() {
  switch (which()) {
  case Tag::kResponse:
    response_.~Controller_GetPowerStateMapping_Response();
    break;
  default:
    break;
  }
  tag_ = Tag::Invalid;
}

void ::llcpp::fuchsia::device::Controller_GetPowerStateMapping_Result::MoveImpl_(Controller_GetPowerStateMapping_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::device::Controller_GetPowerStateMapping_Result::SizeAndOffsetAssertionHelper() {
  static_assert(offsetof(::llcpp::fuchsia::device::Controller_GetPowerStateMapping_Result, response_) == 4);
  static_assert(offsetof(::llcpp::fuchsia::device::Controller_GetPowerStateMapping_Result, err_) == 4);
  static_assert(sizeof(::llcpp::fuchsia::device::Controller_GetPowerStateMapping_Result) == ::llcpp::fuchsia::device::Controller_GetPowerStateMapping_Result::PrimarySize);
}


Controller_GetPowerStateMapping_Response& ::llcpp::fuchsia::device::Controller_GetPowerStateMapping_Result::mutable_response() {
  if (which() != Tag::kResponse) {
    Destroy();
    new (&response_) Controller_GetPowerStateMapping_Response;
  }
  tag_ = Tag::kResponse;
  return response_;
}

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


::llcpp::fuchsia::device::Controller_GetDevicePowerCaps_Result::Controller_GetDevicePowerCaps_Result() {
  tag_ = Tag::Invalid;
}

::llcpp::fuchsia::device::Controller_GetDevicePowerCaps_Result::~Controller_GetDevicePowerCaps_Result() {
  Destroy();
}

void ::llcpp::fuchsia::device::Controller_GetDevicePowerCaps_Result::Destroy() {
  switch (which()) {
  case Tag::kResponse:
    response_.~Controller_GetDevicePowerCaps_Response();
    break;
  default:
    break;
  }
  tag_ = Tag::Invalid;
}

void ::llcpp::fuchsia::device::Controller_GetDevicePowerCaps_Result::MoveImpl_(Controller_GetDevicePowerCaps_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::device::Controller_GetDevicePowerCaps_Result::SizeAndOffsetAssertionHelper() {
  static_assert(offsetof(::llcpp::fuchsia::device::Controller_GetDevicePowerCaps_Result, response_) == 8);
  static_assert(offsetof(::llcpp::fuchsia::device::Controller_GetDevicePowerCaps_Result, err_) == 8);
  static_assert(sizeof(::llcpp::fuchsia::device::Controller_GetDevicePowerCaps_Result) == ::llcpp::fuchsia::device::Controller_GetDevicePowerCaps_Result::PrimarySize);
}


Controller_GetDevicePowerCaps_Response& ::llcpp::fuchsia::device::Controller_GetDevicePowerCaps_Result::mutable_response() {
  if (which() != Tag::kResponse) {
    Destroy();
    new (&response_) Controller_GetDevicePowerCaps_Response;
  }
  tag_ = Tag::kResponse;
  return response_;
}

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


::llcpp::fuchsia::device::Controller_Resume_Result::Controller_Resume_Result() {
  tag_ = Tag::Invalid;
}

::llcpp::fuchsia::device::Controller_Resume_Result::~Controller_Resume_Result() {
  Destroy();
}

void ::llcpp::fuchsia::device::Controller_Resume_Result::Destroy() {
  switch (which()) {
  case Tag::kResponse:
    response_.~Controller_Resume_Response();
    break;
  default:
    break;
  }
  tag_ = Tag::Invalid;
}

void ::llcpp::fuchsia::device::Controller_Resume_Result::MoveImpl_(Controller_Resume_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::device::Controller_Resume_Result::SizeAndOffsetAssertionHelper() {
  static_assert(offsetof(::llcpp::fuchsia::device::Controller_Resume_Result, response_) == 4);
  static_assert(offsetof(::llcpp::fuchsia::device::Controller_Resume_Result, err_) == 4);
  static_assert(sizeof(::llcpp::fuchsia::device::Controller_Resume_Result) == ::llcpp::fuchsia::device::Controller_Resume_Result::PrimarySize);
}


Controller_Resume_Response& ::llcpp::fuchsia::device::Controller_Resume_Result::mutable_response() {
  if (which() != Tag::kResponse) {
    Destroy();
    new (&response_) Controller_Resume_Response;
  }
  tag_ = Tag::kResponse;
  return response_;
}

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

const char DEFAULT_DEVICE_NAME[] = "fuchsia";

::llcpp::fuchsia::device::Controller_UpdatePowerStateMapping_Result::Controller_UpdatePowerStateMapping_Result() {
  tag_ = Tag::Invalid;
}

::llcpp::fuchsia::device::Controller_UpdatePowerStateMapping_Result::~Controller_UpdatePowerStateMapping_Result() {
  Destroy();
}

void ::llcpp::fuchsia::device::Controller_UpdatePowerStateMapping_Result::Destroy() {
  switch (which()) {
  case Tag::kResponse:
    response_.~Controller_UpdatePowerStateMapping_Response();
    break;
  default:
    break;
  }
  tag_ = Tag::Invalid;
}

void ::llcpp::fuchsia::device::Controller_UpdatePowerStateMapping_Result::MoveImpl_(Controller_UpdatePowerStateMapping_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::device::Controller_UpdatePowerStateMapping_Result::SizeAndOffsetAssertionHelper() {
  static_assert(offsetof(::llcpp::fuchsia::device::Controller_UpdatePowerStateMapping_Result, response_) == 4);
  static_assert(offsetof(::llcpp::fuchsia::device::Controller_UpdatePowerStateMapping_Result, err_) == 4);
  static_assert(sizeof(::llcpp::fuchsia::device::Controller_UpdatePowerStateMapping_Result) == ::llcpp::fuchsia::device::Controller_UpdatePowerStateMapping_Result::PrimarySize);
}


Controller_UpdatePowerStateMapping_Response& ::llcpp::fuchsia::device::Controller_UpdatePowerStateMapping_Result::mutable_response() {
  if (which() != Tag::kResponse) {
    Destroy();
    new (&response_) Controller_UpdatePowerStateMapping_Response;
  }
  tag_ = Tag::kResponse;
  return response_;
}

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


namespace {

[[maybe_unused]]
constexpr uint64_t kController_Bind_Ordinal = 0x30b1cd5d00000000lu;
[[maybe_unused]]
constexpr uint64_t kController_Bind_GenOrdinal = 0x3388f12801462769lu;
extern "C" const fidl_type_t fuchsia_device_ControllerBindRequestTable;
extern "C" const fidl_type_t fuchsia_device_ControllerBindResponseTable;
[[maybe_unused]]
constexpr uint64_t kController_ScheduleUnbind_Ordinal = 0xd0cd4ba00000000lu;
[[maybe_unused]]
constexpr uint64_t kController_ScheduleUnbind_GenOrdinal = 0x6128ba9d76aff9clu;
extern "C" const fidl_type_t fuchsia_device_ControllerScheduleUnbindResponseTable;
[[maybe_unused]]
constexpr uint64_t kController_GetDriverName_Ordinal = 0x76995acd00000000lu;
[[maybe_unused]]
constexpr uint64_t kController_GetDriverName_GenOrdinal = 0x26f6ecf97738afe8lu;
extern "C" const fidl_type_t fuchsia_device_ControllerGetDriverNameResponseTable;
[[maybe_unused]]
constexpr uint64_t kController_GetDeviceName_Ordinal = 0x377a34e000000000lu;
[[maybe_unused]]
constexpr uint64_t kController_GetDeviceName_GenOrdinal = 0x69220024bb341abelu;
extern "C" const fidl_type_t fuchsia_device_ControllerGetDeviceNameResponseTable;
[[maybe_unused]]
constexpr uint64_t kController_GetTopologicalPath_Ordinal = 0x430fc2d600000000lu;
[[maybe_unused]]
constexpr uint64_t kController_GetTopologicalPath_GenOrdinal = 0x2689b37663e00788lu;
extern "C" const fidl_type_t fuchsia_device_ControllerGetTopologicalPathResponseTable;
[[maybe_unused]]
constexpr uint64_t kController_GetEventHandle_Ordinal = 0x73cacb3600000000lu;
[[maybe_unused]]
constexpr uint64_t kController_GetEventHandle_GenOrdinal = 0x60b4bf1536cb0ef4lu;
extern "C" const fidl_type_t fuchsia_device_ControllerGetEventHandleResponseTable;
[[maybe_unused]]
constexpr uint64_t kController_GetDriverLogFlags_Ordinal = 0x5c5b709300000000lu;
[[maybe_unused]]
constexpr uint64_t kController_GetDriverLogFlags_GenOrdinal = 0x7272c2cf685f4b16lu;
[[maybe_unused]]
constexpr uint64_t kController_SetDriverLogFlags_Ordinal = 0x7d56732b00000000lu;
[[maybe_unused]]
constexpr uint64_t kController_SetDriverLogFlags_GenOrdinal = 0x45a98c40a24b8cf0lu;
extern "C" const fidl_type_t fuchsia_device_ControllerSetDriverLogFlagsResponseTable;
[[maybe_unused]]
constexpr uint64_t kController_DebugSuspend_Ordinal = 0x65f2322400000000lu;
[[maybe_unused]]
constexpr uint64_t kController_DebugSuspend_GenOrdinal = 0x37827c5e2f45e12elu;
extern "C" const fidl_type_t fuchsia_device_ControllerDebugSuspendResponseTable;
[[maybe_unused]]
constexpr uint64_t kController_DebugResume_Ordinal = 0x5fee29c400000000lu;
[[maybe_unused]]
constexpr uint64_t kController_DebugResume_GenOrdinal = 0xe1555cdd68b40e6lu;
extern "C" const fidl_type_t fuchsia_device_ControllerDebugResumeResponseTable;
[[maybe_unused]]
constexpr uint64_t kController_RunCompatibilityTests_Ordinal = 0x484cd9af00000000lu;
[[maybe_unused]]
constexpr uint64_t kController_RunCompatibilityTests_GenOrdinal = 0x58268c9ba1dc54d1lu;
extern "C" const fidl_type_t fuchsia_device_ControllerRunCompatibilityTestsResponseTable;
[[maybe_unused]]
constexpr uint64_t kController_GetDevicePowerCaps_Ordinal = 0x70a9ecf200000000lu;
[[maybe_unused]]
constexpr uint64_t kController_GetDevicePowerCaps_GenOrdinal = 0x19acb37026ae22dlu;
extern "C" const fidl_type_t fuchsia_device_ControllerGetDevicePowerCapsResponseTable;
[[maybe_unused]]
constexpr uint64_t kController_UpdatePowerStateMapping_Ordinal = 0x5200982600000000lu;
[[maybe_unused]]
constexpr uint64_t kController_UpdatePowerStateMapping_GenOrdinal = 0x185489481614d7a6lu;
extern "C" const fidl_type_t fuchsia_device_ControllerUpdatePowerStateMappingRequestTable;
extern "C" const fidl_type_t fuchsia_device_ControllerUpdatePowerStateMappingResponseTable;
[[maybe_unused]]
constexpr uint64_t kController_GetPowerStateMapping_Ordinal = 0x4ca6662900000000lu;
[[maybe_unused]]
constexpr uint64_t kController_GetPowerStateMapping_GenOrdinal = 0x1a509f4010ee5cbelu;
extern "C" const fidl_type_t fuchsia_device_ControllerGetPowerStateMappingResponseTable;
[[maybe_unused]]
constexpr uint64_t kController_Suspend_Ordinal = 0x5897568300000000lu;
[[maybe_unused]]
constexpr uint64_t kController_Suspend_GenOrdinal = 0x6af131a48f7c8fdalu;
extern "C" const fidl_type_t fuchsia_device_ControllerSuspendRequestTable;
extern "C" const fidl_type_t fuchsia_device_ControllerSuspendResponseTable;
[[maybe_unused]]
constexpr uint64_t kController_Resume_Ordinal = 0x363da84d00000000lu;
[[maybe_unused]]
constexpr uint64_t kController_Resume_GenOrdinal = 0x22c86261fd50a61elu;
extern "C" const fidl_type_t fuchsia_device_ControllerResumeRequestTable;
extern "C" const fidl_type_t fuchsia_device_ControllerResumeResponseTable;

}  // namespace
template <>
Controller::ResultOf::Bind_Impl<Controller::BindResponse>::Bind_Impl(zx::unowned_channel _client_end, ::fidl::StringView driver) {
  constexpr uint32_t _kWriteAllocSize = ::fidl::internal::ClampedMessageSize<BindRequest, ::fidl::MessageDirection::kSending>();
  std::unique_ptr _write_bytes_boxed = std::make_unique<::fidl::internal::AlignedBuffer<_kWriteAllocSize>>();
  auto& _write_bytes_array = *_write_bytes_boxed;
  BindRequest _request = {};
  _request.driver = std::move(driver);
  auto _linearize_result = ::fidl::Linearize(&_request, _write_bytes_array.view());
  if (_linearize_result.status != ZX_OK) {
    Super::SetFailure(std::move(_linearize_result));
    return;
  }
  ::fidl::DecodedMessage<BindRequest> _decoded_request = std::move(_linearize_result.message);
  Super::SetResult(
      Controller::InPlace::Bind(std::move(_client_end), std::move(_decoded_request), Super::response_buffer()));
}

Controller::ResultOf::Bind Controller::SyncClient::Bind(::fidl::StringView driver) {
  return ResultOf::Bind(zx::unowned_channel(this->channel_), std::move(driver));
}

Controller::ResultOf::Bind Controller::Call::Bind(zx::unowned_channel _client_end, ::fidl::StringView driver) {
  return ResultOf::Bind(std::move(_client_end), std::move(driver));
}

template <>
Controller::UnownedResultOf::Bind_Impl<Controller::BindResponse>::Bind_Impl(zx::unowned_channel _client_end, ::fidl::BytePart _request_buffer, ::fidl::StringView driver, ::fidl::BytePart _response_buffer) {
  if (_request_buffer.capacity() < BindRequest::PrimarySize) {
    Super::SetFailure(::fidl::DecodeResult<BindResponse>(ZX_ERR_BUFFER_TOO_SMALL, ::fidl::internal::kErrorRequestBufferTooSmall));
    return;
  }
  BindRequest _request = {};
  _request.driver = std::move(driver);
  auto _linearize_result = ::fidl::Linearize(&_request, std::move(_request_buffer));
  if (_linearize_result.status != ZX_OK) {
    Super::SetFailure(std::move(_linearize_result));
    return;
  }
  ::fidl::DecodedMessage<BindRequest> _decoded_request = std::move(_linearize_result.message);
  Super::SetResult(
      Controller::InPlace::Bind(std::move(_client_end), std::move(_decoded_request), std::move(_response_buffer)));
}

Controller::UnownedResultOf::Bind Controller::SyncClient::Bind(::fidl::BytePart _request_buffer, ::fidl::StringView driver, ::fidl::BytePart _response_buffer) {
  return UnownedResultOf::Bind(zx::unowned_channel(this->channel_), std::move(_request_buffer), std::move(driver), std::move(_response_buffer));
}

Controller::UnownedResultOf::Bind Controller::Call::Bind(zx::unowned_channel _client_end, ::fidl::BytePart _request_buffer, ::fidl::StringView driver, ::fidl::BytePart _response_buffer) {
  return UnownedResultOf::Bind(std::move(_client_end), std::move(_request_buffer), std::move(driver), std::move(_response_buffer));
}

::fidl::DecodeResult<Controller::BindResponse> Controller::InPlace::Bind(zx::unowned_channel _client_end, ::fidl::DecodedMessage<BindRequest> params, ::fidl::BytePart response_buffer) {
  params.message()->_hdr = {};
  params.message()->_hdr.ordinal = kController_Bind_Ordinal;
  auto _encode_request_result = ::fidl::Encode(std::move(params));
  if (_encode_request_result.status != ZX_OK) {
    return ::fidl::DecodeResult<Controller::BindResponse>::FromFailure(
        std::move(_encode_request_result));
  }
  auto _call_result = ::fidl::Call<BindRequest, BindResponse>(
    std::move(_client_end), std::move(_encode_request_result.message), std::move(response_buffer));
  if (_call_result.status != ZX_OK) {
    return ::fidl::DecodeResult<Controller::BindResponse>::FromFailure(
        std::move(_call_result));
  }
  return ::fidl::Decode(std::move(_call_result.message));
}

template <>
Controller::ResultOf::ScheduleUnbind_Impl<Controller::ScheduleUnbindResponse>::ScheduleUnbind_Impl(zx::unowned_channel _client_end) {
  constexpr uint32_t _kWriteAllocSize = ::fidl::internal::ClampedMessageSize<ScheduleUnbindRequest, ::fidl::MessageDirection::kSending>();
  ::fidl::internal::AlignedBuffer<_kWriteAllocSize> _write_bytes_inlined;
  auto& _write_bytes_array = _write_bytes_inlined;
  uint8_t* _write_bytes = _write_bytes_array.view().data();
  memset(_write_bytes, 0, ScheduleUnbindRequest::PrimarySize);
  ::fidl::BytePart _request_bytes(_write_bytes, _kWriteAllocSize, sizeof(ScheduleUnbindRequest));
  ::fidl::DecodedMessage<ScheduleUnbindRequest> _decoded_request(std::move(_request_bytes));
  Super::SetResult(
      Controller::InPlace::ScheduleUnbind(std::move(_client_end), Super::response_buffer()));
}

Controller::ResultOf::ScheduleUnbind Controller::SyncClient::ScheduleUnbind() {
  return ResultOf::ScheduleUnbind(zx::unowned_channel(this->channel_));
}

Controller::ResultOf::ScheduleUnbind Controller::Call::ScheduleUnbind(zx::unowned_channel _client_end) {
  return ResultOf::ScheduleUnbind(std::move(_client_end));
}

template <>
Controller::UnownedResultOf::ScheduleUnbind_Impl<Controller::ScheduleUnbindResponse>::ScheduleUnbind_Impl(zx::unowned_channel _client_end, ::fidl::BytePart _response_buffer) {
  FIDL_ALIGNDECL uint8_t _write_bytes[sizeof(ScheduleUnbindRequest)] = {};
  ::fidl::BytePart _request_buffer(_write_bytes, sizeof(_write_bytes));
  memset(_request_buffer.data(), 0, ScheduleUnbindRequest::PrimarySize);
  _request_buffer.set_actual(sizeof(ScheduleUnbindRequest));
  ::fidl::DecodedMessage<ScheduleUnbindRequest> _decoded_request(std::move(_request_buffer));
  Super::SetResult(
      Controller::InPlace::ScheduleUnbind(std::move(_client_end), std::move(_response_buffer)));
}

Controller::UnownedResultOf::ScheduleUnbind Controller::SyncClient::ScheduleUnbind(::fidl::BytePart _response_buffer) {
  return UnownedResultOf::ScheduleUnbind(zx::unowned_channel(this->channel_), std::move(_response_buffer));
}

Controller::UnownedResultOf::ScheduleUnbind Controller::Call::ScheduleUnbind(zx::unowned_channel _client_end, ::fidl::BytePart _response_buffer) {
  return UnownedResultOf::ScheduleUnbind(std::move(_client_end), std::move(_response_buffer));
}

::fidl::DecodeResult<Controller::ScheduleUnbindResponse> Controller::InPlace::ScheduleUnbind(zx::unowned_channel _client_end, ::fidl::BytePart response_buffer) {
  constexpr uint32_t _write_num_bytes = sizeof(ScheduleUnbindRequest);
  ::fidl::internal::AlignedBuffer<_write_num_bytes> _write_bytes;
  ::fidl::BytePart _request_buffer = _write_bytes.view();
  _request_buffer.set_actual(_write_num_bytes);
  ::fidl::DecodedMessage<ScheduleUnbindRequest> params(std::move(_request_buffer));
  params.message()->_hdr = {};
  params.message()->_hdr.ordinal = kController_ScheduleUnbind_Ordinal;
  auto _encode_request_result = ::fidl::Encode(std::move(params));
  if (_encode_request_result.status != ZX_OK) {
    return ::fidl::DecodeResult<Controller::ScheduleUnbindResponse>::FromFailure(
        std::move(_encode_request_result));
  }
  auto _call_result = ::fidl::Call<ScheduleUnbindRequest, ScheduleUnbindResponse>(
    std::move(_client_end), std::move(_encode_request_result.message), std::move(response_buffer));
  if (_call_result.status != ZX_OK) {
    return ::fidl::DecodeResult<Controller::ScheduleUnbindResponse>::FromFailure(
        std::move(_call_result));
  }
  return ::fidl::Decode(std::move(_call_result.message));
}

template <>
Controller::ResultOf::GetDriverName_Impl<Controller::GetDriverNameResponse>::GetDriverName_Impl(zx::unowned_channel _client_end) {
  constexpr uint32_t _kWriteAllocSize = ::fidl::internal::ClampedMessageSize<GetDriverNameRequest, ::fidl::MessageDirection::kSending>();
  ::fidl::internal::AlignedBuffer<_kWriteAllocSize> _write_bytes_inlined;
  auto& _write_bytes_array = _write_bytes_inlined;
  uint8_t* _write_bytes = _write_bytes_array.view().data();
  memset(_write_bytes, 0, GetDriverNameRequest::PrimarySize);
  ::fidl::BytePart _request_bytes(_write_bytes, _kWriteAllocSize, sizeof(GetDriverNameRequest));
  ::fidl::DecodedMessage<GetDriverNameRequest> _decoded_request(std::move(_request_bytes));
  Super::SetResult(
      Controller::InPlace::GetDriverName(std::move(_client_end), Super::response_buffer()));
}

Controller::ResultOf::GetDriverName Controller::SyncClient::GetDriverName() {
  return ResultOf::GetDriverName(zx::unowned_channel(this->channel_));
}

Controller::ResultOf::GetDriverName Controller::Call::GetDriverName(zx::unowned_channel _client_end) {
  return ResultOf::GetDriverName(std::move(_client_end));
}

template <>
Controller::UnownedResultOf::GetDriverName_Impl<Controller::GetDriverNameResponse>::GetDriverName_Impl(zx::unowned_channel _client_end, ::fidl::BytePart _response_buffer) {
  FIDL_ALIGNDECL uint8_t _write_bytes[sizeof(GetDriverNameRequest)] = {};
  ::fidl::BytePart _request_buffer(_write_bytes, sizeof(_write_bytes));
  memset(_request_buffer.data(), 0, GetDriverNameRequest::PrimarySize);
  _request_buffer.set_actual(sizeof(GetDriverNameRequest));
  ::fidl::DecodedMessage<GetDriverNameRequest> _decoded_request(std::move(_request_buffer));
  Super::SetResult(
      Controller::InPlace::GetDriverName(std::move(_client_end), std::move(_response_buffer)));
}

Controller::UnownedResultOf::GetDriverName Controller::SyncClient::GetDriverName(::fidl::BytePart _response_buffer) {
  return UnownedResultOf::GetDriverName(zx::unowned_channel(this->channel_), std::move(_response_buffer));
}

Controller::UnownedResultOf::GetDriverName Controller::Call::GetDriverName(zx::unowned_channel _client_end, ::fidl::BytePart _response_buffer) {
  return UnownedResultOf::GetDriverName(std::move(_client_end), std::move(_response_buffer));
}

::fidl::DecodeResult<Controller::GetDriverNameResponse> Controller::InPlace::GetDriverName(zx::unowned_channel _client_end, ::fidl::BytePart response_buffer) {
  constexpr uint32_t _write_num_bytes = sizeof(GetDriverNameRequest);
  ::fidl::internal::AlignedBuffer<_write_num_bytes> _write_bytes;
  ::fidl::BytePart _request_buffer = _write_bytes.view();
  _request_buffer.set_actual(_write_num_bytes);
  ::fidl::DecodedMessage<GetDriverNameRequest> params(std::move(_request_buffer));
  params.message()->_hdr = {};
  params.message()->_hdr.ordinal = kController_GetDriverName_Ordinal;
  auto _encode_request_result = ::fidl::Encode(std::move(params));
  if (_encode_request_result.status != ZX_OK) {
    return ::fidl::DecodeResult<Controller::GetDriverNameResponse>::FromFailure(
        std::move(_encode_request_result));
  }
  auto _call_result = ::fidl::Call<GetDriverNameRequest, GetDriverNameResponse>(
    std::move(_client_end), std::move(_encode_request_result.message), std::move(response_buffer));
  if (_call_result.status != ZX_OK) {
    return ::fidl::DecodeResult<Controller::GetDriverNameResponse>::FromFailure(
        std::move(_call_result));
  }
  return ::fidl::Decode(std::move(_call_result.message));
}

template <>
Controller::ResultOf::GetDeviceName_Impl<Controller::GetDeviceNameResponse>::GetDeviceName_Impl(zx::unowned_channel _client_end) {
  constexpr uint32_t _kWriteAllocSize = ::fidl::internal::ClampedMessageSize<GetDeviceNameRequest, ::fidl::MessageDirection::kSending>();
  ::fidl::internal::AlignedBuffer<_kWriteAllocSize> _write_bytes_inlined;
  auto& _write_bytes_array = _write_bytes_inlined;
  uint8_t* _write_bytes = _write_bytes_array.view().data();
  memset(_write_bytes, 0, GetDeviceNameRequest::PrimarySize);
  ::fidl::BytePart _request_bytes(_write_bytes, _kWriteAllocSize, sizeof(GetDeviceNameRequest));
  ::fidl::DecodedMessage<GetDeviceNameRequest> _decoded_request(std::move(_request_bytes));
  Super::SetResult(
      Controller::InPlace::GetDeviceName(std::move(_client_end), Super::response_buffer()));
}

Controller::ResultOf::GetDeviceName Controller::SyncClient::GetDeviceName() {
  return ResultOf::GetDeviceName(zx::unowned_channel(this->channel_));
}

Controller::ResultOf::GetDeviceName Controller::Call::GetDeviceName(zx::unowned_channel _client_end) {
  return ResultOf::GetDeviceName(std::move(_client_end));
}

template <>
Controller::UnownedResultOf::GetDeviceName_Impl<Controller::GetDeviceNameResponse>::GetDeviceName_Impl(zx::unowned_channel _client_end, ::fidl::BytePart _response_buffer) {
  FIDL_ALIGNDECL uint8_t _write_bytes[sizeof(GetDeviceNameRequest)] = {};
  ::fidl::BytePart _request_buffer(_write_bytes, sizeof(_write_bytes));
  memset(_request_buffer.data(), 0, GetDeviceNameRequest::PrimarySize);
  _request_buffer.set_actual(sizeof(GetDeviceNameRequest));
  ::fidl::DecodedMessage<GetDeviceNameRequest> _decoded_request(std::move(_request_buffer));
  Super::SetResult(
      Controller::InPlace::GetDeviceName(std::move(_client_end), std::move(_response_buffer)));
}

Controller::UnownedResultOf::GetDeviceName Controller::SyncClient::GetDeviceName(::fidl::BytePart _response_buffer) {
  return UnownedResultOf::GetDeviceName(zx::unowned_channel(this->channel_), std::move(_response_buffer));
}

Controller::UnownedResultOf::GetDeviceName Controller::Call::GetDeviceName(zx::unowned_channel _client_end, ::fidl::BytePart _response_buffer) {
  return UnownedResultOf::GetDeviceName(std::move(_client_end), std::move(_response_buffer));
}

::fidl::DecodeResult<Controller::GetDeviceNameResponse> Controller::InPlace::GetDeviceName(zx::unowned_channel _client_end, ::fidl::BytePart response_buffer) {
  constexpr uint32_t _write_num_bytes = sizeof(GetDeviceNameRequest);
  ::fidl::internal::AlignedBuffer<_write_num_bytes> _write_bytes;
  ::fidl::BytePart _request_buffer = _write_bytes.view();
  _request_buffer.set_actual(_write_num_bytes);
  ::fidl::DecodedMessage<GetDeviceNameRequest> params(std::move(_request_buffer));
  params.message()->_hdr = {};
  params.message()->_hdr.ordinal = kController_GetDeviceName_Ordinal;
  auto _encode_request_result = ::fidl::Encode(std::move(params));
  if (_encode_request_result.status != ZX_OK) {
    return ::fidl::DecodeResult<Controller::GetDeviceNameResponse>::FromFailure(
        std::move(_encode_request_result));
  }
  auto _call_result = ::fidl::Call<GetDeviceNameRequest, GetDeviceNameResponse>(
    std::move(_client_end), std::move(_encode_request_result.message), std::move(response_buffer));
  if (_call_result.status != ZX_OK) {
    return ::fidl::DecodeResult<Controller::GetDeviceNameResponse>::FromFailure(
        std::move(_call_result));
  }
  return ::fidl::Decode(std::move(_call_result.message));
}

template <>
Controller::ResultOf::GetTopologicalPath_Impl<Controller::GetTopologicalPathResponse>::GetTopologicalPath_Impl(zx::unowned_channel _client_end) {
  constexpr uint32_t _kWriteAllocSize = ::fidl::internal::ClampedMessageSize<GetTopologicalPathRequest, ::fidl::MessageDirection::kSending>();
  ::fidl::internal::AlignedBuffer<_kWriteAllocSize> _write_bytes_inlined;
  auto& _write_bytes_array = _write_bytes_inlined;
  uint8_t* _write_bytes = _write_bytes_array.view().data();
  memset(_write_bytes, 0, GetTopologicalPathRequest::PrimarySize);
  ::fidl::BytePart _request_bytes(_write_bytes, _kWriteAllocSize, sizeof(GetTopologicalPathRequest));
  ::fidl::DecodedMessage<GetTopologicalPathRequest> _decoded_request(std::move(_request_bytes));
  Super::SetResult(
      Controller::InPlace::GetTopologicalPath(std::move(_client_end), Super::response_buffer()));
}

Controller::ResultOf::GetTopologicalPath Controller::SyncClient::GetTopologicalPath() {
  return ResultOf::GetTopologicalPath(zx::unowned_channel(this->channel_));
}

Controller::ResultOf::GetTopologicalPath Controller::Call::GetTopologicalPath(zx::unowned_channel _client_end) {
  return ResultOf::GetTopologicalPath(std::move(_client_end));
}

template <>
Controller::UnownedResultOf::GetTopologicalPath_Impl<Controller::GetTopologicalPathResponse>::GetTopologicalPath_Impl(zx::unowned_channel _client_end, ::fidl::BytePart _response_buffer) {
  FIDL_ALIGNDECL uint8_t _write_bytes[sizeof(GetTopologicalPathRequest)] = {};
  ::fidl::BytePart _request_buffer(_write_bytes, sizeof(_write_bytes));
  memset(_request_buffer.data(), 0, GetTopologicalPathRequest::PrimarySize);
  _request_buffer.set_actual(sizeof(GetTopologicalPathRequest));
  ::fidl::DecodedMessage<GetTopologicalPathRequest> _decoded_request(std::move(_request_buffer));
  Super::SetResult(
      Controller::InPlace::GetTopologicalPath(std::move(_client_end), std::move(_response_buffer)));
}

Controller::UnownedResultOf::GetTopologicalPath Controller::SyncClient::GetTopologicalPath(::fidl::BytePart _response_buffer) {
  return UnownedResultOf::GetTopologicalPath(zx::unowned_channel(this->channel_), std::move(_response_buffer));
}

Controller::UnownedResultOf::GetTopologicalPath Controller::Call::GetTopologicalPath(zx::unowned_channel _client_end, ::fidl::BytePart _response_buffer) {
  return UnownedResultOf::GetTopologicalPath(std::move(_client_end), std::move(_response_buffer));
}

::fidl::DecodeResult<Controller::GetTopologicalPathResponse> Controller::InPlace::GetTopologicalPath(zx::unowned_channel _client_end, ::fidl::BytePart response_buffer) {
  constexpr uint32_t _write_num_bytes = sizeof(GetTopologicalPathRequest);
  ::fidl::internal::AlignedBuffer<_write_num_bytes> _write_bytes;
  ::fidl::BytePart _request_buffer = _write_bytes.view();
  _request_buffer.set_actual(_write_num_bytes);
  ::fidl::DecodedMessage<GetTopologicalPathRequest> params(std::move(_request_buffer));
  params.message()->_hdr = {};
  params.message()->_hdr.ordinal = kController_GetTopologicalPath_Ordinal;
  auto _encode_request_result = ::fidl::Encode(std::move(params));
  if (_encode_request_result.status != ZX_OK) {
    return ::fidl::DecodeResult<Controller::GetTopologicalPathResponse>::FromFailure(
        std::move(_encode_request_result));
  }
  auto _call_result = ::fidl::Call<GetTopologicalPathRequest, GetTopologicalPathResponse>(
    std::move(_client_end), std::move(_encode_request_result.message), std::move(response_buffer));
  if (_call_result.status != ZX_OK) {
    return ::fidl::DecodeResult<Controller::GetTopologicalPathResponse>::FromFailure(
        std::move(_call_result));
  }
  return ::fidl::Decode(std::move(_call_result.message));
}

template <>
Controller::ResultOf::GetEventHandle_Impl<Controller::GetEventHandleResponse>::GetEventHandle_Impl(zx::unowned_channel _client_end) {
  constexpr uint32_t _kWriteAllocSize = ::fidl::internal::ClampedMessageSize<GetEventHandleRequest, ::fidl::MessageDirection::kSending>();
  ::fidl::internal::AlignedBuffer<_kWriteAllocSize> _write_bytes_inlined;
  auto& _write_bytes_array = _write_bytes_inlined;
  uint8_t* _write_bytes = _write_bytes_array.view().data();
  memset(_write_bytes, 0, GetEventHandleRequest::PrimarySize);
  ::fidl::BytePart _request_bytes(_write_bytes, _kWriteAllocSize, sizeof(GetEventHandleRequest));
  ::fidl::DecodedMessage<GetEventHandleRequest> _decoded_request(std::move(_request_bytes));
  Super::SetResult(
      Controller::InPlace::GetEventHandle(std::move(_client_end), Super::response_buffer()));
}

Controller::ResultOf::GetEventHandle Controller::SyncClient::GetEventHandle() {
  return ResultOf::GetEventHandle(zx::unowned_channel(this->channel_));
}

Controller::ResultOf::GetEventHandle Controller::Call::GetEventHandle(zx::unowned_channel _client_end) {
  return ResultOf::GetEventHandle(std::move(_client_end));
}

template <>
Controller::UnownedResultOf::GetEventHandle_Impl<Controller::GetEventHandleResponse>::GetEventHandle_Impl(zx::unowned_channel _client_end, ::fidl::BytePart _response_buffer) {
  FIDL_ALIGNDECL uint8_t _write_bytes[sizeof(GetEventHandleRequest)] = {};
  ::fidl::BytePart _request_buffer(_write_bytes, sizeof(_write_bytes));
  memset(_request_buffer.data(), 0, GetEventHandleRequest::PrimarySize);
  _request_buffer.set_actual(sizeof(GetEventHandleRequest));
  ::fidl::DecodedMessage<GetEventHandleRequest> _decoded_request(std::move(_request_buffer));
  Super::SetResult(
      Controller::InPlace::GetEventHandle(std::move(_client_end), std::move(_response_buffer)));
}

Controller::UnownedResultOf::GetEventHandle Controller::SyncClient::GetEventHandle(::fidl::BytePart _response_buffer) {
  return UnownedResultOf::GetEventHandle(zx::unowned_channel(this->channel_), std::move(_response_buffer));
}

Controller::UnownedResultOf::GetEventHandle Controller::Call::GetEventHandle(zx::unowned_channel _client_end, ::fidl::BytePart _response_buffer) {
  return UnownedResultOf::GetEventHandle(std::move(_client_end), std::move(_response_buffer));
}

::fidl::DecodeResult<Controller::GetEventHandleResponse> Controller::InPlace::GetEventHandle(zx::unowned_channel _client_end, ::fidl::BytePart response_buffer) {
  constexpr uint32_t _write_num_bytes = sizeof(GetEventHandleRequest);
  ::fidl::internal::AlignedBuffer<_write_num_bytes> _write_bytes;
  ::fidl::BytePart _request_buffer = _write_bytes.view();
  _request_buffer.set_actual(_write_num_bytes);
  ::fidl::DecodedMessage<GetEventHandleRequest> params(std::move(_request_buffer));
  params.message()->_hdr = {};
  params.message()->_hdr.ordinal = kController_GetEventHandle_Ordinal;
  auto _encode_request_result = ::fidl::Encode(std::move(params));
  if (_encode_request_result.status != ZX_OK) {
    return ::fidl::DecodeResult<Controller::GetEventHandleResponse>::FromFailure(
        std::move(_encode_request_result));
  }
  auto _call_result = ::fidl::Call<GetEventHandleRequest, GetEventHandleResponse>(
    std::move(_client_end), std::move(_encode_request_result.message), std::move(response_buffer));
  if (_call_result.status != ZX_OK) {
    return ::fidl::DecodeResult<Controller::GetEventHandleResponse>::FromFailure(
        std::move(_call_result));
  }
  return ::fidl::Decode(std::move(_call_result.message));
}

template <>
Controller::ResultOf::GetDriverLogFlags_Impl<Controller::GetDriverLogFlagsResponse>::GetDriverLogFlags_Impl(zx::unowned_channel _client_end) {
  constexpr uint32_t _kWriteAllocSize = ::fidl::internal::ClampedMessageSize<GetDriverLogFlagsRequest, ::fidl::MessageDirection::kSending>();
  ::fidl::internal::AlignedBuffer<_kWriteAllocSize> _write_bytes_inlined;
  auto& _write_bytes_array = _write_bytes_inlined;
  uint8_t* _write_bytes = _write_bytes_array.view().data();
  memset(_write_bytes, 0, GetDriverLogFlagsRequest::PrimarySize);
  ::fidl::BytePart _request_bytes(_write_bytes, _kWriteAllocSize, sizeof(GetDriverLogFlagsRequest));
  ::fidl::DecodedMessage<GetDriverLogFlagsRequest> _decoded_request(std::move(_request_bytes));
  Super::SetResult(
      Controller::InPlace::GetDriverLogFlags(std::move(_client_end), Super::response_buffer()));
}

Controller::ResultOf::GetDriverLogFlags Controller::SyncClient::GetDriverLogFlags() {
  return ResultOf::GetDriverLogFlags(zx::unowned_channel(this->channel_));
}

Controller::ResultOf::GetDriverLogFlags Controller::Call::GetDriverLogFlags(zx::unowned_channel _client_end) {
  return ResultOf::GetDriverLogFlags(std::move(_client_end));
}

template <>
Controller::UnownedResultOf::GetDriverLogFlags_Impl<Controller::GetDriverLogFlagsResponse>::GetDriverLogFlags_Impl(zx::unowned_channel _client_end, ::fidl::BytePart _response_buffer) {
  FIDL_ALIGNDECL uint8_t _write_bytes[sizeof(GetDriverLogFlagsRequest)] = {};
  ::fidl::BytePart _request_buffer(_write_bytes, sizeof(_write_bytes));
  memset(_request_buffer.data(), 0, GetDriverLogFlagsRequest::PrimarySize);
  _request_buffer.set_actual(sizeof(GetDriverLogFlagsRequest));
  ::fidl::DecodedMessage<GetDriverLogFlagsRequest> _decoded_request(std::move(_request_buffer));
  Super::SetResult(
      Controller::InPlace::GetDriverLogFlags(std::move(_client_end), std::move(_response_buffer)));
}

Controller::UnownedResultOf::GetDriverLogFlags Controller::SyncClient::GetDriverLogFlags(::fidl::BytePart _response_buffer) {
  return UnownedResultOf::GetDriverLogFlags(zx::unowned_channel(this->channel_), std::move(_response_buffer));
}

Controller::UnownedResultOf::GetDriverLogFlags Controller::Call::GetDriverLogFlags(zx::unowned_channel _client_end, ::fidl::BytePart _response_buffer) {
  return UnownedResultOf::GetDriverLogFlags(std::move(_client_end), std::move(_response_buffer));
}

::fidl::DecodeResult<Controller::GetDriverLogFlagsResponse> Controller::InPlace::GetDriverLogFlags(zx::unowned_channel _client_end, ::fidl::BytePart response_buffer) {
  constexpr uint32_t _write_num_bytes = sizeof(GetDriverLogFlagsRequest);
  ::fidl::internal::AlignedBuffer<_write_num_bytes> _write_bytes;
  ::fidl::BytePart _request_buffer = _write_bytes.view();
  _request_buffer.set_actual(_write_num_bytes);
  ::fidl::DecodedMessage<GetDriverLogFlagsRequest> params(std::move(_request_buffer));
  params.message()->_hdr = {};
  params.message()->_hdr.ordinal = kController_GetDriverLogFlags_Ordinal;
  auto _encode_request_result = ::fidl::Encode(std::move(params));
  if (_encode_request_result.status != ZX_OK) {
    return ::fidl::DecodeResult<Controller::GetDriverLogFlagsResponse>::FromFailure(
        std::move(_encode_request_result));
  }
  auto _call_result = ::fidl::Call<GetDriverLogFlagsRequest, GetDriverLogFlagsResponse>(
    std::move(_client_end), std::move(_encode_request_result.message), std::move(response_buffer));
  if (_call_result.status != ZX_OK) {
    return ::fidl::DecodeResult<Controller::GetDriverLogFlagsResponse>::FromFailure(
        std::move(_call_result));
  }
  return ::fidl::Decode(std::move(_call_result.message));
}

template <>
Controller::ResultOf::SetDriverLogFlags_Impl<Controller::SetDriverLogFlagsResponse>::SetDriverLogFlags_Impl(zx::unowned_channel _client_end, uint32_t clear_flags, uint32_t set_flags) {
  constexpr uint32_t _kWriteAllocSize = ::fidl::internal::ClampedMessageSize<SetDriverLogFlagsRequest, ::fidl::MessageDirection::kSending>();
  ::fidl::internal::AlignedBuffer<_kWriteAllocSize> _write_bytes_inlined;
  auto& _write_bytes_array = _write_bytes_inlined;
  uint8_t* _write_bytes = _write_bytes_array.view().data();
  memset(_write_bytes, 0, SetDriverLogFlagsRequest::PrimarySize);
  auto& _request = *reinterpret_cast<SetDriverLogFlagsRequest*>(_write_bytes);
  _request.clear_flags = std::move(clear_flags);
  _request.set_flags = std::move(set_flags);
  ::fidl::BytePart _request_bytes(_write_bytes, _kWriteAllocSize, sizeof(SetDriverLogFlagsRequest));
  ::fidl::DecodedMessage<SetDriverLogFlagsRequest> _decoded_request(std::move(_request_bytes));
  Super::SetResult(
      Controller::InPlace::SetDriverLogFlags(std::move(_client_end), std::move(_decoded_request), Super::response_buffer()));
}

Controller::ResultOf::SetDriverLogFlags Controller::SyncClient::SetDriverLogFlags(uint32_t clear_flags, uint32_t set_flags) {
  return ResultOf::SetDriverLogFlags(zx::unowned_channel(this->channel_), std::move(clear_flags), std::move(set_flags));
}

Controller::ResultOf::SetDriverLogFlags Controller::Call::SetDriverLogFlags(zx::unowned_channel _client_end, uint32_t clear_flags, uint32_t set_flags) {
  return ResultOf::SetDriverLogFlags(std::move(_client_end), std::move(clear_flags), std::move(set_flags));
}

template <>
Controller::UnownedResultOf::SetDriverLogFlags_Impl<Controller::SetDriverLogFlagsResponse>::SetDriverLogFlags_Impl(zx::unowned_channel _client_end, ::fidl::BytePart _request_buffer, uint32_t clear_flags, uint32_t set_flags, ::fidl::BytePart _response_buffer) {
  if (_request_buffer.capacity() < SetDriverLogFlagsRequest::PrimarySize) {
    Super::SetFailure(::fidl::DecodeResult<SetDriverLogFlagsResponse>(ZX_ERR_BUFFER_TOO_SMALL, ::fidl::internal::kErrorRequestBufferTooSmall));
    return;
  }
  memset(_request_buffer.data(), 0, SetDriverLogFlagsRequest::PrimarySize);
  auto& _request = *reinterpret_cast<SetDriverLogFlagsRequest*>(_request_buffer.data());
  _request.clear_flags = std::move(clear_flags);
  _request.set_flags = std::move(set_flags);
  _request_buffer.set_actual(sizeof(SetDriverLogFlagsRequest));
  ::fidl::DecodedMessage<SetDriverLogFlagsRequest> _decoded_request(std::move(_request_buffer));
  Super::SetResult(
      Controller::InPlace::SetDriverLogFlags(std::move(_client_end), std::move(_decoded_request), std::move(_response_buffer)));
}

Controller::UnownedResultOf::SetDriverLogFlags Controller::SyncClient::SetDriverLogFlags(::fidl::BytePart _request_buffer, uint32_t clear_flags, uint32_t set_flags, ::fidl::BytePart _response_buffer) {
  return UnownedResultOf::SetDriverLogFlags(zx::unowned_channel(this->channel_), std::move(_request_buffer), std::move(clear_flags), std::move(set_flags), std::move(_response_buffer));
}

Controller::UnownedResultOf::SetDriverLogFlags Controller::Call::SetDriverLogFlags(zx::unowned_channel _client_end, ::fidl::BytePart _request_buffer, uint32_t clear_flags, uint32_t set_flags, ::fidl::BytePart _response_buffer) {
  return UnownedResultOf::SetDriverLogFlags(std::move(_client_end), std::move(_request_buffer), std::move(clear_flags), std::move(set_flags), std::move(_response_buffer));
}

::fidl::DecodeResult<Controller::SetDriverLogFlagsResponse> Controller::InPlace::SetDriverLogFlags(zx::unowned_channel _client_end, ::fidl::DecodedMessage<SetDriverLogFlagsRequest> params, ::fidl::BytePart response_buffer) {
  params.message()->_hdr = {};
  params.message()->_hdr.ordinal = kController_SetDriverLogFlags_Ordinal;
  auto _encode_request_result = ::fidl::Encode(std::move(params));
  if (_encode_request_result.status != ZX_OK) {
    return ::fidl::DecodeResult<Controller::SetDriverLogFlagsResponse>::FromFailure(
        std::move(_encode_request_result));
  }
  auto _call_result = ::fidl::Call<SetDriverLogFlagsRequest, SetDriverLogFlagsResponse>(
    std::move(_client_end), std::move(_encode_request_result.message), std::move(response_buffer));
  if (_call_result.status != ZX_OK) {
    return ::fidl::DecodeResult<Controller::SetDriverLogFlagsResponse>::FromFailure(
        std::move(_call_result));
  }
  return ::fidl::Decode(std::move(_call_result.message));
}

template <>
Controller::ResultOf::DebugSuspend_Impl<Controller::DebugSuspendResponse>::DebugSuspend_Impl(zx::unowned_channel _client_end) {
  constexpr uint32_t _kWriteAllocSize = ::fidl::internal::ClampedMessageSize<DebugSuspendRequest, ::fidl::MessageDirection::kSending>();
  ::fidl::internal::AlignedBuffer<_kWriteAllocSize> _write_bytes_inlined;
  auto& _write_bytes_array = _write_bytes_inlined;
  uint8_t* _write_bytes = _write_bytes_array.view().data();
  memset(_write_bytes, 0, DebugSuspendRequest::PrimarySize);
  ::fidl::BytePart _request_bytes(_write_bytes, _kWriteAllocSize, sizeof(DebugSuspendRequest));
  ::fidl::DecodedMessage<DebugSuspendRequest> _decoded_request(std::move(_request_bytes));
  Super::SetResult(
      Controller::InPlace::DebugSuspend(std::move(_client_end), Super::response_buffer()));
}

Controller::ResultOf::DebugSuspend Controller::SyncClient::DebugSuspend() {
  return ResultOf::DebugSuspend(zx::unowned_channel(this->channel_));
}

Controller::ResultOf::DebugSuspend Controller::Call::DebugSuspend(zx::unowned_channel _client_end) {
  return ResultOf::DebugSuspend(std::move(_client_end));
}

template <>
Controller::UnownedResultOf::DebugSuspend_Impl<Controller::DebugSuspendResponse>::DebugSuspend_Impl(zx::unowned_channel _client_end, ::fidl::BytePart _response_buffer) {
  FIDL_ALIGNDECL uint8_t _write_bytes[sizeof(DebugSuspendRequest)] = {};
  ::fidl::BytePart _request_buffer(_write_bytes, sizeof(_write_bytes));
  memset(_request_buffer.data(), 0, DebugSuspendRequest::PrimarySize);
  _request_buffer.set_actual(sizeof(DebugSuspendRequest));
  ::fidl::DecodedMessage<DebugSuspendRequest> _decoded_request(std::move(_request_buffer));
  Super::SetResult(
      Controller::InPlace::DebugSuspend(std::move(_client_end), std::move(_response_buffer)));
}

Controller::UnownedResultOf::DebugSuspend Controller::SyncClient::DebugSuspend(::fidl::BytePart _response_buffer) {
  return UnownedResultOf::DebugSuspend(zx::unowned_channel(this->channel_), std::move(_response_buffer));
}

Controller::UnownedResultOf::DebugSuspend Controller::Call::DebugSuspend(zx::unowned_channel _client_end, ::fidl::BytePart _response_buffer) {
  return UnownedResultOf::DebugSuspend(std::move(_client_end), std::move(_response_buffer));
}

::fidl::DecodeResult<Controller::DebugSuspendResponse> Controller::InPlace::DebugSuspend(zx::unowned_channel _client_end, ::fidl::BytePart response_buffer) {
  constexpr uint32_t _write_num_bytes = sizeof(DebugSuspendRequest);
  ::fidl::internal::AlignedBuffer<_write_num_bytes> _write_bytes;
  ::fidl::BytePart _request_buffer = _write_bytes.view();
  _request_buffer.set_actual(_write_num_bytes);
  ::fidl::DecodedMessage<DebugSuspendRequest> params(std::move(_request_buffer));
  params.message()->_hdr = {};
  params.message()->_hdr.ordinal = kController_DebugSuspend_Ordinal;
  auto _encode_request_result = ::fidl::Encode(std::move(params));
  if (_encode_request_result.status != ZX_OK) {
    return ::fidl::DecodeResult<Controller::DebugSuspendResponse>::FromFailure(
        std::move(_encode_request_result));
  }
  auto _call_result = ::fidl::Call<DebugSuspendRequest, DebugSuspendResponse>(
    std::move(_client_end), std::move(_encode_request_result.message), std::move(response_buffer));
  if (_call_result.status != ZX_OK) {
    return ::fidl::DecodeResult<Controller::DebugSuspendResponse>::FromFailure(
        std::move(_call_result));
  }
  return ::fidl::Decode(std::move(_call_result.message));
}

template <>
Controller::ResultOf::DebugResume_Impl<Controller::DebugResumeResponse>::DebugResume_Impl(zx::unowned_channel _client_end) {
  constexpr uint32_t _kWriteAllocSize = ::fidl::internal::ClampedMessageSize<DebugResumeRequest, ::fidl::MessageDirection::kSending>();
  ::fidl::internal::AlignedBuffer<_kWriteAllocSize> _write_bytes_inlined;
  auto& _write_bytes_array = _write_bytes_inlined;
  uint8_t* _write_bytes = _write_bytes_array.view().data();
  memset(_write_bytes, 0, DebugResumeRequest::PrimarySize);
  ::fidl::BytePart _request_bytes(_write_bytes, _kWriteAllocSize, sizeof(DebugResumeRequest));
  ::fidl::DecodedMessage<DebugResumeRequest> _decoded_request(std::move(_request_bytes));
  Super::SetResult(
      Controller::InPlace::DebugResume(std::move(_client_end), Super::response_buffer()));
}

Controller::ResultOf::DebugResume Controller::SyncClient::DebugResume() {
  return ResultOf::DebugResume(zx::unowned_channel(this->channel_));
}

Controller::ResultOf::DebugResume Controller::Call::DebugResume(zx::unowned_channel _client_end) {
  return ResultOf::DebugResume(std::move(_client_end));
}

template <>
Controller::UnownedResultOf::DebugResume_Impl<Controller::DebugResumeResponse>::DebugResume_Impl(zx::unowned_channel _client_end, ::fidl::BytePart _response_buffer) {
  FIDL_ALIGNDECL uint8_t _write_bytes[sizeof(DebugResumeRequest)] = {};
  ::fidl::BytePart _request_buffer(_write_bytes, sizeof(_write_bytes));
  memset(_request_buffer.data(), 0, DebugResumeRequest::PrimarySize);
  _request_buffer.set_actual(sizeof(DebugResumeRequest));
  ::fidl::DecodedMessage<DebugResumeRequest> _decoded_request(std::move(_request_buffer));
  Super::SetResult(
      Controller::InPlace::DebugResume(std::move(_client_end), std::move(_response_buffer)));
}

Controller::UnownedResultOf::DebugResume Controller::SyncClient::DebugResume(::fidl::BytePart _response_buffer) {
  return UnownedResultOf::DebugResume(zx::unowned_channel(this->channel_), std::move(_response_buffer));
}

Controller::UnownedResultOf::DebugResume Controller::Call::DebugResume(zx::unowned_channel _client_end, ::fidl::BytePart _response_buffer) {
  return UnownedResultOf::DebugResume(std::move(_client_end), std::move(_response_buffer));
}

::fidl::DecodeResult<Controller::DebugResumeResponse> Controller::InPlace::DebugResume(zx::unowned_channel _client_end, ::fidl::BytePart response_buffer) {
  constexpr uint32_t _write_num_bytes = sizeof(DebugResumeRequest);
  ::fidl::internal::AlignedBuffer<_write_num_bytes> _write_bytes;
  ::fidl::BytePart _request_buffer = _write_bytes.view();
  _request_buffer.set_actual(_write_num_bytes);
  ::fidl::DecodedMessage<DebugResumeRequest> params(std::move(_request_buffer));
  params.message()->_hdr = {};
  params.message()->_hdr.ordinal = kController_DebugResume_Ordinal;
  auto _encode_request_result = ::fidl::Encode(std::move(params));
  if (_encode_request_result.status != ZX_OK) {
    return ::fidl::DecodeResult<Controller::DebugResumeResponse>::FromFailure(
        std::move(_encode_request_result));
  }
  auto _call_result = ::fidl::Call<DebugResumeRequest, DebugResumeResponse>(
    std::move(_client_end), std::move(_encode_request_result.message), std::move(response_buffer));
  if (_call_result.status != ZX_OK) {
    return ::fidl::DecodeResult<Controller::DebugResumeResponse>::FromFailure(
        std::move(_call_result));
  }
  return ::fidl::Decode(std::move(_call_result.message));
}

template <>
Controller::ResultOf::RunCompatibilityTests_Impl<Controller::RunCompatibilityTestsResponse>::RunCompatibilityTests_Impl(zx::unowned_channel _client_end, int64_t hook_wait_time) {
  constexpr uint32_t _kWriteAllocSize = ::fidl::internal::ClampedMessageSize<RunCompatibilityTestsRequest, ::fidl::MessageDirection::kSending>();
  ::fidl::internal::AlignedBuffer<_kWriteAllocSize> _write_bytes_inlined;
  auto& _write_bytes_array = _write_bytes_inlined;
  uint8_t* _write_bytes = _write_bytes_array.view().data();
  memset(_write_bytes, 0, RunCompatibilityTestsRequest::PrimarySize);
  auto& _request = *reinterpret_cast<RunCompatibilityTestsRequest*>(_write_bytes);
  _request.hook_wait_time = std::move(hook_wait_time);
  ::fidl::BytePart _request_bytes(_write_bytes, _kWriteAllocSize, sizeof(RunCompatibilityTestsRequest));
  ::fidl::DecodedMessage<RunCompatibilityTestsRequest> _decoded_request(std::move(_request_bytes));
  Super::SetResult(
      Controller::InPlace::RunCompatibilityTests(std::move(_client_end), std::move(_decoded_request), Super::response_buffer()));
}

Controller::ResultOf::RunCompatibilityTests Controller::SyncClient::RunCompatibilityTests(int64_t hook_wait_time) {
  return ResultOf::RunCompatibilityTests(zx::unowned_channel(this->channel_), std::move(hook_wait_time));
}

Controller::ResultOf::RunCompatibilityTests Controller::Call::RunCompatibilityTests(zx::unowned_channel _client_end, int64_t hook_wait_time) {
  return ResultOf::RunCompatibilityTests(std::move(_client_end), std::move(hook_wait_time));
}

template <>
Controller::UnownedResultOf::RunCompatibilityTests_Impl<Controller::RunCompatibilityTestsResponse>::RunCompatibilityTests_Impl(zx::unowned_channel _client_end, ::fidl::BytePart _request_buffer, int64_t hook_wait_time, ::fidl::BytePart _response_buffer) {
  if (_request_buffer.capacity() < RunCompatibilityTestsRequest::PrimarySize) {
    Super::SetFailure(::fidl::DecodeResult<RunCompatibilityTestsResponse>(ZX_ERR_BUFFER_TOO_SMALL, ::fidl::internal::kErrorRequestBufferTooSmall));
    return;
  }
  memset(_request_buffer.data(), 0, RunCompatibilityTestsRequest::PrimarySize);
  auto& _request = *reinterpret_cast<RunCompatibilityTestsRequest*>(_request_buffer.data());
  _request.hook_wait_time = std::move(hook_wait_time);
  _request_buffer.set_actual(sizeof(RunCompatibilityTestsRequest));
  ::fidl::DecodedMessage<RunCompatibilityTestsRequest> _decoded_request(std::move(_request_buffer));
  Super::SetResult(
      Controller::InPlace::RunCompatibilityTests(std::move(_client_end), std::move(_decoded_request), std::move(_response_buffer)));
}

Controller::UnownedResultOf::RunCompatibilityTests Controller::SyncClient::RunCompatibilityTests(::fidl::BytePart _request_buffer, int64_t hook_wait_time, ::fidl::BytePart _response_buffer) {
  return UnownedResultOf::RunCompatibilityTests(zx::unowned_channel(this->channel_), std::move(_request_buffer), std::move(hook_wait_time), std::move(_response_buffer));
}

Controller::UnownedResultOf::RunCompatibilityTests Controller::Call::RunCompatibilityTests(zx::unowned_channel _client_end, ::fidl::BytePart _request_buffer, int64_t hook_wait_time, ::fidl::BytePart _response_buffer) {
  return UnownedResultOf::RunCompatibilityTests(std::move(_client_end), std::move(_request_buffer), std::move(hook_wait_time), std::move(_response_buffer));
}

::fidl::DecodeResult<Controller::RunCompatibilityTestsResponse> Controller::InPlace::RunCompatibilityTests(zx::unowned_channel _client_end, ::fidl::DecodedMessage<RunCompatibilityTestsRequest> params, ::fidl::BytePart response_buffer) {
  params.message()->_hdr = {};
  params.message()->_hdr.ordinal = kController_RunCompatibilityTests_Ordinal;
  auto _encode_request_result = ::fidl::Encode(std::move(params));
  if (_encode_request_result.status != ZX_OK) {
    return ::fidl::DecodeResult<Controller::RunCompatibilityTestsResponse>::FromFailure(
        std::move(_encode_request_result));
  }
  auto _call_result = ::fidl::Call<RunCompatibilityTestsRequest, RunCompatibilityTestsResponse>(
    std::move(_client_end), std::move(_encode_request_result.message), std::move(response_buffer));
  if (_call_result.status != ZX_OK) {
    return ::fidl::DecodeResult<Controller::RunCompatibilityTestsResponse>::FromFailure(
        std::move(_call_result));
  }
  return ::fidl::Decode(std::move(_call_result.message));
}

template <>
Controller::ResultOf::GetDevicePowerCaps_Impl<Controller::GetDevicePowerCapsResponse>::GetDevicePowerCaps_Impl(zx::unowned_channel _client_end) {
  constexpr uint32_t _kWriteAllocSize = ::fidl::internal::ClampedMessageSize<GetDevicePowerCapsRequest, ::fidl::MessageDirection::kSending>();
  ::fidl::internal::AlignedBuffer<_kWriteAllocSize> _write_bytes_inlined;
  auto& _write_bytes_array = _write_bytes_inlined;
  uint8_t* _write_bytes = _write_bytes_array.view().data();
  memset(_write_bytes, 0, GetDevicePowerCapsRequest::PrimarySize);
  ::fidl::BytePart _request_bytes(_write_bytes, _kWriteAllocSize, sizeof(GetDevicePowerCapsRequest));
  ::fidl::DecodedMessage<GetDevicePowerCapsRequest> _decoded_request(std::move(_request_bytes));
  Super::SetResult(
      Controller::InPlace::GetDevicePowerCaps(std::move(_client_end), Super::response_buffer()));
}

Controller::ResultOf::GetDevicePowerCaps Controller::SyncClient::GetDevicePowerCaps() {
  return ResultOf::GetDevicePowerCaps(zx::unowned_channel(this->channel_));
}

Controller::ResultOf::GetDevicePowerCaps Controller::Call::GetDevicePowerCaps(zx::unowned_channel _client_end) {
  return ResultOf::GetDevicePowerCaps(std::move(_client_end));
}

template <>
Controller::UnownedResultOf::GetDevicePowerCaps_Impl<Controller::GetDevicePowerCapsResponse>::GetDevicePowerCaps_Impl(zx::unowned_channel _client_end, ::fidl::BytePart _response_buffer) {
  FIDL_ALIGNDECL uint8_t _write_bytes[sizeof(GetDevicePowerCapsRequest)] = {};
  ::fidl::BytePart _request_buffer(_write_bytes, sizeof(_write_bytes));
  memset(_request_buffer.data(), 0, GetDevicePowerCapsRequest::PrimarySize);
  _request_buffer.set_actual(sizeof(GetDevicePowerCapsRequest));
  ::fidl::DecodedMessage<GetDevicePowerCapsRequest> _decoded_request(std::move(_request_buffer));
  Super::SetResult(
      Controller::InPlace::GetDevicePowerCaps(std::move(_client_end), std::move(_response_buffer)));
}

Controller::UnownedResultOf::GetDevicePowerCaps Controller::SyncClient::GetDevicePowerCaps(::fidl::BytePart _response_buffer) {
  return UnownedResultOf::GetDevicePowerCaps(zx::unowned_channel(this->channel_), std::move(_response_buffer));
}

Controller::UnownedResultOf::GetDevicePowerCaps Controller::Call::GetDevicePowerCaps(zx::unowned_channel _client_end, ::fidl::BytePart _response_buffer) {
  return UnownedResultOf::GetDevicePowerCaps(std::move(_client_end), std::move(_response_buffer));
}

::fidl::DecodeResult<Controller::GetDevicePowerCapsResponse> Controller::InPlace::GetDevicePowerCaps(zx::unowned_channel _client_end, ::fidl::BytePart response_buffer) {
  constexpr uint32_t _write_num_bytes = sizeof(GetDevicePowerCapsRequest);
  ::fidl::internal::AlignedBuffer<_write_num_bytes> _write_bytes;
  ::fidl::BytePart _request_buffer = _write_bytes.view();
  _request_buffer.set_actual(_write_num_bytes);
  ::fidl::DecodedMessage<GetDevicePowerCapsRequest> params(std::move(_request_buffer));
  params.message()->_hdr = {};
  params.message()->_hdr.ordinal = kController_GetDevicePowerCaps_Ordinal;
  auto _encode_request_result = ::fidl::Encode(std::move(params));
  if (_encode_request_result.status != ZX_OK) {
    return ::fidl::DecodeResult<Controller::GetDevicePowerCapsResponse>::FromFailure(
        std::move(_encode_request_result));
  }
  auto _call_result = ::fidl::Call<GetDevicePowerCapsRequest, GetDevicePowerCapsResponse>(
    std::move(_client_end), std::move(_encode_request_result.message), std::move(response_buffer));
  if (_call_result.status != ZX_OK) {
    return ::fidl::DecodeResult<Controller::GetDevicePowerCapsResponse>::FromFailure(
        std::move(_call_result));
  }
  return ::fidl::Decode(std::move(_call_result.message));
}

template <>
Controller::ResultOf::UpdatePowerStateMapping_Impl<Controller::UpdatePowerStateMappingResponse>::UpdatePowerStateMapping_Impl(zx::unowned_channel _client_end, ::fidl::Array<SystemPowerStateInfo, 7> mapping) {
  constexpr uint32_t _kWriteAllocSize = ::fidl::internal::ClampedMessageSize<UpdatePowerStateMappingRequest, ::fidl::MessageDirection::kSending>();
  ::fidl::internal::AlignedBuffer<_kWriteAllocSize> _write_bytes_inlined;
  auto& _write_bytes_array = _write_bytes_inlined;
  uint8_t* _write_bytes = _write_bytes_array.view().data();
  memset(_write_bytes, 0, UpdatePowerStateMappingRequest::PrimarySize);
  auto& _request = *reinterpret_cast<UpdatePowerStateMappingRequest*>(_write_bytes);
  _request.mapping = std::move(mapping);
  ::fidl::BytePart _request_bytes(_write_bytes, _kWriteAllocSize, sizeof(UpdatePowerStateMappingRequest));
  ::fidl::DecodedMessage<UpdatePowerStateMappingRequest> _decoded_request(std::move(_request_bytes));
  Super::SetResult(
      Controller::InPlace::UpdatePowerStateMapping(std::move(_client_end), std::move(_decoded_request), Super::response_buffer()));
}

Controller::ResultOf::UpdatePowerStateMapping Controller::SyncClient::UpdatePowerStateMapping(::fidl::Array<SystemPowerStateInfo, 7> mapping) {
  return ResultOf::UpdatePowerStateMapping(zx::unowned_channel(this->channel_), std::move(mapping));
}

Controller::ResultOf::UpdatePowerStateMapping Controller::Call::UpdatePowerStateMapping(zx::unowned_channel _client_end, ::fidl::Array<SystemPowerStateInfo, 7> mapping) {
  return ResultOf::UpdatePowerStateMapping(std::move(_client_end), std::move(mapping));
}

template <>
Controller::UnownedResultOf::UpdatePowerStateMapping_Impl<Controller::UpdatePowerStateMappingResponse>::UpdatePowerStateMapping_Impl(zx::unowned_channel _client_end, ::fidl::BytePart _request_buffer, ::fidl::Array<SystemPowerStateInfo, 7> mapping, ::fidl::BytePart _response_buffer) {
  if (_request_buffer.capacity() < UpdatePowerStateMappingRequest::PrimarySize) {
    Super::SetFailure(::fidl::DecodeResult<UpdatePowerStateMappingResponse>(ZX_ERR_BUFFER_TOO_SMALL, ::fidl::internal::kErrorRequestBufferTooSmall));
    return;
  }
  memset(_request_buffer.data(), 0, UpdatePowerStateMappingRequest::PrimarySize);
  auto& _request = *reinterpret_cast<UpdatePowerStateMappingRequest*>(_request_buffer.data());
  _request.mapping = std::move(mapping);
  _request_buffer.set_actual(sizeof(UpdatePowerStateMappingRequest));
  ::fidl::DecodedMessage<UpdatePowerStateMappingRequest> _decoded_request(std::move(_request_buffer));
  Super::SetResult(
      Controller::InPlace::UpdatePowerStateMapping(std::move(_client_end), std::move(_decoded_request), std::move(_response_buffer)));
}

Controller::UnownedResultOf::UpdatePowerStateMapping Controller::SyncClient::UpdatePowerStateMapping(::fidl::BytePart _request_buffer, ::fidl::Array<SystemPowerStateInfo, 7> mapping, ::fidl::BytePart _response_buffer) {
  return UnownedResultOf::UpdatePowerStateMapping(zx::unowned_channel(this->channel_), std::move(_request_buffer), std::move(mapping), std::move(_response_buffer));
}

Controller::UnownedResultOf::UpdatePowerStateMapping Controller::Call::UpdatePowerStateMapping(zx::unowned_channel _client_end, ::fidl::BytePart _request_buffer, ::fidl::Array<SystemPowerStateInfo, 7> mapping, ::fidl::BytePart _response_buffer) {
  return UnownedResultOf::UpdatePowerStateMapping(std::move(_client_end), std::move(_request_buffer), std::move(mapping), std::move(_response_buffer));
}

::fidl::DecodeResult<Controller::UpdatePowerStateMappingResponse> Controller::InPlace::UpdatePowerStateMapping(zx::unowned_channel _client_end, ::fidl::DecodedMessage<UpdatePowerStateMappingRequest> params, ::fidl::BytePart response_buffer) {
  params.message()->_hdr = {};
  params.message()->_hdr.ordinal = kController_UpdatePowerStateMapping_Ordinal;
  auto _encode_request_result = ::fidl::Encode(std::move(params));
  if (_encode_request_result.status != ZX_OK) {
    return ::fidl::DecodeResult<Controller::UpdatePowerStateMappingResponse>::FromFailure(
        std::move(_encode_request_result));
  }
  auto _call_result = ::fidl::Call<UpdatePowerStateMappingRequest, UpdatePowerStateMappingResponse>(
    std::move(_client_end), std::move(_encode_request_result.message), std::move(response_buffer));
  if (_call_result.status != ZX_OK) {
    return ::fidl::DecodeResult<Controller::UpdatePowerStateMappingResponse>::FromFailure(
        std::move(_call_result));
  }
  return ::fidl::Decode(std::move(_call_result.message));
}

template <>
Controller::ResultOf::GetPowerStateMapping_Impl<Controller::GetPowerStateMappingResponse>::GetPowerStateMapping_Impl(zx::unowned_channel _client_end) {
  constexpr uint32_t _kWriteAllocSize = ::fidl::internal::ClampedMessageSize<GetPowerStateMappingRequest, ::fidl::MessageDirection::kSending>();
  ::fidl::internal::AlignedBuffer<_kWriteAllocSize> _write_bytes_inlined;
  auto& _write_bytes_array = _write_bytes_inlined;
  uint8_t* _write_bytes = _write_bytes_array.view().data();
  memset(_write_bytes, 0, GetPowerStateMappingRequest::PrimarySize);
  ::fidl::BytePart _request_bytes(_write_bytes, _kWriteAllocSize, sizeof(GetPowerStateMappingRequest));
  ::fidl::DecodedMessage<GetPowerStateMappingRequest> _decoded_request(std::move(_request_bytes));
  Super::SetResult(
      Controller::InPlace::GetPowerStateMapping(std::move(_client_end), Super::response_buffer()));
}

Controller::ResultOf::GetPowerStateMapping Controller::SyncClient::GetPowerStateMapping() {
  return ResultOf::GetPowerStateMapping(zx::unowned_channel(this->channel_));
}

Controller::ResultOf::GetPowerStateMapping Controller::Call::GetPowerStateMapping(zx::unowned_channel _client_end) {
  return ResultOf::GetPowerStateMapping(std::move(_client_end));
}

template <>
Controller::UnownedResultOf::GetPowerStateMapping_Impl<Controller::GetPowerStateMappingResponse>::GetPowerStateMapping_Impl(zx::unowned_channel _client_end, ::fidl::BytePart _response_buffer) {
  FIDL_ALIGNDECL uint8_t _write_bytes[sizeof(GetPowerStateMappingRequest)] = {};
  ::fidl::BytePart _request_buffer(_write_bytes, sizeof(_write_bytes));
  memset(_request_buffer.data(), 0, GetPowerStateMappingRequest::PrimarySize);
  _request_buffer.set_actual(sizeof(GetPowerStateMappingRequest));
  ::fidl::DecodedMessage<GetPowerStateMappingRequest> _decoded_request(std::move(_request_buffer));
  Super::SetResult(
      Controller::InPlace::GetPowerStateMapping(std::move(_client_end), std::move(_response_buffer)));
}

Controller::UnownedResultOf::GetPowerStateMapping Controller::SyncClient::GetPowerStateMapping(::fidl::BytePart _response_buffer) {
  return UnownedResultOf::GetPowerStateMapping(zx::unowned_channel(this->channel_), std::move(_response_buffer));
}

Controller::UnownedResultOf::GetPowerStateMapping Controller::Call::GetPowerStateMapping(zx::unowned_channel _client_end, ::fidl::BytePart _response_buffer) {
  return UnownedResultOf::GetPowerStateMapping(std::move(_client_end), std::move(_response_buffer));
}

::fidl::DecodeResult<Controller::GetPowerStateMappingResponse> Controller::InPlace::GetPowerStateMapping(zx::unowned_channel _client_end, ::fidl::BytePart response_buffer) {
  constexpr uint32_t _write_num_bytes = sizeof(GetPowerStateMappingRequest);
  ::fidl::internal::AlignedBuffer<_write_num_bytes> _write_bytes;
  ::fidl::BytePart _request_buffer = _write_bytes.view();
  _request_buffer.set_actual(_write_num_bytes);
  ::fidl::DecodedMessage<GetPowerStateMappingRequest> params(std::move(_request_buffer));
  params.message()->_hdr = {};
  params.message()->_hdr.ordinal = kController_GetPowerStateMapping_Ordinal;
  auto _encode_request_result = ::fidl::Encode(std::move(params));
  if (_encode_request_result.status != ZX_OK) {
    return ::fidl::DecodeResult<Controller::GetPowerStateMappingResponse>::FromFailure(
        std::move(_encode_request_result));
  }
  auto _call_result = ::fidl::Call<GetPowerStateMappingRequest, GetPowerStateMappingResponse>(
    std::move(_client_end), std::move(_encode_request_result.message), std::move(response_buffer));
  if (_call_result.status != ZX_OK) {
    return ::fidl::DecodeResult<Controller::GetPowerStateMappingResponse>::FromFailure(
        std::move(_call_result));
  }
  return ::fidl::Decode(std::move(_call_result.message));
}

template <>
Controller::ResultOf::Suspend_Impl<Controller::SuspendResponse>::Suspend_Impl(zx::unowned_channel _client_end, DevicePowerState requested_state) {
  constexpr uint32_t _kWriteAllocSize = ::fidl::internal::ClampedMessageSize<SuspendRequest, ::fidl::MessageDirection::kSending>();
  ::fidl::internal::AlignedBuffer<_kWriteAllocSize> _write_bytes_inlined;
  auto& _write_bytes_array = _write_bytes_inlined;
  uint8_t* _write_bytes = _write_bytes_array.view().data();
  memset(_write_bytes, 0, SuspendRequest::PrimarySize);
  auto& _request = *reinterpret_cast<SuspendRequest*>(_write_bytes);
  _request.requested_state = std::move(requested_state);
  ::fidl::BytePart _request_bytes(_write_bytes, _kWriteAllocSize, sizeof(SuspendRequest));
  ::fidl::DecodedMessage<SuspendRequest> _decoded_request(std::move(_request_bytes));
  Super::SetResult(
      Controller::InPlace::Suspend(std::move(_client_end), std::move(_decoded_request), Super::response_buffer()));
}

Controller::ResultOf::Suspend Controller::SyncClient::Suspend(DevicePowerState requested_state) {
  return ResultOf::Suspend(zx::unowned_channel(this->channel_), std::move(requested_state));
}

Controller::ResultOf::Suspend Controller::Call::Suspend(zx::unowned_channel _client_end, DevicePowerState requested_state) {
  return ResultOf::Suspend(std::move(_client_end), std::move(requested_state));
}

template <>
Controller::UnownedResultOf::Suspend_Impl<Controller::SuspendResponse>::Suspend_Impl(zx::unowned_channel _client_end, ::fidl::BytePart _request_buffer, DevicePowerState requested_state, ::fidl::BytePart _response_buffer) {
  if (_request_buffer.capacity() < SuspendRequest::PrimarySize) {
    Super::SetFailure(::fidl::DecodeResult<SuspendResponse>(ZX_ERR_BUFFER_TOO_SMALL, ::fidl::internal::kErrorRequestBufferTooSmall));
    return;
  }
  memset(_request_buffer.data(), 0, SuspendRequest::PrimarySize);
  auto& _request = *reinterpret_cast<SuspendRequest*>(_request_buffer.data());
  _request.requested_state = std::move(requested_state);
  _request_buffer.set_actual(sizeof(SuspendRequest));
  ::fidl::DecodedMessage<SuspendRequest> _decoded_request(std::move(_request_buffer));
  Super::SetResult(
      Controller::InPlace::Suspend(std::move(_client_end), std::move(_decoded_request), std::move(_response_buffer)));
}

Controller::UnownedResultOf::Suspend Controller::SyncClient::Suspend(::fidl::BytePart _request_buffer, DevicePowerState requested_state, ::fidl::BytePart _response_buffer) {
  return UnownedResultOf::Suspend(zx::unowned_channel(this->channel_), std::move(_request_buffer), std::move(requested_state), std::move(_response_buffer));
}

Controller::UnownedResultOf::Suspend Controller::Call::Suspend(zx::unowned_channel _client_end, ::fidl::BytePart _request_buffer, DevicePowerState requested_state, ::fidl::BytePart _response_buffer) {
  return UnownedResultOf::Suspend(std::move(_client_end), std::move(_request_buffer), std::move(requested_state), std::move(_response_buffer));
}

::fidl::DecodeResult<Controller::SuspendResponse> Controller::InPlace::Suspend(zx::unowned_channel _client_end, ::fidl::DecodedMessage<SuspendRequest> params, ::fidl::BytePart response_buffer) {
  params.message()->_hdr = {};
  params.message()->_hdr.ordinal = kController_Suspend_Ordinal;
  auto _encode_request_result = ::fidl::Encode(std::move(params));
  if (_encode_request_result.status != ZX_OK) {
    return ::fidl::DecodeResult<Controller::SuspendResponse>::FromFailure(
        std::move(_encode_request_result));
  }
  auto _call_result = ::fidl::Call<SuspendRequest, SuspendResponse>(
    std::move(_client_end), std::move(_encode_request_result.message), std::move(response_buffer));
  if (_call_result.status != ZX_OK) {
    return ::fidl::DecodeResult<Controller::SuspendResponse>::FromFailure(
        std::move(_call_result));
  }
  return ::fidl::Decode(std::move(_call_result.message));
}

template <>
Controller::ResultOf::Resume_Impl<Controller::ResumeResponse>::Resume_Impl(zx::unowned_channel _client_end, DevicePowerState requested_state) {
  constexpr uint32_t _kWriteAllocSize = ::fidl::internal::ClampedMessageSize<ResumeRequest, ::fidl::MessageDirection::kSending>();
  ::fidl::internal::AlignedBuffer<_kWriteAllocSize> _write_bytes_inlined;
  auto& _write_bytes_array = _write_bytes_inlined;
  uint8_t* _write_bytes = _write_bytes_array.view().data();
  memset(_write_bytes, 0, ResumeRequest::PrimarySize);
  auto& _request = *reinterpret_cast<ResumeRequest*>(_write_bytes);
  _request.requested_state = std::move(requested_state);
  ::fidl::BytePart _request_bytes(_write_bytes, _kWriteAllocSize, sizeof(ResumeRequest));
  ::fidl::DecodedMessage<ResumeRequest> _decoded_request(std::move(_request_bytes));
  Super::SetResult(
      Controller::InPlace::Resume(std::move(_client_end), std::move(_decoded_request), Super::response_buffer()));
}

Controller::ResultOf::Resume Controller::SyncClient::Resume(DevicePowerState requested_state) {
  return ResultOf::Resume(zx::unowned_channel(this->channel_), std::move(requested_state));
}

Controller::ResultOf::Resume Controller::Call::Resume(zx::unowned_channel _client_end, DevicePowerState requested_state) {
  return ResultOf::Resume(std::move(_client_end), std::move(requested_state));
}

template <>
Controller::UnownedResultOf::Resume_Impl<Controller::ResumeResponse>::Resume_Impl(zx::unowned_channel _client_end, ::fidl::BytePart _request_buffer, DevicePowerState requested_state, ::fidl::BytePart _response_buffer) {
  if (_request_buffer.capacity() < ResumeRequest::PrimarySize) {
    Super::SetFailure(::fidl::DecodeResult<ResumeResponse>(ZX_ERR_BUFFER_TOO_SMALL, ::fidl::internal::kErrorRequestBufferTooSmall));
    return;
  }
  memset(_request_buffer.data(), 0, ResumeRequest::PrimarySize);
  auto& _request = *reinterpret_cast<ResumeRequest*>(_request_buffer.data());
  _request.requested_state = std::move(requested_state);
  _request_buffer.set_actual(sizeof(ResumeRequest));
  ::fidl::DecodedMessage<ResumeRequest> _decoded_request(std::move(_request_buffer));
  Super::SetResult(
      Controller::InPlace::Resume(std::move(_client_end), std::move(_decoded_request), std::move(_response_buffer)));
}

Controller::UnownedResultOf::Resume Controller::SyncClient::Resume(::fidl::BytePart _request_buffer, DevicePowerState requested_state, ::fidl::BytePart _response_buffer) {
  return UnownedResultOf::Resume(zx::unowned_channel(this->channel_), std::move(_request_buffer), std::move(requested_state), std::move(_response_buffer));
}

Controller::UnownedResultOf::Resume Controller::Call::Resume(zx::unowned_channel _client_end, ::fidl::BytePart _request_buffer, DevicePowerState requested_state, ::fidl::BytePart _response_buffer) {
  return UnownedResultOf::Resume(std::move(_client_end), std::move(_request_buffer), std::move(requested_state), std::move(_response_buffer));
}

::fidl::DecodeResult<Controller::ResumeResponse> Controller::InPlace::Resume(zx::unowned_channel _client_end, ::fidl::DecodedMessage<ResumeRequest> params, ::fidl::BytePart response_buffer) {
  params.message()->_hdr = {};
  params.message()->_hdr.ordinal = kController_Resume_Ordinal;
  auto _encode_request_result = ::fidl::Encode(std::move(params));
  if (_encode_request_result.status != ZX_OK) {
    return ::fidl::DecodeResult<Controller::ResumeResponse>::FromFailure(
        std::move(_encode_request_result));
  }
  auto _call_result = ::fidl::Call<ResumeRequest, ResumeResponse>(
    std::move(_client_end), std::move(_encode_request_result.message), std::move(response_buffer));
  if (_call_result.status != ZX_OK) {
    return ::fidl::DecodeResult<Controller::ResumeResponse>::FromFailure(
        std::move(_call_result));
  }
  return ::fidl::Decode(std::move(_call_result.message));
}


bool Controller::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 kController_Bind_Ordinal:
    case kController_Bind_GenOrdinal:
    {
      auto result = ::fidl::DecodeAs<BindRequest>(msg);
      if (result.status != ZX_OK) {
        txn->Close(ZX_ERR_INVALID_ARGS);
        return true;
      }
      auto message = result.message.message();
      impl->Bind(std::move(message->driver),
        Interface::BindCompleter::Sync(txn));
      return true;
    }
    case kController_ScheduleUnbind_Ordinal:
    case kController_ScheduleUnbind_GenOrdinal:
    {
      auto result = ::fidl::DecodeAs<ScheduleUnbindRequest>(msg);
      if (result.status != ZX_OK) {
        txn->Close(ZX_ERR_INVALID_ARGS);
        return true;
      }
      impl->ScheduleUnbind(
        Interface::ScheduleUnbindCompleter::Sync(txn));
      return true;
    }
    case kController_GetDriverName_Ordinal:
    case kController_GetDriverName_GenOrdinal:
    {
      auto result = ::fidl::DecodeAs<GetDriverNameRequest>(msg);
      if (result.status != ZX_OK) {
        txn->Close(ZX_ERR_INVALID_ARGS);
        return true;
      }
      impl->GetDriverName(
        Interface::GetDriverNameCompleter::Sync(txn));
      return true;
    }
    case kController_GetDeviceName_Ordinal:
    case kController_GetDeviceName_GenOrdinal:
    {
      auto result = ::fidl::DecodeAs<GetDeviceNameRequest>(msg);
      if (result.status != ZX_OK) {
        txn->Close(ZX_ERR_INVALID_ARGS);
        return true;
      }
      impl->GetDeviceName(
        Interface::GetDeviceNameCompleter::Sync(txn));
      return true;
    }
    case kController_GetTopologicalPath_Ordinal:
    case kController_GetTopologicalPath_GenOrdinal:
    {
      auto result = ::fidl::DecodeAs<GetTopologicalPathRequest>(msg);
      if (result.status != ZX_OK) {
        txn->Close(ZX_ERR_INVALID_ARGS);
        return true;
      }
      impl->GetTopologicalPath(
        Interface::GetTopologicalPathCompleter::Sync(txn));
      return true;
    }
    case kController_GetEventHandle_Ordinal:
    case kController_GetEventHandle_GenOrdinal:
    {
      auto result = ::fidl::DecodeAs<GetEventHandleRequest>(msg);
      if (result.status != ZX_OK) {
        txn->Close(ZX_ERR_INVALID_ARGS);
        return true;
      }
      impl->GetEventHandle(
        Interface::GetEventHandleCompleter::Sync(txn));
      return true;
    }
    case kController_GetDriverLogFlags_Ordinal:
    case kController_GetDriverLogFlags_GenOrdinal:
    {
      auto result = ::fidl::DecodeAs<GetDriverLogFlagsRequest>(msg);
      if (result.status != ZX_OK) {
        txn->Close(ZX_ERR_INVALID_ARGS);
        return true;
      }
      impl->GetDriverLogFlags(
        Interface::GetDriverLogFlagsCompleter::Sync(txn));
      return true;
    }
    case kController_SetDriverLogFlags_Ordinal:
    case kController_SetDriverLogFlags_GenOrdinal:
    {
      auto result = ::fidl::DecodeAs<SetDriverLogFlagsRequest>(msg);
      if (result.status != ZX_OK) {
        txn->Close(ZX_ERR_INVALID_ARGS);
        return true;
      }
      auto message = result.message.message();
      impl->SetDriverLogFlags(std::move(message->clear_flags), std::move(message->set_flags),
        Interface::SetDriverLogFlagsCompleter::Sync(txn));
      return true;
    }
    case kController_DebugSuspend_Ordinal:
    case kController_DebugSuspend_GenOrdinal:
    {
      auto result = ::fidl::DecodeAs<DebugSuspendRequest>(msg);
      if (result.status != ZX_OK) {
        txn->Close(ZX_ERR_INVALID_ARGS);
        return true;
      }
      impl->DebugSuspend(
        Interface::DebugSuspendCompleter::Sync(txn));
      return true;
    }
    case kController_DebugResume_Ordinal:
    case kController_DebugResume_GenOrdinal:
    {
      auto result = ::fidl::DecodeAs<DebugResumeRequest>(msg);
      if (result.status != ZX_OK) {
        txn->Close(ZX_ERR_INVALID_ARGS);
        return true;
      }
      impl->DebugResume(
        Interface::DebugResumeCompleter::Sync(txn));
      return true;
    }
    case kController_RunCompatibilityTests_Ordinal:
    case kController_RunCompatibilityTests_GenOrdinal:
    {
      auto result = ::fidl::DecodeAs<RunCompatibilityTestsRequest>(msg);
      if (result.status != ZX_OK) {
        txn->Close(ZX_ERR_INVALID_ARGS);
        return true;
      }
      auto message = result.message.message();
      impl->RunCompatibilityTests(std::move(message->hook_wait_time),
        Interface::RunCompatibilityTestsCompleter::Sync(txn));
      return true;
    }
    case kController_GetDevicePowerCaps_Ordinal:
    case kController_GetDevicePowerCaps_GenOrdinal:
    {
      auto result = ::fidl::DecodeAs<GetDevicePowerCapsRequest>(msg);
      if (result.status != ZX_OK) {
        txn->Close(ZX_ERR_INVALID_ARGS);
        return true;
      }
      impl->GetDevicePowerCaps(
        Interface::GetDevicePowerCapsCompleter::Sync(txn));
      return true;
    }
    case kController_UpdatePowerStateMapping_Ordinal:
    case kController_UpdatePowerStateMapping_GenOrdinal:
    {
      auto result = ::fidl::DecodeAs<UpdatePowerStateMappingRequest>(msg);
      if (result.status != ZX_OK) {
        txn->Close(ZX_ERR_INVALID_ARGS);
        return true;
      }
      auto message = result.message.message();
      impl->UpdatePowerStateMapping(std::move(message->mapping),
        Interface::UpdatePowerStateMappingCompleter::Sync(txn));
      return true;
    }
    case kController_GetPowerStateMapping_Ordinal:
    case kController_GetPowerStateMapping_GenOrdinal:
    {
      auto result = ::fidl::DecodeAs<GetPowerStateMappingRequest>(msg);
      if (result.status != ZX_OK) {
        txn->Close(ZX_ERR_INVALID_ARGS);
        return true;
      }
      impl->GetPowerStateMapping(
        Interface::GetPowerStateMappingCompleter::Sync(txn));
      return true;
    }
    case kController_Suspend_Ordinal:
    case kController_Suspend_GenOrdinal:
    {
      auto result = ::fidl::DecodeAs<SuspendRequest>(msg);
      if (result.status != ZX_OK) {
        txn->Close(ZX_ERR_INVALID_ARGS);
        return true;
      }
      auto message = result.message.message();
      impl->Suspend(std::move(message->requested_state),
        Interface::SuspendCompleter::Sync(txn));
      return true;
    }
    case kController_Resume_Ordinal:
    case kController_Resume_GenOrdinal:
    {
      auto result = ::fidl::DecodeAs<ResumeRequest>(msg);
      if (result.status != ZX_OK) {
        txn->Close(ZX_ERR_INVALID_ARGS);
        return true;
      }
      auto message = result.message.message();
      impl->Resume(std::move(message->requested_state),
        Interface::ResumeCompleter::Sync(txn));
      return true;
    }
    default: {
      return false;
    }
  }
}

bool Controller::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 Controller::Interface::BindCompleterBase::Reply(int32_t status) {
  constexpr uint32_t _kWriteAllocSize = ::fidl::internal::ClampedMessageSize<BindResponse, ::fidl::MessageDirection::kSending>();
  FIDL_ALIGNDECL uint8_t _write_bytes[_kWriteAllocSize] = {};
  auto& _response = *reinterpret_cast<BindResponse*>(_write_bytes);
  _response._hdr.ordinal = kController_Bind_Ordinal;
  _response.status = std::move(status);
  ::fidl::BytePart _response_bytes(_write_bytes, _kWriteAllocSize, sizeof(BindResponse));
  CompleterBase::SendReply(::fidl::DecodedMessage<BindResponse>(std::move(_response_bytes)));
}

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

void Controller::Interface::BindCompleterBase::Reply(::fidl::DecodedMessage<BindResponse> params) {
  params.message()->_hdr = {};
  params.message()->_hdr.ordinal = kController_Bind_Ordinal;
  CompleterBase::SendReply(std::move(params));
}


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

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

void Controller::Interface::ScheduleUnbindCompleterBase::Reply(::fidl::DecodedMessage<ScheduleUnbindResponse> params) {
  params.message()->_hdr = {};
  params.message()->_hdr.ordinal = kController_ScheduleUnbind_Ordinal;
  CompleterBase::SendReply(std::move(params));
}


void Controller::Interface::GetDriverNameCompleterBase::Reply(int32_t status, ::fidl::StringView name) {
  constexpr uint32_t _kWriteAllocSize = ::fidl::internal::ClampedMessageSize<GetDriverNameResponse, ::fidl::MessageDirection::kSending>();
  FIDL_ALIGNDECL uint8_t _write_bytes[_kWriteAllocSize];
  GetDriverNameResponse _response = {};
  _response._hdr.ordinal = kController_GetDriverName_Ordinal;
  _response.status = std::move(status);
  _response.name = std::move(name);
  auto _linearize_result = ::fidl::Linearize(&_response, ::fidl::BytePart(_write_bytes,
                                                                          _kWriteAllocSize));
  if (_linearize_result.status != ZX_OK) {
    CompleterBase::Close(ZX_ERR_INTERNAL);
    return;
  }
  CompleterBase::SendReply(std::move(_linearize_result.message));
}

void Controller::Interface::GetDriverNameCompleterBase::Reply(::fidl::BytePart _buffer, int32_t status, ::fidl::StringView name) {
  if (_buffer.capacity() < GetDriverNameResponse::PrimarySize) {
    CompleterBase::Close(ZX_ERR_INTERNAL);
    return;
  }
  GetDriverNameResponse _response = {};
  _response._hdr.ordinal = kController_GetDriverName_Ordinal;
  _response.status = std::move(status);
  _response.name = std::move(name);
  auto _linearize_result = ::fidl::Linearize(&_response, std::move(_buffer));
  if (_linearize_result.status != ZX_OK) {
    CompleterBase::Close(ZX_ERR_INTERNAL);
    return;
  }
  CompleterBase::SendReply(std::move(_linearize_result.message));
}

void Controller::Interface::GetDriverNameCompleterBase::Reply(::fidl::DecodedMessage<GetDriverNameResponse> params) {
  params.message()->_hdr = {};
  params.message()->_hdr.ordinal = kController_GetDriverName_Ordinal;
  CompleterBase::SendReply(std::move(params));
}


void Controller::Interface::GetDeviceNameCompleterBase::Reply(::fidl::StringView name) {
  constexpr uint32_t _kWriteAllocSize = ::fidl::internal::ClampedMessageSize<GetDeviceNameResponse, ::fidl::MessageDirection::kSending>();
  FIDL_ALIGNDECL uint8_t _write_bytes[_kWriteAllocSize];
  GetDeviceNameResponse _response = {};
  _response._hdr.ordinal = kController_GetDeviceName_Ordinal;
  _response.name = std::move(name);
  auto _linearize_result = ::fidl::Linearize(&_response, ::fidl::BytePart(_write_bytes,
                                                                          _kWriteAllocSize));
  if (_linearize_result.status != ZX_OK) {
    CompleterBase::Close(ZX_ERR_INTERNAL);
    return;
  }
  CompleterBase::SendReply(std::move(_linearize_result.message));
}

void Controller::Interface::GetDeviceNameCompleterBase::Reply(::fidl::BytePart _buffer, ::fidl::StringView name) {
  if (_buffer.capacity() < GetDeviceNameResponse::PrimarySize) {
    CompleterBase::Close(ZX_ERR_INTERNAL);
    return;
  }
  GetDeviceNameResponse _response = {};
  _response._hdr.ordinal = kController_GetDeviceName_Ordinal;
  _response.name = std::move(name);
  auto _linearize_result = ::fidl::Linearize(&_response, std::move(_buffer));
  if (_linearize_result.status != ZX_OK) {
    CompleterBase::Close(ZX_ERR_INTERNAL);
    return;
  }
  CompleterBase::SendReply(std::move(_linearize_result.message));
}

void Controller::Interface::GetDeviceNameCompleterBase::Reply(::fidl::DecodedMessage<GetDeviceNameResponse> params) {
  params.message()->_hdr = {};
  params.message()->_hdr.ordinal = kController_GetDeviceName_Ordinal;
  CompleterBase::SendReply(std::move(params));
}


void Controller::Interface::GetTopologicalPathCompleterBase::Reply(int32_t status, ::fidl::StringView path) {
  constexpr uint32_t _kWriteAllocSize = ::fidl::internal::ClampedMessageSize<GetTopologicalPathResponse, ::fidl::MessageDirection::kSending>();
  std::unique_ptr<uint8_t[]> _write_bytes_unique_ptr(new uint8_t[_kWriteAllocSize]);
  uint8_t* _write_bytes = _write_bytes_unique_ptr.get();
  GetTopologicalPathResponse _response = {};
  _response._hdr.ordinal = kController_GetTopologicalPath_Ordinal;
  _response.status = std::move(status);
  _response.path = std::move(path);
  auto _linearize_result = ::fidl::Linearize(&_response, ::fidl::BytePart(_write_bytes,
                                                                          _kWriteAllocSize));
  if (_linearize_result.status != ZX_OK) {
    CompleterBase::Close(ZX_ERR_INTERNAL);
    return;
  }
  CompleterBase::SendReply(std::move(_linearize_result.message));
}

void Controller::Interface::GetTopologicalPathCompleterBase::Reply(::fidl::BytePart _buffer, int32_t status, ::fidl::StringView path) {
  if (_buffer.capacity() < GetTopologicalPathResponse::PrimarySize) {
    CompleterBase::Close(ZX_ERR_INTERNAL);
    return;
  }
  GetTopologicalPathResponse _response = {};
  _response._hdr.ordinal = kController_GetTopologicalPath_Ordinal;
  _response.status = std::move(status);
  _response.path = std::move(path);
  auto _linearize_result = ::fidl::Linearize(&_response, std::move(_buffer));
  if (_linearize_result.status != ZX_OK) {
    CompleterBase::Close(ZX_ERR_INTERNAL);
    return;
  }
  CompleterBase::SendReply(std::move(_linearize_result.message));
}

void Controller::Interface::GetTopologicalPathCompleterBase::Reply(::fidl::DecodedMessage<GetTopologicalPathResponse> params) {
  params.message()->_hdr = {};
  params.message()->_hdr.ordinal = kController_GetTopologicalPath_Ordinal;
  CompleterBase::SendReply(std::move(params));
}


void Controller::Interface::GetEventHandleCompleterBase::Reply(int32_t status, ::zx::event event) {
  constexpr uint32_t _kWriteAllocSize = ::fidl::internal::ClampedMessageSize<GetEventHandleResponse, ::fidl::MessageDirection::kSending>();
  FIDL_ALIGNDECL uint8_t _write_bytes[_kWriteAllocSize] = {};
  auto& _response = *reinterpret_cast<GetEventHandleResponse*>(_write_bytes);
  _response._hdr.ordinal = kController_GetEventHandle_Ordinal;
  _response.status = std::move(status);
  _response.event = std::move(event);
  ::fidl::BytePart _response_bytes(_write_bytes, _kWriteAllocSize, sizeof(GetEventHandleResponse));
  CompleterBase::SendReply(::fidl::DecodedMessage<GetEventHandleResponse>(std::move(_response_bytes)));
}

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

void Controller::Interface::GetEventHandleCompleterBase::Reply(::fidl::DecodedMessage<GetEventHandleResponse> params) {
  params.message()->_hdr = {};
  params.message()->_hdr.ordinal = kController_GetEventHandle_Ordinal;
  CompleterBase::SendReply(std::move(params));
}


void Controller::Interface::GetDriverLogFlagsCompleterBase::Reply(int32_t status, uint32_t flags) {
  constexpr uint32_t _kWriteAllocSize = ::fidl::internal::ClampedMessageSize<GetDriverLogFlagsResponse, ::fidl::MessageDirection::kSending>();
  FIDL_ALIGNDECL uint8_t _write_bytes[_kWriteAllocSize] = {};
  auto& _response = *reinterpret_cast<GetDriverLogFlagsResponse*>(_write_bytes);
  _response._hdr.ordinal = kController_GetDriverLogFlags_Ordinal;
  _response.status = std::move(status);
  _response.flags = std::move(flags);
  ::fidl::BytePart _response_bytes(_write_bytes, _kWriteAllocSize, sizeof(GetDriverLogFlagsResponse));
  CompleterBase::SendReply(::fidl::DecodedMessage<GetDriverLogFlagsResponse>(std::move(_response_bytes)));
}

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

void Controller::Interface::GetDriverLogFlagsCompleterBase::Reply(::fidl::DecodedMessage<GetDriverLogFlagsResponse> params) {
  params.message()->_hdr = {};
  params.message()->_hdr.ordinal = kController_GetDriverLogFlags_Ordinal;
  CompleterBase::SendReply(std::move(params));
}


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

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

void Controller::Interface::SetDriverLogFlagsCompleterBase::Reply(::fidl::DecodedMessage<SetDriverLogFlagsResponse> params) {
  params.message()->_hdr = {};
  params.message()->_hdr.ordinal = kController_SetDriverLogFlags_Ordinal;
  CompleterBase::SendReply(std::move(params));
}


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

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

void Controller::Interface::DebugSuspendCompleterBase::Reply(::fidl::DecodedMessage<DebugSuspendResponse> params) {
  params.message()->_hdr = {};
  params.message()->_hdr.ordinal = kController_DebugSuspend_Ordinal;
  CompleterBase::SendReply(std::move(params));
}


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

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

void Controller::Interface::DebugResumeCompleterBase::Reply(::fidl::DecodedMessage<DebugResumeResponse> params) {
  params.message()->_hdr = {};
  params.message()->_hdr.ordinal = kController_DebugResume_Ordinal;
  CompleterBase::SendReply(std::move(params));
}


void Controller::Interface::RunCompatibilityTestsCompleterBase::Reply(uint32_t status) {
  constexpr uint32_t _kWriteAllocSize = ::fidl::internal::ClampedMessageSize<RunCompatibilityTestsResponse, ::fidl::MessageDirection::kSending>();
  FIDL_ALIGNDECL uint8_t _write_bytes[_kWriteAllocSize] = {};
  auto& _response = *reinterpret_cast<RunCompatibilityTestsResponse*>(_write_bytes);
  _response._hdr.ordinal = kController_RunCompatibilityTests_Ordinal;
  _response.status = std::move(status);
  ::fidl::BytePart _response_bytes(_write_bytes, _kWriteAllocSize, sizeof(RunCompatibilityTestsResponse));
  CompleterBase::SendReply(::fidl::DecodedMessage<RunCompatibilityTestsResponse>(std::move(_response_bytes)));
}

void Controller::Interface::RunCompatibilityTestsCompleterBase::Reply(::fidl::BytePart _buffer, uint32_t status) {
  if (_buffer.capacity() < RunCompatibilityTestsResponse::PrimarySize) {
    CompleterBase::Close(ZX_ERR_INTERNAL);
    return;
  }
  auto& _response = *reinterpret_cast<RunCompatibilityTestsResponse*>(_buffer.data());
  _response._hdr.ordinal = kController_RunCompatibilityTests_Ordinal;
  _response.status = std::move(status);
  _buffer.set_actual(sizeof(RunCompatibilityTestsResponse));
  CompleterBase::SendReply(::fidl::DecodedMessage<RunCompatibilityTestsResponse>(std::move(_buffer)));
}

void Controller::Interface::RunCompatibilityTestsCompleterBase::Reply(::fidl::DecodedMessage<RunCompatibilityTestsResponse> params) {
  params.message()->_hdr = {};
  params.message()->_hdr.ordinal = kController_RunCompatibilityTests_Ordinal;
  CompleterBase::SendReply(std::move(params));
}


void Controller::Interface::GetDevicePowerCapsCompleterBase::Reply(Controller_GetDevicePowerCaps_Result result) {
  constexpr uint32_t _kWriteAllocSize = ::fidl::internal::ClampedMessageSize<GetDevicePowerCapsResponse, ::fidl::MessageDirection::kSending>();
  FIDL_ALIGNDECL uint8_t _write_bytes[_kWriteAllocSize] = {};
  auto& _response = *reinterpret_cast<GetDevicePowerCapsResponse*>(_write_bytes);
  _response._hdr.ordinal = kController_GetDevicePowerCaps_Ordinal;
  _response.result = std::move(result);
  ::fidl::BytePart _response_bytes(_write_bytes, _kWriteAllocSize, sizeof(GetDevicePowerCapsResponse));
  CompleterBase::SendReply(::fidl::DecodedMessage<GetDevicePowerCapsResponse>(std::move(_response_bytes)));
}
void Controller::Interface::GetDevicePowerCapsCompleterBase::ReplySuccess(::fidl::Array<DevicePowerStateInfo, 5> dpstates) {
  Controller_GetDevicePowerCaps_Response response;
  response.dpstates = std::move(dpstates);

  Reply(Controller_GetDevicePowerCaps_Result::WithResponse(std::move(response)));
}
void Controller::Interface::GetDevicePowerCapsCompleterBase::ReplyError(int32_t error) {
  Reply(Controller_GetDevicePowerCaps_Result::WithErr(std::move(error)));
}

void Controller::Interface::GetDevicePowerCapsCompleterBase::Reply(::fidl::BytePart _buffer, Controller_GetDevicePowerCaps_Result result) {
  if (_buffer.capacity() < GetDevicePowerCapsResponse::PrimarySize) {
    CompleterBase::Close(ZX_ERR_INTERNAL);
    return;
  }
  auto& _response = *reinterpret_cast<GetDevicePowerCapsResponse*>(_buffer.data());
  _response._hdr.ordinal = kController_GetDevicePowerCaps_Ordinal;
  _response.result = std::move(result);
  _buffer.set_actual(sizeof(GetDevicePowerCapsResponse));
  CompleterBase::SendReply(::fidl::DecodedMessage<GetDevicePowerCapsResponse>(std::move(_buffer)));
}
void Controller::Interface::GetDevicePowerCapsCompleterBase::ReplySuccess(::fidl::BytePart _buffer, ::fidl::Array<DevicePowerStateInfo, 5> dpstates) {
  Controller_GetDevicePowerCaps_Response response;
  response.dpstates = std::move(dpstates);

  Reply(std::move(_buffer), Controller_GetDevicePowerCaps_Result::WithResponse(std::move(response)));
}

void Controller::Interface::GetDevicePowerCapsCompleterBase::Reply(::fidl::DecodedMessage<GetDevicePowerCapsResponse> params) {
  params.message()->_hdr = {};
  params.message()->_hdr.ordinal = kController_GetDevicePowerCaps_Ordinal;
  CompleterBase::SendReply(std::move(params));
}


void Controller::Interface::UpdatePowerStateMappingCompleterBase::Reply(Controller_UpdatePowerStateMapping_Result result) {
  constexpr uint32_t _kWriteAllocSize = ::fidl::internal::ClampedMessageSize<UpdatePowerStateMappingResponse, ::fidl::MessageDirection::kSending>();
  FIDL_ALIGNDECL uint8_t _write_bytes[_kWriteAllocSize] = {};
  auto& _response = *reinterpret_cast<UpdatePowerStateMappingResponse*>(_write_bytes);
  _response._hdr.ordinal = kController_UpdatePowerStateMapping_Ordinal;
  _response.result = std::move(result);
  ::fidl::BytePart _response_bytes(_write_bytes, _kWriteAllocSize, sizeof(UpdatePowerStateMappingResponse));
  CompleterBase::SendReply(::fidl::DecodedMessage<UpdatePowerStateMappingResponse>(std::move(_response_bytes)));
}
void Controller::Interface::UpdatePowerStateMappingCompleterBase::ReplySuccess() {
  Controller_UpdatePowerStateMapping_Response response;

  Reply(Controller_UpdatePowerStateMapping_Result::WithResponse(std::move(response)));
}
void Controller::Interface::UpdatePowerStateMappingCompleterBase::ReplyError(int32_t error) {
  Reply(Controller_UpdatePowerStateMapping_Result::WithErr(std::move(error)));
}

void Controller::Interface::UpdatePowerStateMappingCompleterBase::Reply(::fidl::BytePart _buffer, Controller_UpdatePowerStateMapping_Result result) {
  if (_buffer.capacity() < UpdatePowerStateMappingResponse::PrimarySize) {
    CompleterBase::Close(ZX_ERR_INTERNAL);
    return;
  }
  auto& _response = *reinterpret_cast<UpdatePowerStateMappingResponse*>(_buffer.data());
  _response._hdr.ordinal = kController_UpdatePowerStateMapping_Ordinal;
  _response.result = std::move(result);
  _buffer.set_actual(sizeof(UpdatePowerStateMappingResponse));
  CompleterBase::SendReply(::fidl::DecodedMessage<UpdatePowerStateMappingResponse>(std::move(_buffer)));
}
void Controller::Interface::UpdatePowerStateMappingCompleterBase::ReplySuccess(::fidl::BytePart _buffer) {
  Controller_UpdatePowerStateMapping_Response response;

  Reply(std::move(_buffer), Controller_UpdatePowerStateMapping_Result::WithResponse(std::move(response)));
}

void Controller::Interface::UpdatePowerStateMappingCompleterBase::Reply(::fidl::DecodedMessage<UpdatePowerStateMappingResponse> params) {
  params.message()->_hdr = {};
  params.message()->_hdr.ordinal = kController_UpdatePowerStateMapping_Ordinal;
  CompleterBase::SendReply(std::move(params));
}


void Controller::Interface::GetPowerStateMappingCompleterBase::Reply(Controller_GetPowerStateMapping_Result result) {
  constexpr uint32_t _kWriteAllocSize = ::fidl::internal::ClampedMessageSize<GetPowerStateMappingResponse, ::fidl::MessageDirection::kSending>();
  FIDL_ALIGNDECL uint8_t _write_bytes[_kWriteAllocSize] = {};
  auto& _response = *reinterpret_cast<GetPowerStateMappingResponse*>(_write_bytes);
  _response._hdr.ordinal = kController_GetPowerStateMapping_Ordinal;
  _response.result = std::move(result);
  ::fidl::BytePart _response_bytes(_write_bytes, _kWriteAllocSize, sizeof(GetPowerStateMappingResponse));
  CompleterBase::SendReply(::fidl::DecodedMessage<GetPowerStateMappingResponse>(std::move(_response_bytes)));
}
void Controller::Interface::GetPowerStateMappingCompleterBase::ReplySuccess(::fidl::Array<SystemPowerStateInfo, 7> mapping) {
  Controller_GetPowerStateMapping_Response response;
  response.mapping = std::move(mapping);

  Reply(Controller_GetPowerStateMapping_Result::WithResponse(std::move(response)));
}
void Controller::Interface::GetPowerStateMappingCompleterBase::ReplyError(int32_t error) {
  Reply(Controller_GetPowerStateMapping_Result::WithErr(std::move(error)));
}

void Controller::Interface::GetPowerStateMappingCompleterBase::Reply(::fidl::BytePart _buffer, Controller_GetPowerStateMapping_Result result) {
  if (_buffer.capacity() < GetPowerStateMappingResponse::PrimarySize) {
    CompleterBase::Close(ZX_ERR_INTERNAL);
    return;
  }
  auto& _response = *reinterpret_cast<GetPowerStateMappingResponse*>(_buffer.data());
  _response._hdr.ordinal = kController_GetPowerStateMapping_Ordinal;
  _response.result = std::move(result);
  _buffer.set_actual(sizeof(GetPowerStateMappingResponse));
  CompleterBase::SendReply(::fidl::DecodedMessage<GetPowerStateMappingResponse>(std::move(_buffer)));
}
void Controller::Interface::GetPowerStateMappingCompleterBase::ReplySuccess(::fidl::BytePart _buffer, ::fidl::Array<SystemPowerStateInfo, 7> mapping) {
  Controller_GetPowerStateMapping_Response response;
  response.mapping = std::move(mapping);

  Reply(std::move(_buffer), Controller_GetPowerStateMapping_Result::WithResponse(std::move(response)));
}

void Controller::Interface::GetPowerStateMappingCompleterBase::Reply(::fidl::DecodedMessage<GetPowerStateMappingResponse> params) {
  params.message()->_hdr = {};
  params.message()->_hdr.ordinal = kController_GetPowerStateMapping_Ordinal;
  CompleterBase::SendReply(std::move(params));
}


void Controller::Interface::SuspendCompleterBase::Reply(int32_t status, DevicePowerState out_state) {
  constexpr uint32_t _kWriteAllocSize = ::fidl::internal::ClampedMessageSize<SuspendResponse, ::fidl::MessageDirection::kSending>();
  FIDL_ALIGNDECL uint8_t _write_bytes[_kWriteAllocSize] = {};
  auto& _response = *reinterpret_cast<SuspendResponse*>(_write_bytes);
  _response._hdr.ordinal = kController_Suspend_Ordinal;
  _response.status = std::move(status);
  _response.out_state = std::move(out_state);
  ::fidl::BytePart _response_bytes(_write_bytes, _kWriteAllocSize, sizeof(SuspendResponse));
  CompleterBase::SendReply(::fidl::DecodedMessage<SuspendResponse>(std::move(_response_bytes)));
}

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

void Controller::Interface::SuspendCompleterBase::Reply(::fidl::DecodedMessage<SuspendResponse> params) {
  params.message()->_hdr = {};
  params.message()->_hdr.ordinal = kController_Suspend_Ordinal;
  CompleterBase::SendReply(std::move(params));
}


void Controller::Interface::ResumeCompleterBase::Reply(Controller_Resume_Result result) {
  constexpr uint32_t _kWriteAllocSize = ::fidl::internal::ClampedMessageSize<ResumeResponse, ::fidl::MessageDirection::kSending>();
  FIDL_ALIGNDECL uint8_t _write_bytes[_kWriteAllocSize] = {};
  auto& _response = *reinterpret_cast<ResumeResponse*>(_write_bytes);
  _response._hdr.ordinal = kController_Resume_Ordinal;
  _response.result = std::move(result);
  ::fidl::BytePart _response_bytes(_write_bytes, _kWriteAllocSize, sizeof(ResumeResponse));
  CompleterBase::SendReply(::fidl::DecodedMessage<ResumeResponse>(std::move(_response_bytes)));
}
void Controller::Interface::ResumeCompleterBase::ReplySuccess(DevicePowerState out_state) {
  Controller_Resume_Response response;
  response.out_state = std::move(out_state);

  Reply(Controller_Resume_Result::WithResponse(std::move(response)));
}
void Controller::Interface::ResumeCompleterBase::ReplyError(int32_t error) {
  Reply(Controller_Resume_Result::WithErr(std::move(error)));
}

void Controller::Interface::ResumeCompleterBase::Reply(::fidl::BytePart _buffer, Controller_Resume_Result result) {
  if (_buffer.capacity() < ResumeResponse::PrimarySize) {
    CompleterBase::Close(ZX_ERR_INTERNAL);
    return;
  }
  auto& _response = *reinterpret_cast<ResumeResponse*>(_buffer.data());
  _response._hdr.ordinal = kController_Resume_Ordinal;
  _response.result = std::move(result);
  _buffer.set_actual(sizeof(ResumeResponse));
  CompleterBase::SendReply(::fidl::DecodedMessage<ResumeResponse>(std::move(_buffer)));
}
void Controller::Interface::ResumeCompleterBase::ReplySuccess(::fidl::BytePart _buffer, DevicePowerState out_state) {
  Controller_Resume_Response response;
  response.out_state = std::move(out_state);

  Reply(std::move(_buffer), Controller_Resume_Result::WithResponse(std::move(response)));
}

void Controller::Interface::ResumeCompleterBase::Reply(::fidl::DecodedMessage<ResumeResponse> params) {
  params.message()->_hdr = {};
  params.message()->_hdr.ordinal = kController_Resume_Ordinal;
  CompleterBase::SendReply(std::move(params));
}


}  // namespace device
}  // namespace fuchsia
}  // namespace llcpp
