// Copyright 2022 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

// Generated by the Codegen C++ plugin.
// If you make any local changes, they will be lost.
// source: google/cloud/vmmigration/v1/vmmigration.proto

#include "google/cloud/vmmigration/v1/internal/vm_migration_connection_impl.h"
#include "google/cloud/vmmigration/v1/internal/vm_migration_option_defaults.h"
#include "google/cloud/background_threads.h"
#include "google/cloud/common_options.h"
#include "google/cloud/grpc_options.h"
#include "google/cloud/internal/async_long_running_operation.h"
#include "google/cloud/internal/pagination_range.h"
#include "google/cloud/internal/retry_loop.h"
#include <memory>

namespace google {
namespace cloud {
namespace vmmigration_v1_internal {
GOOGLE_CLOUD_CPP_INLINE_NAMESPACE_BEGIN
namespace {

std::unique_ptr<vmmigration_v1::VmMigrationRetryPolicy> retry_policy(
    Options const& options) {
  return options.get<vmmigration_v1::VmMigrationRetryPolicyOption>()->clone();
}

std::unique_ptr<BackoffPolicy> backoff_policy(Options const& options) {
  return options.get<vmmigration_v1::VmMigrationBackoffPolicyOption>()->clone();
}

std::unique_ptr<vmmigration_v1::VmMigrationConnectionIdempotencyPolicy>
idempotency_policy(Options const& options) {
  return options
      .get<vmmigration_v1::VmMigrationConnectionIdempotencyPolicyOption>()
      ->clone();
}

std::unique_ptr<PollingPolicy> polling_policy(Options const& options) {
  return options.get<vmmigration_v1::VmMigrationPollingPolicyOption>()->clone();
}

}  // namespace

VmMigrationConnectionImpl::VmMigrationConnectionImpl(
    std::unique_ptr<google::cloud::BackgroundThreads> background,
    std::shared_ptr<vmmigration_v1_internal::VmMigrationStub> stub,
    Options options)
    : background_(std::move(background)),
      stub_(std::move(stub)),
      options_(internal::MergeOptions(std::move(options),
                                      VmMigrationConnection::options())) {}

StreamRange<google::cloud::vmmigration::v1::Source>
VmMigrationConnectionImpl::ListSources(
    google::cloud::vmmigration::v1::ListSourcesRequest request) {
  request.clear_page_token();
  auto current = google::cloud::internal::SaveCurrentOptions();
  auto idempotency = idempotency_policy(*current)->ListSources(request);
  char const* function_name = __func__;
  return google::cloud::internal::MakePaginationRange<
      StreamRange<google::cloud::vmmigration::v1::Source>>(
      std::move(request),
      [idempotency, function_name, stub = stub_,
       retry = std::shared_ptr<vmmigration_v1::VmMigrationRetryPolicy>(
           retry_policy(*current)),
       backoff = std::shared_ptr<BackoffPolicy>(backoff_policy(*current))](
          google::cloud::vmmigration::v1::ListSourcesRequest const& r) {
        return google::cloud::internal::RetryLoop(
            retry->clone(), backoff->clone(), idempotency,
            [stub](grpc::ClientContext& context,
                   google::cloud::vmmigration::v1::ListSourcesRequest const&
                       request) { return stub->ListSources(context, request); },
            r, function_name);
      },
      [](google::cloud::vmmigration::v1::ListSourcesResponse r) {
        std::vector<google::cloud::vmmigration::v1::Source> result(
            r.sources().size());
        auto& messages = *r.mutable_sources();
        std::move(messages.begin(), messages.end(), result.begin());
        return result;
      });
}

StatusOr<google::cloud::vmmigration::v1::Source>
VmMigrationConnectionImpl::GetSource(
    google::cloud::vmmigration::v1::GetSourceRequest const& request) {
  auto current = google::cloud::internal::SaveCurrentOptions();
  return google::cloud::internal::RetryLoop(
      retry_policy(*current), backoff_policy(*current),
      idempotency_policy(*current)->GetSource(request),
      [this](grpc::ClientContext& context,
             google::cloud::vmmigration::v1::GetSourceRequest const& request) {
        return stub_->GetSource(context, request);
      },
      request, __func__);
}

future<StatusOr<google::cloud::vmmigration::v1::Source>>
VmMigrationConnectionImpl::CreateSource(
    google::cloud::vmmigration::v1::CreateSourceRequest const& request) {
  auto current = google::cloud::internal::SaveCurrentOptions();
  return google::cloud::internal::AsyncLongRunningOperation<
      google::cloud::vmmigration::v1::Source>(
      background_->cq(), current, request,
      [stub = stub_](
          google::cloud::CompletionQueue& cq,
          std::shared_ptr<grpc::ClientContext> context, Options const& options,
          google::cloud::vmmigration::v1::CreateSourceRequest const& request) {
        return stub->AsyncCreateSource(cq, std::move(context), options,
                                       request);
      },
      [stub = stub_](google::cloud::CompletionQueue& cq,
                     std::shared_ptr<grpc::ClientContext> context,
                     Options const& options,
                     google::longrunning::GetOperationRequest const& request) {
        return stub->AsyncGetOperation(cq, std::move(context), options,
                                       request);
      },
      [stub = stub_](
          google::cloud::CompletionQueue& cq,
          std::shared_ptr<grpc::ClientContext> context, Options const& options,
          google::longrunning::CancelOperationRequest const& request) {
        return stub->AsyncCancelOperation(cq, std::move(context), options,
                                          request);
      },
      &google::cloud::internal::ExtractLongRunningResultResponse<
          google::cloud::vmmigration::v1::Source>,
      retry_policy(*current), backoff_policy(*current),
      idempotency_policy(*current)->CreateSource(request),
      polling_policy(*current), __func__);
}

future<StatusOr<google::cloud::vmmigration::v1::Source>>
VmMigrationConnectionImpl::UpdateSource(
    google::cloud::vmmigration::v1::UpdateSourceRequest const& request) {
  auto current = google::cloud::internal::SaveCurrentOptions();
  return google::cloud::internal::AsyncLongRunningOperation<
      google::cloud::vmmigration::v1::Source>(
      background_->cq(), current, request,
      [stub = stub_](
          google::cloud::CompletionQueue& cq,
          std::shared_ptr<grpc::ClientContext> context, Options const& options,
          google::cloud::vmmigration::v1::UpdateSourceRequest const& request) {
        return stub->AsyncUpdateSource(cq, std::move(context), options,
                                       request);
      },
      [stub = stub_](google::cloud::CompletionQueue& cq,
                     std::shared_ptr<grpc::ClientContext> context,
                     Options const& options,
                     google::longrunning::GetOperationRequest const& request) {
        return stub->AsyncGetOperation(cq, std::move(context), options,
                                       request);
      },
      [stub = stub_](
          google::cloud::CompletionQueue& cq,
          std::shared_ptr<grpc::ClientContext> context, Options const& options,
          google::longrunning::CancelOperationRequest const& request) {
        return stub->AsyncCancelOperation(cq, std::move(context), options,
                                          request);
      },
      &google::cloud::internal::ExtractLongRunningResultResponse<
          google::cloud::vmmigration::v1::Source>,
      retry_policy(*current), backoff_policy(*current),
      idempotency_policy(*current)->UpdateSource(request),
      polling_policy(*current), __func__);
}

future<StatusOr<google::cloud::vmmigration::v1::OperationMetadata>>
VmMigrationConnectionImpl::DeleteSource(
    google::cloud::vmmigration::v1::DeleteSourceRequest const& request) {
  auto current = google::cloud::internal::SaveCurrentOptions();
  return google::cloud::internal::AsyncLongRunningOperation<
      google::cloud::vmmigration::v1::OperationMetadata>(
      background_->cq(), current, request,
      [stub = stub_](
          google::cloud::CompletionQueue& cq,
          std::shared_ptr<grpc::ClientContext> context, Options const& options,
          google::cloud::vmmigration::v1::DeleteSourceRequest const& request) {
        return stub->AsyncDeleteSource(cq, std::move(context), options,
                                       request);
      },
      [stub = stub_](google::cloud::CompletionQueue& cq,
                     std::shared_ptr<grpc::ClientContext> context,
                     Options const& options,
                     google::longrunning::GetOperationRequest const& request) {
        return stub->AsyncGetOperation(cq, std::move(context), options,
                                       request);
      },
      [stub = stub_](
          google::cloud::CompletionQueue& cq,
          std::shared_ptr<grpc::ClientContext> context, Options const& options,
          google::longrunning::CancelOperationRequest const& request) {
        return stub->AsyncCancelOperation(cq, std::move(context), options,
                                          request);
      },
      &google::cloud::internal::ExtractLongRunningResultMetadata<
          google::cloud::vmmigration::v1::OperationMetadata>,
      retry_policy(*current), backoff_policy(*current),
      idempotency_policy(*current)->DeleteSource(request),
      polling_policy(*current), __func__);
}

StatusOr<google::cloud::vmmigration::v1::FetchInventoryResponse>
VmMigrationConnectionImpl::FetchInventory(
    google::cloud::vmmigration::v1::FetchInventoryRequest const& request) {
  auto current = google::cloud::internal::SaveCurrentOptions();
  return google::cloud::internal::RetryLoop(
      retry_policy(*current), backoff_policy(*current),
      idempotency_policy(*current)->FetchInventory(request),
      [this](grpc::ClientContext& context,
             google::cloud::vmmigration::v1::FetchInventoryRequest const&
                 request) { return stub_->FetchInventory(context, request); },
      request, __func__);
}

StreamRange<google::cloud::vmmigration::v1::UtilizationReport>
VmMigrationConnectionImpl::ListUtilizationReports(
    google::cloud::vmmigration::v1::ListUtilizationReportsRequest request) {
  request.clear_page_token();
  auto current = google::cloud::internal::SaveCurrentOptions();
  auto idempotency =
      idempotency_policy(*current)->ListUtilizationReports(request);
  char const* function_name = __func__;
  return google::cloud::internal::MakePaginationRange<
      StreamRange<google::cloud::vmmigration::v1::UtilizationReport>>(
      std::move(request),
      [idempotency, function_name, stub = stub_,
       retry = std::shared_ptr<vmmigration_v1::VmMigrationRetryPolicy>(
           retry_policy(*current)),
       backoff = std::shared_ptr<BackoffPolicy>(backoff_policy(*current))](
          google::cloud::vmmigration::v1::ListUtilizationReportsRequest const&
              r) {
        return google::cloud::internal::RetryLoop(
            retry->clone(), backoff->clone(), idempotency,
            [stub](grpc::ClientContext& context,
                   google::cloud::vmmigration::v1::
                       ListUtilizationReportsRequest const& request) {
              return stub->ListUtilizationReports(context, request);
            },
            r, function_name);
      },
      [](google::cloud::vmmigration::v1::ListUtilizationReportsResponse r) {
        std::vector<google::cloud::vmmigration::v1::UtilizationReport> result(
            r.utilization_reports().size());
        auto& messages = *r.mutable_utilization_reports();
        std::move(messages.begin(), messages.end(), result.begin());
        return result;
      });
}

StatusOr<google::cloud::vmmigration::v1::UtilizationReport>
VmMigrationConnectionImpl::GetUtilizationReport(
    google::cloud::vmmigration::v1::GetUtilizationReportRequest const&
        request) {
  auto current = google::cloud::internal::SaveCurrentOptions();
  return google::cloud::internal::RetryLoop(
      retry_policy(*current), backoff_policy(*current),
      idempotency_policy(*current)->GetUtilizationReport(request),
      [this](grpc::ClientContext& context,
             google::cloud::vmmigration::v1::GetUtilizationReportRequest const&
                 request) {
        return stub_->GetUtilizationReport(context, request);
      },
      request, __func__);
}

future<StatusOr<google::cloud::vmmigration::v1::UtilizationReport>>
VmMigrationConnectionImpl::CreateUtilizationReport(
    google::cloud::vmmigration::v1::CreateUtilizationReportRequest const&
        request) {
  auto current = google::cloud::internal::SaveCurrentOptions();
  return google::cloud::internal::AsyncLongRunningOperation<
      google::cloud::vmmigration::v1::UtilizationReport>(
      background_->cq(), current, request,
      [stub = stub_](
          google::cloud::CompletionQueue& cq,
          std::shared_ptr<grpc::ClientContext> context, Options const& options,
          google::cloud::vmmigration::v1::CreateUtilizationReportRequest const&
              request) {
        return stub->AsyncCreateUtilizationReport(cq, std::move(context),
                                                  options, request);
      },
      [stub = stub_](google::cloud::CompletionQueue& cq,
                     std::shared_ptr<grpc::ClientContext> context,
                     Options const& options,
                     google::longrunning::GetOperationRequest const& request) {
        return stub->AsyncGetOperation(cq, std::move(context), options,
                                       request);
      },
      [stub = stub_](
          google::cloud::CompletionQueue& cq,
          std::shared_ptr<grpc::ClientContext> context, Options const& options,
          google::longrunning::CancelOperationRequest const& request) {
        return stub->AsyncCancelOperation(cq, std::move(context), options,
                                          request);
      },
      &google::cloud::internal::ExtractLongRunningResultResponse<
          google::cloud::vmmigration::v1::UtilizationReport>,
      retry_policy(*current), backoff_policy(*current),
      idempotency_policy(*current)->CreateUtilizationReport(request),
      polling_policy(*current), __func__);
}

future<StatusOr<google::cloud::vmmigration::v1::OperationMetadata>>
VmMigrationConnectionImpl::DeleteUtilizationReport(
    google::cloud::vmmigration::v1::DeleteUtilizationReportRequest const&
        request) {
  auto current = google::cloud::internal::SaveCurrentOptions();
  return google::cloud::internal::AsyncLongRunningOperation<
      google::cloud::vmmigration::v1::OperationMetadata>(
      background_->cq(), current, request,
      [stub = stub_](
          google::cloud::CompletionQueue& cq,
          std::shared_ptr<grpc::ClientContext> context, Options const& options,
          google::cloud::vmmigration::v1::DeleteUtilizationReportRequest const&
              request) {
        return stub->AsyncDeleteUtilizationReport(cq, std::move(context),
                                                  options, request);
      },
      [stub = stub_](google::cloud::CompletionQueue& cq,
                     std::shared_ptr<grpc::ClientContext> context,
                     Options const& options,
                     google::longrunning::GetOperationRequest const& request) {
        return stub->AsyncGetOperation(cq, std::move(context), options,
                                       request);
      },
      [stub = stub_](
          google::cloud::CompletionQueue& cq,
          std::shared_ptr<grpc::ClientContext> context, Options const& options,
          google::longrunning::CancelOperationRequest const& request) {
        return stub->AsyncCancelOperation(cq, std::move(context), options,
                                          request);
      },
      &google::cloud::internal::ExtractLongRunningResultMetadata<
          google::cloud::vmmigration::v1::OperationMetadata>,
      retry_policy(*current), backoff_policy(*current),
      idempotency_policy(*current)->DeleteUtilizationReport(request),
      polling_policy(*current), __func__);
}

StreamRange<google::cloud::vmmigration::v1::DatacenterConnector>
VmMigrationConnectionImpl::ListDatacenterConnectors(
    google::cloud::vmmigration::v1::ListDatacenterConnectorsRequest request) {
  request.clear_page_token();
  auto current = google::cloud::internal::SaveCurrentOptions();
  auto idempotency =
      idempotency_policy(*current)->ListDatacenterConnectors(request);
  char const* function_name = __func__;
  return google::cloud::internal::MakePaginationRange<
      StreamRange<google::cloud::vmmigration::v1::DatacenterConnector>>(
      std::move(request),
      [idempotency, function_name, stub = stub_,
       retry = std::shared_ptr<vmmigration_v1::VmMigrationRetryPolicy>(
           retry_policy(*current)),
       backoff = std::shared_ptr<BackoffPolicy>(backoff_policy(*current))](
          google::cloud::vmmigration::v1::ListDatacenterConnectorsRequest const&
              r) {
        return google::cloud::internal::RetryLoop(
            retry->clone(), backoff->clone(), idempotency,
            [stub](grpc::ClientContext& context,
                   google::cloud::vmmigration::v1::
                       ListDatacenterConnectorsRequest const& request) {
              return stub->ListDatacenterConnectors(context, request);
            },
            r, function_name);
      },
      [](google::cloud::vmmigration::v1::ListDatacenterConnectorsResponse r) {
        std::vector<google::cloud::vmmigration::v1::DatacenterConnector> result(
            r.datacenter_connectors().size());
        auto& messages = *r.mutable_datacenter_connectors();
        std::move(messages.begin(), messages.end(), result.begin());
        return result;
      });
}

StatusOr<google::cloud::vmmigration::v1::DatacenterConnector>
VmMigrationConnectionImpl::GetDatacenterConnector(
    google::cloud::vmmigration::v1::GetDatacenterConnectorRequest const&
        request) {
  auto current = google::cloud::internal::SaveCurrentOptions();
  return google::cloud::internal::RetryLoop(
      retry_policy(*current), backoff_policy(*current),
      idempotency_policy(*current)->GetDatacenterConnector(request),
      [this](
          grpc::ClientContext& context,
          google::cloud::vmmigration::v1::GetDatacenterConnectorRequest const&
              request) {
        return stub_->GetDatacenterConnector(context, request);
      },
      request, __func__);
}

future<StatusOr<google::cloud::vmmigration::v1::DatacenterConnector>>
VmMigrationConnectionImpl::CreateDatacenterConnector(
    google::cloud::vmmigration::v1::CreateDatacenterConnectorRequest const&
        request) {
  auto current = google::cloud::internal::SaveCurrentOptions();
  return google::cloud::internal::AsyncLongRunningOperation<
      google::cloud::vmmigration::v1::DatacenterConnector>(
      background_->cq(), current, request,
      [stub = stub_](google::cloud::CompletionQueue& cq,
                     std::shared_ptr<grpc::ClientContext> context,
                     Options const& options,
                     google::cloud::vmmigration::v1::
                         CreateDatacenterConnectorRequest const& request) {
        return stub->AsyncCreateDatacenterConnector(cq, std::move(context),
                                                    options, request);
      },
      [stub = stub_](google::cloud::CompletionQueue& cq,
                     std::shared_ptr<grpc::ClientContext> context,
                     Options const& options,
                     google::longrunning::GetOperationRequest const& request) {
        return stub->AsyncGetOperation(cq, std::move(context), options,
                                       request);
      },
      [stub = stub_](
          google::cloud::CompletionQueue& cq,
          std::shared_ptr<grpc::ClientContext> context, Options const& options,
          google::longrunning::CancelOperationRequest const& request) {
        return stub->AsyncCancelOperation(cq, std::move(context), options,
                                          request);
      },
      &google::cloud::internal::ExtractLongRunningResultResponse<
          google::cloud::vmmigration::v1::DatacenterConnector>,
      retry_policy(*current), backoff_policy(*current),
      idempotency_policy(*current)->CreateDatacenterConnector(request),
      polling_policy(*current), __func__);
}

future<StatusOr<google::cloud::vmmigration::v1::OperationMetadata>>
VmMigrationConnectionImpl::DeleteDatacenterConnector(
    google::cloud::vmmigration::v1::DeleteDatacenterConnectorRequest const&
        request) {
  auto current = google::cloud::internal::SaveCurrentOptions();
  return google::cloud::internal::AsyncLongRunningOperation<
      google::cloud::vmmigration::v1::OperationMetadata>(
      background_->cq(), current, request,
      [stub = stub_](google::cloud::CompletionQueue& cq,
                     std::shared_ptr<grpc::ClientContext> context,
                     Options const& options,
                     google::cloud::vmmigration::v1::
                         DeleteDatacenterConnectorRequest const& request) {
        return stub->AsyncDeleteDatacenterConnector(cq, std::move(context),
                                                    options, request);
      },
      [stub = stub_](google::cloud::CompletionQueue& cq,
                     std::shared_ptr<grpc::ClientContext> context,
                     Options const& options,
                     google::longrunning::GetOperationRequest const& request) {
        return stub->AsyncGetOperation(cq, std::move(context), options,
                                       request);
      },
      [stub = stub_](
          google::cloud::CompletionQueue& cq,
          std::shared_ptr<grpc::ClientContext> context, Options const& options,
          google::longrunning::CancelOperationRequest const& request) {
        return stub->AsyncCancelOperation(cq, std::move(context), options,
                                          request);
      },
      &google::cloud::internal::ExtractLongRunningResultMetadata<
          google::cloud::vmmigration::v1::OperationMetadata>,
      retry_policy(*current), backoff_policy(*current),
      idempotency_policy(*current)->DeleteDatacenterConnector(request),
      polling_policy(*current), __func__);
}

future<StatusOr<google::cloud::vmmigration::v1::UpgradeApplianceResponse>>
VmMigrationConnectionImpl::UpgradeAppliance(
    google::cloud::vmmigration::v1::UpgradeApplianceRequest const& request) {
  auto current = google::cloud::internal::SaveCurrentOptions();
  return google::cloud::internal::AsyncLongRunningOperation<
      google::cloud::vmmigration::v1::UpgradeApplianceResponse>(
      background_->cq(), current, request,
      [stub = stub_](
          google::cloud::CompletionQueue& cq,
          std::shared_ptr<grpc::ClientContext> context, Options const& options,
          google::cloud::vmmigration::v1::UpgradeApplianceRequest const&
              request) {
        return stub->AsyncUpgradeAppliance(cq, std::move(context), options,
                                           request);
      },
      [stub = stub_](google::cloud::CompletionQueue& cq,
                     std::shared_ptr<grpc::ClientContext> context,
                     Options const& options,
                     google::longrunning::GetOperationRequest const& request) {
        return stub->AsyncGetOperation(cq, std::move(context), options,
                                       request);
      },
      [stub = stub_](
          google::cloud::CompletionQueue& cq,
          std::shared_ptr<grpc::ClientContext> context, Options const& options,
          google::longrunning::CancelOperationRequest const& request) {
        return stub->AsyncCancelOperation(cq, std::move(context), options,
                                          request);
      },
      &google::cloud::internal::ExtractLongRunningResultResponse<
          google::cloud::vmmigration::v1::UpgradeApplianceResponse>,
      retry_policy(*current), backoff_policy(*current),
      idempotency_policy(*current)->UpgradeAppliance(request),
      polling_policy(*current), __func__);
}

future<StatusOr<google::cloud::vmmigration::v1::MigratingVm>>
VmMigrationConnectionImpl::CreateMigratingVm(
    google::cloud::vmmigration::v1::CreateMigratingVmRequest const& request) {
  auto current = google::cloud::internal::SaveCurrentOptions();
  return google::cloud::internal::AsyncLongRunningOperation<
      google::cloud::vmmigration::v1::MigratingVm>(
      background_->cq(), current, request,
      [stub = stub_](
          google::cloud::CompletionQueue& cq,
          std::shared_ptr<grpc::ClientContext> context, Options const& options,
          google::cloud::vmmigration::v1::CreateMigratingVmRequest const&
              request) {
        return stub->AsyncCreateMigratingVm(cq, std::move(context), options,
                                            request);
      },
      [stub = stub_](google::cloud::CompletionQueue& cq,
                     std::shared_ptr<grpc::ClientContext> context,
                     Options const& options,
                     google::longrunning::GetOperationRequest const& request) {
        return stub->AsyncGetOperation(cq, std::move(context), options,
                                       request);
      },
      [stub = stub_](
          google::cloud::CompletionQueue& cq,
          std::shared_ptr<grpc::ClientContext> context, Options const& options,
          google::longrunning::CancelOperationRequest const& request) {
        return stub->AsyncCancelOperation(cq, std::move(context), options,
                                          request);
      },
      &google::cloud::internal::ExtractLongRunningResultResponse<
          google::cloud::vmmigration::v1::MigratingVm>,
      retry_policy(*current), backoff_policy(*current),
      idempotency_policy(*current)->CreateMigratingVm(request),
      polling_policy(*current), __func__);
}

StreamRange<google::cloud::vmmigration::v1::MigratingVm>
VmMigrationConnectionImpl::ListMigratingVms(
    google::cloud::vmmigration::v1::ListMigratingVmsRequest request) {
  request.clear_page_token();
  auto current = google::cloud::internal::SaveCurrentOptions();
  auto idempotency = idempotency_policy(*current)->ListMigratingVms(request);
  char const* function_name = __func__;
  return google::cloud::internal::MakePaginationRange<
      StreamRange<google::cloud::vmmigration::v1::MigratingVm>>(
      std::move(request),
      [idempotency, function_name, stub = stub_,
       retry = std::shared_ptr<vmmigration_v1::VmMigrationRetryPolicy>(
           retry_policy(*current)),
       backoff = std::shared_ptr<BackoffPolicy>(backoff_policy(*current))](
          google::cloud::vmmigration::v1::ListMigratingVmsRequest const& r) {
        return google::cloud::internal::RetryLoop(
            retry->clone(), backoff->clone(), idempotency,
            [stub](
                grpc::ClientContext& context,
                google::cloud::vmmigration::v1::ListMigratingVmsRequest const&
                    request) {
              return stub->ListMigratingVms(context, request);
            },
            r, function_name);
      },
      [](google::cloud::vmmigration::v1::ListMigratingVmsResponse r) {
        std::vector<google::cloud::vmmigration::v1::MigratingVm> result(
            r.migrating_vms().size());
        auto& messages = *r.mutable_migrating_vms();
        std::move(messages.begin(), messages.end(), result.begin());
        return result;
      });
}

StatusOr<google::cloud::vmmigration::v1::MigratingVm>
VmMigrationConnectionImpl::GetMigratingVm(
    google::cloud::vmmigration::v1::GetMigratingVmRequest const& request) {
  auto current = google::cloud::internal::SaveCurrentOptions();
  return google::cloud::internal::RetryLoop(
      retry_policy(*current), backoff_policy(*current),
      idempotency_policy(*current)->GetMigratingVm(request),
      [this](grpc::ClientContext& context,
             google::cloud::vmmigration::v1::GetMigratingVmRequest const&
                 request) { return stub_->GetMigratingVm(context, request); },
      request, __func__);
}

future<StatusOr<google::cloud::vmmigration::v1::MigratingVm>>
VmMigrationConnectionImpl::UpdateMigratingVm(
    google::cloud::vmmigration::v1::UpdateMigratingVmRequest const& request) {
  auto current = google::cloud::internal::SaveCurrentOptions();
  return google::cloud::internal::AsyncLongRunningOperation<
      google::cloud::vmmigration::v1::MigratingVm>(
      background_->cq(), current, request,
      [stub = stub_](
          google::cloud::CompletionQueue& cq,
          std::shared_ptr<grpc::ClientContext> context, Options const& options,
          google::cloud::vmmigration::v1::UpdateMigratingVmRequest const&
              request) {
        return stub->AsyncUpdateMigratingVm(cq, std::move(context), options,
                                            request);
      },
      [stub = stub_](google::cloud::CompletionQueue& cq,
                     std::shared_ptr<grpc::ClientContext> context,
                     Options const& options,
                     google::longrunning::GetOperationRequest const& request) {
        return stub->AsyncGetOperation(cq, std::move(context), options,
                                       request);
      },
      [stub = stub_](
          google::cloud::CompletionQueue& cq,
          std::shared_ptr<grpc::ClientContext> context, Options const& options,
          google::longrunning::CancelOperationRequest const& request) {
        return stub->AsyncCancelOperation(cq, std::move(context), options,
                                          request);
      },
      &google::cloud::internal::ExtractLongRunningResultResponse<
          google::cloud::vmmigration::v1::MigratingVm>,
      retry_policy(*current), backoff_policy(*current),
      idempotency_policy(*current)->UpdateMigratingVm(request),
      polling_policy(*current), __func__);
}

future<StatusOr<google::cloud::vmmigration::v1::OperationMetadata>>
VmMigrationConnectionImpl::DeleteMigratingVm(
    google::cloud::vmmigration::v1::DeleteMigratingVmRequest const& request) {
  auto current = google::cloud::internal::SaveCurrentOptions();
  return google::cloud::internal::AsyncLongRunningOperation<
      google::cloud::vmmigration::v1::OperationMetadata>(
      background_->cq(), current, request,
      [stub = stub_](
          google::cloud::CompletionQueue& cq,
          std::shared_ptr<grpc::ClientContext> context, Options const& options,
          google::cloud::vmmigration::v1::DeleteMigratingVmRequest const&
              request) {
        return stub->AsyncDeleteMigratingVm(cq, std::move(context), options,
                                            request);
      },
      [stub = stub_](google::cloud::CompletionQueue& cq,
                     std::shared_ptr<grpc::ClientContext> context,
                     Options const& options,
                     google::longrunning::GetOperationRequest const& request) {
        return stub->AsyncGetOperation(cq, std::move(context), options,
                                       request);
      },
      [stub = stub_](
          google::cloud::CompletionQueue& cq,
          std::shared_ptr<grpc::ClientContext> context, Options const& options,
          google::longrunning::CancelOperationRequest const& request) {
        return stub->AsyncCancelOperation(cq, std::move(context), options,
                                          request);
      },
      &google::cloud::internal::ExtractLongRunningResultMetadata<
          google::cloud::vmmigration::v1::OperationMetadata>,
      retry_policy(*current), backoff_policy(*current),
      idempotency_policy(*current)->DeleteMigratingVm(request),
      polling_policy(*current), __func__);
}

future<StatusOr<google::cloud::vmmigration::v1::StartMigrationResponse>>
VmMigrationConnectionImpl::StartMigration(
    google::cloud::vmmigration::v1::StartMigrationRequest const& request) {
  auto current = google::cloud::internal::SaveCurrentOptions();
  return google::cloud::internal::AsyncLongRunningOperation<
      google::cloud::vmmigration::v1::StartMigrationResponse>(
      background_->cq(), current, request,
      [stub = stub_](
          google::cloud::CompletionQueue& cq,
          std::shared_ptr<grpc::ClientContext> context, Options const& options,
          google::cloud::vmmigration::v1::StartMigrationRequest const&
              request) {
        return stub->AsyncStartMigration(cq, std::move(context), options,
                                         request);
      },
      [stub = stub_](google::cloud::CompletionQueue& cq,
                     std::shared_ptr<grpc::ClientContext> context,
                     Options const& options,
                     google::longrunning::GetOperationRequest const& request) {
        return stub->AsyncGetOperation(cq, std::move(context), options,
                                       request);
      },
      [stub = stub_](
          google::cloud::CompletionQueue& cq,
          std::shared_ptr<grpc::ClientContext> context, Options const& options,
          google::longrunning::CancelOperationRequest const& request) {
        return stub->AsyncCancelOperation(cq, std::move(context), options,
                                          request);
      },
      &google::cloud::internal::ExtractLongRunningResultResponse<
          google::cloud::vmmigration::v1::StartMigrationResponse>,
      retry_policy(*current), backoff_policy(*current),
      idempotency_policy(*current)->StartMigration(request),
      polling_policy(*current), __func__);
}

future<StatusOr<google::cloud::vmmigration::v1::ResumeMigrationResponse>>
VmMigrationConnectionImpl::ResumeMigration(
    google::cloud::vmmigration::v1::ResumeMigrationRequest const& request) {
  auto current = google::cloud::internal::SaveCurrentOptions();
  return google::cloud::internal::AsyncLongRunningOperation<
      google::cloud::vmmigration::v1::ResumeMigrationResponse>(
      background_->cq(), current, request,
      [stub = stub_](
          google::cloud::CompletionQueue& cq,
          std::shared_ptr<grpc::ClientContext> context, Options const& options,
          google::cloud::vmmigration::v1::ResumeMigrationRequest const&
              request) {
        return stub->AsyncResumeMigration(cq, std::move(context), options,
                                          request);
      },
      [stub = stub_](google::cloud::CompletionQueue& cq,
                     std::shared_ptr<grpc::ClientContext> context,
                     Options const& options,
                     google::longrunning::GetOperationRequest const& request) {
        return stub->AsyncGetOperation(cq, std::move(context), options,
                                       request);
      },
      [stub = stub_](
          google::cloud::CompletionQueue& cq,
          std::shared_ptr<grpc::ClientContext> context, Options const& options,
          google::longrunning::CancelOperationRequest const& request) {
        return stub->AsyncCancelOperation(cq, std::move(context), options,
                                          request);
      },
      &google::cloud::internal::ExtractLongRunningResultResponse<
          google::cloud::vmmigration::v1::ResumeMigrationResponse>,
      retry_policy(*current), backoff_policy(*current),
      idempotency_policy(*current)->ResumeMigration(request),
      polling_policy(*current), __func__);
}

future<StatusOr<google::cloud::vmmigration::v1::PauseMigrationResponse>>
VmMigrationConnectionImpl::PauseMigration(
    google::cloud::vmmigration::v1::PauseMigrationRequest const& request) {
  auto current = google::cloud::internal::SaveCurrentOptions();
  return google::cloud::internal::AsyncLongRunningOperation<
      google::cloud::vmmigration::v1::PauseMigrationResponse>(
      background_->cq(), current, request,
      [stub = stub_](
          google::cloud::CompletionQueue& cq,
          std::shared_ptr<grpc::ClientContext> context, Options const& options,
          google::cloud::vmmigration::v1::PauseMigrationRequest const&
              request) {
        return stub->AsyncPauseMigration(cq, std::move(context), options,
                                         request);
      },
      [stub = stub_](google::cloud::CompletionQueue& cq,
                     std::shared_ptr<grpc::ClientContext> context,
                     Options const& options,
                     google::longrunning::GetOperationRequest const& request) {
        return stub->AsyncGetOperation(cq, std::move(context), options,
                                       request);
      },
      [stub = stub_](
          google::cloud::CompletionQueue& cq,
          std::shared_ptr<grpc::ClientContext> context, Options const& options,
          google::longrunning::CancelOperationRequest const& request) {
        return stub->AsyncCancelOperation(cq, std::move(context), options,
                                          request);
      },
      &google::cloud::internal::ExtractLongRunningResultResponse<
          google::cloud::vmmigration::v1::PauseMigrationResponse>,
      retry_policy(*current), backoff_policy(*current),
      idempotency_policy(*current)->PauseMigration(request),
      polling_policy(*current), __func__);
}

future<StatusOr<google::cloud::vmmigration::v1::FinalizeMigrationResponse>>
VmMigrationConnectionImpl::FinalizeMigration(
    google::cloud::vmmigration::v1::FinalizeMigrationRequest const& request) {
  auto current = google::cloud::internal::SaveCurrentOptions();
  return google::cloud::internal::AsyncLongRunningOperation<
      google::cloud::vmmigration::v1::FinalizeMigrationResponse>(
      background_->cq(), current, request,
      [stub = stub_](
          google::cloud::CompletionQueue& cq,
          std::shared_ptr<grpc::ClientContext> context, Options const& options,
          google::cloud::vmmigration::v1::FinalizeMigrationRequest const&
              request) {
        return stub->AsyncFinalizeMigration(cq, std::move(context), options,
                                            request);
      },
      [stub = stub_](google::cloud::CompletionQueue& cq,
                     std::shared_ptr<grpc::ClientContext> context,
                     Options const& options,
                     google::longrunning::GetOperationRequest const& request) {
        return stub->AsyncGetOperation(cq, std::move(context), options,
                                       request);
      },
      [stub = stub_](
          google::cloud::CompletionQueue& cq,
          std::shared_ptr<grpc::ClientContext> context, Options const& options,
          google::longrunning::CancelOperationRequest const& request) {
        return stub->AsyncCancelOperation(cq, std::move(context), options,
                                          request);
      },
      &google::cloud::internal::ExtractLongRunningResultResponse<
          google::cloud::vmmigration::v1::FinalizeMigrationResponse>,
      retry_policy(*current), backoff_policy(*current),
      idempotency_policy(*current)->FinalizeMigration(request),
      polling_policy(*current), __func__);
}

future<StatusOr<google::cloud::vmmigration::v1::CloneJob>>
VmMigrationConnectionImpl::CreateCloneJob(
    google::cloud::vmmigration::v1::CreateCloneJobRequest const& request) {
  auto current = google::cloud::internal::SaveCurrentOptions();
  return google::cloud::internal::AsyncLongRunningOperation<
      google::cloud::vmmigration::v1::CloneJob>(
      background_->cq(), current, request,
      [stub = stub_](
          google::cloud::CompletionQueue& cq,
          std::shared_ptr<grpc::ClientContext> context, Options const& options,
          google::cloud::vmmigration::v1::CreateCloneJobRequest const&
              request) {
        return stub->AsyncCreateCloneJob(cq, std::move(context), options,
                                         request);
      },
      [stub = stub_](google::cloud::CompletionQueue& cq,
                     std::shared_ptr<grpc::ClientContext> context,
                     Options const& options,
                     google::longrunning::GetOperationRequest const& request) {
        return stub->AsyncGetOperation(cq, std::move(context), options,
                                       request);
      },
      [stub = stub_](
          google::cloud::CompletionQueue& cq,
          std::shared_ptr<grpc::ClientContext> context, Options const& options,
          google::longrunning::CancelOperationRequest const& request) {
        return stub->AsyncCancelOperation(cq, std::move(context), options,
                                          request);
      },
      &google::cloud::internal::ExtractLongRunningResultResponse<
          google::cloud::vmmigration::v1::CloneJob>,
      retry_policy(*current), backoff_policy(*current),
      idempotency_policy(*current)->CreateCloneJob(request),
      polling_policy(*current), __func__);
}

future<StatusOr<google::cloud::vmmigration::v1::CancelCloneJobResponse>>
VmMigrationConnectionImpl::CancelCloneJob(
    google::cloud::vmmigration::v1::CancelCloneJobRequest const& request) {
  auto current = google::cloud::internal::SaveCurrentOptions();
  return google::cloud::internal::AsyncLongRunningOperation<
      google::cloud::vmmigration::v1::CancelCloneJobResponse>(
      background_->cq(), current, request,
      [stub = stub_](
          google::cloud::CompletionQueue& cq,
          std::shared_ptr<grpc::ClientContext> context, Options const& options,
          google::cloud::vmmigration::v1::CancelCloneJobRequest const&
              request) {
        return stub->AsyncCancelCloneJob(cq, std::move(context), options,
                                         request);
      },
      [stub = stub_](google::cloud::CompletionQueue& cq,
                     std::shared_ptr<grpc::ClientContext> context,
                     Options const& options,
                     google::longrunning::GetOperationRequest const& request) {
        return stub->AsyncGetOperation(cq, std::move(context), options,
                                       request);
      },
      [stub = stub_](
          google::cloud::CompletionQueue& cq,
          std::shared_ptr<grpc::ClientContext> context, Options const& options,
          google::longrunning::CancelOperationRequest const& request) {
        return stub->AsyncCancelOperation(cq, std::move(context), options,
                                          request);
      },
      &google::cloud::internal::ExtractLongRunningResultResponse<
          google::cloud::vmmigration::v1::CancelCloneJobResponse>,
      retry_policy(*current), backoff_policy(*current),
      idempotency_policy(*current)->CancelCloneJob(request),
      polling_policy(*current), __func__);
}

StreamRange<google::cloud::vmmigration::v1::CloneJob>
VmMigrationConnectionImpl::ListCloneJobs(
    google::cloud::vmmigration::v1::ListCloneJobsRequest request) {
  request.clear_page_token();
  auto current = google::cloud::internal::SaveCurrentOptions();
  auto idempotency = idempotency_policy(*current)->ListCloneJobs(request);
  char const* function_name = __func__;
  return google::cloud::internal::MakePaginationRange<
      StreamRange<google::cloud::vmmigration::v1::CloneJob>>(
      std::move(request),
      [idempotency, function_name, stub = stub_,
       retry = std::shared_ptr<vmmigration_v1::VmMigrationRetryPolicy>(
           retry_policy(*current)),
       backoff = std::shared_ptr<BackoffPolicy>(backoff_policy(*current))](
          google::cloud::vmmigration::v1::ListCloneJobsRequest const& r) {
        return google::cloud::internal::RetryLoop(
            retry->clone(), backoff->clone(), idempotency,
            [stub](grpc::ClientContext& context,
                   google::cloud::vmmigration::v1::ListCloneJobsRequest const&
                       request) {
              return stub->ListCloneJobs(context, request);
            },
            r, function_name);
      },
      [](google::cloud::vmmigration::v1::ListCloneJobsResponse r) {
        std::vector<google::cloud::vmmigration::v1::CloneJob> result(
            r.clone_jobs().size());
        auto& messages = *r.mutable_clone_jobs();
        std::move(messages.begin(), messages.end(), result.begin());
        return result;
      });
}

StatusOr<google::cloud::vmmigration::v1::CloneJob>
VmMigrationConnectionImpl::GetCloneJob(
    google::cloud::vmmigration::v1::GetCloneJobRequest const& request) {
  auto current = google::cloud::internal::SaveCurrentOptions();
  return google::cloud::internal::RetryLoop(
      retry_policy(*current), backoff_policy(*current),
      idempotency_policy(*current)->GetCloneJob(request),
      [this](
          grpc::ClientContext& context,
          google::cloud::vmmigration::v1::GetCloneJobRequest const& request) {
        return stub_->GetCloneJob(context, request);
      },
      request, __func__);
}

future<StatusOr<google::cloud::vmmigration::v1::CutoverJob>>
VmMigrationConnectionImpl::CreateCutoverJob(
    google::cloud::vmmigration::v1::CreateCutoverJobRequest const& request) {
  auto current = google::cloud::internal::SaveCurrentOptions();
  return google::cloud::internal::AsyncLongRunningOperation<
      google::cloud::vmmigration::v1::CutoverJob>(
      background_->cq(), current, request,
      [stub = stub_](
          google::cloud::CompletionQueue& cq,
          std::shared_ptr<grpc::ClientContext> context, Options const& options,
          google::cloud::vmmigration::v1::CreateCutoverJobRequest const&
              request) {
        return stub->AsyncCreateCutoverJob(cq, std::move(context), options,
                                           request);
      },
      [stub = stub_](google::cloud::CompletionQueue& cq,
                     std::shared_ptr<grpc::ClientContext> context,
                     Options const& options,
                     google::longrunning::GetOperationRequest const& request) {
        return stub->AsyncGetOperation(cq, std::move(context), options,
                                       request);
      },
      [stub = stub_](
          google::cloud::CompletionQueue& cq,
          std::shared_ptr<grpc::ClientContext> context, Options const& options,
          google::longrunning::CancelOperationRequest const& request) {
        return stub->AsyncCancelOperation(cq, std::move(context), options,
                                          request);
      },
      &google::cloud::internal::ExtractLongRunningResultResponse<
          google::cloud::vmmigration::v1::CutoverJob>,
      retry_policy(*current), backoff_policy(*current),
      idempotency_policy(*current)->CreateCutoverJob(request),
      polling_policy(*current), __func__);
}

future<StatusOr<google::cloud::vmmigration::v1::CancelCutoverJobResponse>>
VmMigrationConnectionImpl::CancelCutoverJob(
    google::cloud::vmmigration::v1::CancelCutoverJobRequest const& request) {
  auto current = google::cloud::internal::SaveCurrentOptions();
  return google::cloud::internal::AsyncLongRunningOperation<
      google::cloud::vmmigration::v1::CancelCutoverJobResponse>(
      background_->cq(), current, request,
      [stub = stub_](
          google::cloud::CompletionQueue& cq,
          std::shared_ptr<grpc::ClientContext> context, Options const& options,
          google::cloud::vmmigration::v1::CancelCutoverJobRequest const&
              request) {
        return stub->AsyncCancelCutoverJob(cq, std::move(context), options,
                                           request);
      },
      [stub = stub_](google::cloud::CompletionQueue& cq,
                     std::shared_ptr<grpc::ClientContext> context,
                     Options const& options,
                     google::longrunning::GetOperationRequest const& request) {
        return stub->AsyncGetOperation(cq, std::move(context), options,
                                       request);
      },
      [stub = stub_](
          google::cloud::CompletionQueue& cq,
          std::shared_ptr<grpc::ClientContext> context, Options const& options,
          google::longrunning::CancelOperationRequest const& request) {
        return stub->AsyncCancelOperation(cq, std::move(context), options,
                                          request);
      },
      &google::cloud::internal::ExtractLongRunningResultResponse<
          google::cloud::vmmigration::v1::CancelCutoverJobResponse>,
      retry_policy(*current), backoff_policy(*current),
      idempotency_policy(*current)->CancelCutoverJob(request),
      polling_policy(*current), __func__);
}

StreamRange<google::cloud::vmmigration::v1::CutoverJob>
VmMigrationConnectionImpl::ListCutoverJobs(
    google::cloud::vmmigration::v1::ListCutoverJobsRequest request) {
  request.clear_page_token();
  auto current = google::cloud::internal::SaveCurrentOptions();
  auto idempotency = idempotency_policy(*current)->ListCutoverJobs(request);
  char const* function_name = __func__;
  return google::cloud::internal::MakePaginationRange<
      StreamRange<google::cloud::vmmigration::v1::CutoverJob>>(
      std::move(request),
      [idempotency, function_name, stub = stub_,
       retry = std::shared_ptr<vmmigration_v1::VmMigrationRetryPolicy>(
           retry_policy(*current)),
       backoff = std::shared_ptr<BackoffPolicy>(backoff_policy(*current))](
          google::cloud::vmmigration::v1::ListCutoverJobsRequest const& r) {
        return google::cloud::internal::RetryLoop(
            retry->clone(), backoff->clone(), idempotency,
            [stub](grpc::ClientContext& context,
                   google::cloud::vmmigration::v1::ListCutoverJobsRequest const&
                       request) {
              return stub->ListCutoverJobs(context, request);
            },
            r, function_name);
      },
      [](google::cloud::vmmigration::v1::ListCutoverJobsResponse r) {
        std::vector<google::cloud::vmmigration::v1::CutoverJob> result(
            r.cutover_jobs().size());
        auto& messages = *r.mutable_cutover_jobs();
        std::move(messages.begin(), messages.end(), result.begin());
        return result;
      });
}

StatusOr<google::cloud::vmmigration::v1::CutoverJob>
VmMigrationConnectionImpl::GetCutoverJob(
    google::cloud::vmmigration::v1::GetCutoverJobRequest const& request) {
  auto current = google::cloud::internal::SaveCurrentOptions();
  return google::cloud::internal::RetryLoop(
      retry_policy(*current), backoff_policy(*current),
      idempotency_policy(*current)->GetCutoverJob(request),
      [this](
          grpc::ClientContext& context,
          google::cloud::vmmigration::v1::GetCutoverJobRequest const& request) {
        return stub_->GetCutoverJob(context, request);
      },
      request, __func__);
}

StreamRange<google::cloud::vmmigration::v1::Group>
VmMigrationConnectionImpl::ListGroups(
    google::cloud::vmmigration::v1::ListGroupsRequest request) {
  request.clear_page_token();
  auto current = google::cloud::internal::SaveCurrentOptions();
  auto idempotency = idempotency_policy(*current)->ListGroups(request);
  char const* function_name = __func__;
  return google::cloud::internal::MakePaginationRange<
      StreamRange<google::cloud::vmmigration::v1::Group>>(
      std::move(request),
      [idempotency, function_name, stub = stub_,
       retry = std::shared_ptr<vmmigration_v1::VmMigrationRetryPolicy>(
           retry_policy(*current)),
       backoff = std::shared_ptr<BackoffPolicy>(backoff_policy(*current))](
          google::cloud::vmmigration::v1::ListGroupsRequest const& r) {
        return google::cloud::internal::RetryLoop(
            retry->clone(), backoff->clone(), idempotency,
            [stub](grpc::ClientContext& context,
                   google::cloud::vmmigration::v1::ListGroupsRequest const&
                       request) { return stub->ListGroups(context, request); },
            r, function_name);
      },
      [](google::cloud::vmmigration::v1::ListGroupsResponse r) {
        std::vector<google::cloud::vmmigration::v1::Group> result(
            r.groups().size());
        auto& messages = *r.mutable_groups();
        std::move(messages.begin(), messages.end(), result.begin());
        return result;
      });
}

StatusOr<google::cloud::vmmigration::v1::Group>
VmMigrationConnectionImpl::GetGroup(
    google::cloud::vmmigration::v1::GetGroupRequest const& request) {
  auto current = google::cloud::internal::SaveCurrentOptions();
  return google::cloud::internal::RetryLoop(
      retry_policy(*current), backoff_policy(*current),
      idempotency_policy(*current)->GetGroup(request),
      [this](grpc::ClientContext& context,
             google::cloud::vmmigration::v1::GetGroupRequest const& request) {
        return stub_->GetGroup(context, request);
      },
      request, __func__);
}

future<StatusOr<google::cloud::vmmigration::v1::Group>>
VmMigrationConnectionImpl::CreateGroup(
    google::cloud::vmmigration::v1::CreateGroupRequest const& request) {
  auto current = google::cloud::internal::SaveCurrentOptions();
  return google::cloud::internal::AsyncLongRunningOperation<
      google::cloud::vmmigration::v1::Group>(
      background_->cq(), current, request,
      [stub = stub_](
          google::cloud::CompletionQueue& cq,
          std::shared_ptr<grpc::ClientContext> context, Options const& options,
          google::cloud::vmmigration::v1::CreateGroupRequest const& request) {
        return stub->AsyncCreateGroup(cq, std::move(context), options, request);
      },
      [stub = stub_](google::cloud::CompletionQueue& cq,
                     std::shared_ptr<grpc::ClientContext> context,
                     Options const& options,
                     google::longrunning::GetOperationRequest const& request) {
        return stub->AsyncGetOperation(cq, std::move(context), options,
                                       request);
      },
      [stub = stub_](
          google::cloud::CompletionQueue& cq,
          std::shared_ptr<grpc::ClientContext> context, Options const& options,
          google::longrunning::CancelOperationRequest const& request) {
        return stub->AsyncCancelOperation(cq, std::move(context), options,
                                          request);
      },
      &google::cloud::internal::ExtractLongRunningResultResponse<
          google::cloud::vmmigration::v1::Group>,
      retry_policy(*current), backoff_policy(*current),
      idempotency_policy(*current)->CreateGroup(request),
      polling_policy(*current), __func__);
}

future<StatusOr<google::cloud::vmmigration::v1::Group>>
VmMigrationConnectionImpl::UpdateGroup(
    google::cloud::vmmigration::v1::UpdateGroupRequest const& request) {
  auto current = google::cloud::internal::SaveCurrentOptions();
  return google::cloud::internal::AsyncLongRunningOperation<
      google::cloud::vmmigration::v1::Group>(
      background_->cq(), current, request,
      [stub = stub_](
          google::cloud::CompletionQueue& cq,
          std::shared_ptr<grpc::ClientContext> context, Options const& options,
          google::cloud::vmmigration::v1::UpdateGroupRequest const& request) {
        return stub->AsyncUpdateGroup(cq, std::move(context), options, request);
      },
      [stub = stub_](google::cloud::CompletionQueue& cq,
                     std::shared_ptr<grpc::ClientContext> context,
                     Options const& options,
                     google::longrunning::GetOperationRequest const& request) {
        return stub->AsyncGetOperation(cq, std::move(context), options,
                                       request);
      },
      [stub = stub_](
          google::cloud::CompletionQueue& cq,
          std::shared_ptr<grpc::ClientContext> context, Options const& options,
          google::longrunning::CancelOperationRequest const& request) {
        return stub->AsyncCancelOperation(cq, std::move(context), options,
                                          request);
      },
      &google::cloud::internal::ExtractLongRunningResultResponse<
          google::cloud::vmmigration::v1::Group>,
      retry_policy(*current), backoff_policy(*current),
      idempotency_policy(*current)->UpdateGroup(request),
      polling_policy(*current), __func__);
}

future<StatusOr<google::cloud::vmmigration::v1::OperationMetadata>>
VmMigrationConnectionImpl::DeleteGroup(
    google::cloud::vmmigration::v1::DeleteGroupRequest const& request) {
  auto current = google::cloud::internal::SaveCurrentOptions();
  return google::cloud::internal::AsyncLongRunningOperation<
      google::cloud::vmmigration::v1::OperationMetadata>(
      background_->cq(), current, request,
      [stub = stub_](
          google::cloud::CompletionQueue& cq,
          std::shared_ptr<grpc::ClientContext> context, Options const& options,
          google::cloud::vmmigration::v1::DeleteGroupRequest const& request) {
        return stub->AsyncDeleteGroup(cq, std::move(context), options, request);
      },
      [stub = stub_](google::cloud::CompletionQueue& cq,
                     std::shared_ptr<grpc::ClientContext> context,
                     Options const& options,
                     google::longrunning::GetOperationRequest const& request) {
        return stub->AsyncGetOperation(cq, std::move(context), options,
                                       request);
      },
      [stub = stub_](
          google::cloud::CompletionQueue& cq,
          std::shared_ptr<grpc::ClientContext> context, Options const& options,
          google::longrunning::CancelOperationRequest const& request) {
        return stub->AsyncCancelOperation(cq, std::move(context), options,
                                          request);
      },
      &google::cloud::internal::ExtractLongRunningResultMetadata<
          google::cloud::vmmigration::v1::OperationMetadata>,
      retry_policy(*current), backoff_policy(*current),
      idempotency_policy(*current)->DeleteGroup(request),
      polling_policy(*current), __func__);
}

future<StatusOr<google::cloud::vmmigration::v1::AddGroupMigrationResponse>>
VmMigrationConnectionImpl::AddGroupMigration(
    google::cloud::vmmigration::v1::AddGroupMigrationRequest const& request) {
  auto current = google::cloud::internal::SaveCurrentOptions();
  return google::cloud::internal::AsyncLongRunningOperation<
      google::cloud::vmmigration::v1::AddGroupMigrationResponse>(
      background_->cq(), current, request,
      [stub = stub_](
          google::cloud::CompletionQueue& cq,
          std::shared_ptr<grpc::ClientContext> context, Options const& options,
          google::cloud::vmmigration::v1::AddGroupMigrationRequest const&
              request) {
        return stub->AsyncAddGroupMigration(cq, std::move(context), options,
                                            request);
      },
      [stub = stub_](google::cloud::CompletionQueue& cq,
                     std::shared_ptr<grpc::ClientContext> context,
                     Options const& options,
                     google::longrunning::GetOperationRequest const& request) {
        return stub->AsyncGetOperation(cq, std::move(context), options,
                                       request);
      },
      [stub = stub_](
          google::cloud::CompletionQueue& cq,
          std::shared_ptr<grpc::ClientContext> context, Options const& options,
          google::longrunning::CancelOperationRequest const& request) {
        return stub->AsyncCancelOperation(cq, std::move(context), options,
                                          request);
      },
      &google::cloud::internal::ExtractLongRunningResultResponse<
          google::cloud::vmmigration::v1::AddGroupMigrationResponse>,
      retry_policy(*current), backoff_policy(*current),
      idempotency_policy(*current)->AddGroupMigration(request),
      polling_policy(*current), __func__);
}

future<StatusOr<google::cloud::vmmigration::v1::RemoveGroupMigrationResponse>>
VmMigrationConnectionImpl::RemoveGroupMigration(
    google::cloud::vmmigration::v1::RemoveGroupMigrationRequest const&
        request) {
  auto current = google::cloud::internal::SaveCurrentOptions();
  return google::cloud::internal::AsyncLongRunningOperation<
      google::cloud::vmmigration::v1::RemoveGroupMigrationResponse>(
      background_->cq(), current, request,
      [stub = stub_](
          google::cloud::CompletionQueue& cq,
          std::shared_ptr<grpc::ClientContext> context, Options const& options,
          google::cloud::vmmigration::v1::RemoveGroupMigrationRequest const&
              request) {
        return stub->AsyncRemoveGroupMigration(cq, std::move(context), options,
                                               request);
      },
      [stub = stub_](google::cloud::CompletionQueue& cq,
                     std::shared_ptr<grpc::ClientContext> context,
                     Options const& options,
                     google::longrunning::GetOperationRequest const& request) {
        return stub->AsyncGetOperation(cq, std::move(context), options,
                                       request);
      },
      [stub = stub_](
          google::cloud::CompletionQueue& cq,
          std::shared_ptr<grpc::ClientContext> context, Options const& options,
          google::longrunning::CancelOperationRequest const& request) {
        return stub->AsyncCancelOperation(cq, std::move(context), options,
                                          request);
      },
      &google::cloud::internal::ExtractLongRunningResultResponse<
          google::cloud::vmmigration::v1::RemoveGroupMigrationResponse>,
      retry_policy(*current), backoff_policy(*current),
      idempotency_policy(*current)->RemoveGroupMigration(request),
      polling_policy(*current), __func__);
}

StreamRange<google::cloud::vmmigration::v1::TargetProject>
VmMigrationConnectionImpl::ListTargetProjects(
    google::cloud::vmmigration::v1::ListTargetProjectsRequest request) {
  request.clear_page_token();
  auto current = google::cloud::internal::SaveCurrentOptions();
  auto idempotency = idempotency_policy(*current)->ListTargetProjects(request);
  char const* function_name = __func__;
  return google::cloud::internal::MakePaginationRange<
      StreamRange<google::cloud::vmmigration::v1::TargetProject>>(
      std::move(request),
      [idempotency, function_name, stub = stub_,
       retry = std::shared_ptr<vmmigration_v1::VmMigrationRetryPolicy>(
           retry_policy(*current)),
       backoff = std::shared_ptr<BackoffPolicy>(backoff_policy(*current))](
          google::cloud::vmmigration::v1::ListTargetProjectsRequest const& r) {
        return google::cloud::internal::RetryLoop(
            retry->clone(), backoff->clone(), idempotency,
            [stub](
                grpc::ClientContext& context,
                google::cloud::vmmigration::v1::ListTargetProjectsRequest const&
                    request) {
              return stub->ListTargetProjects(context, request);
            },
            r, function_name);
      },
      [](google::cloud::vmmigration::v1::ListTargetProjectsResponse r) {
        std::vector<google::cloud::vmmigration::v1::TargetProject> result(
            r.target_projects().size());
        auto& messages = *r.mutable_target_projects();
        std::move(messages.begin(), messages.end(), result.begin());
        return result;
      });
}

StatusOr<google::cloud::vmmigration::v1::TargetProject>
VmMigrationConnectionImpl::GetTargetProject(
    google::cloud::vmmigration::v1::GetTargetProjectRequest const& request) {
  auto current = google::cloud::internal::SaveCurrentOptions();
  return google::cloud::internal::RetryLoop(
      retry_policy(*current), backoff_policy(*current),
      idempotency_policy(*current)->GetTargetProject(request),
      [this](grpc::ClientContext& context,
             google::cloud::vmmigration::v1::GetTargetProjectRequest const&
                 request) { return stub_->GetTargetProject(context, request); },
      request, __func__);
}

future<StatusOr<google::cloud::vmmigration::v1::TargetProject>>
VmMigrationConnectionImpl::CreateTargetProject(
    google::cloud::vmmigration::v1::CreateTargetProjectRequest const& request) {
  auto current = google::cloud::internal::SaveCurrentOptions();
  return google::cloud::internal::AsyncLongRunningOperation<
      google::cloud::vmmigration::v1::TargetProject>(
      background_->cq(), current, request,
      [stub = stub_](
          google::cloud::CompletionQueue& cq,
          std::shared_ptr<grpc::ClientContext> context, Options const& options,
          google::cloud::vmmigration::v1::CreateTargetProjectRequest const&
              request) {
        return stub->AsyncCreateTargetProject(cq, std::move(context), options,
                                              request);
      },
      [stub = stub_](google::cloud::CompletionQueue& cq,
                     std::shared_ptr<grpc::ClientContext> context,
                     Options const& options,
                     google::longrunning::GetOperationRequest const& request) {
        return stub->AsyncGetOperation(cq, std::move(context), options,
                                       request);
      },
      [stub = stub_](
          google::cloud::CompletionQueue& cq,
          std::shared_ptr<grpc::ClientContext> context, Options const& options,
          google::longrunning::CancelOperationRequest const& request) {
        return stub->AsyncCancelOperation(cq, std::move(context), options,
                                          request);
      },
      &google::cloud::internal::ExtractLongRunningResultResponse<
          google::cloud::vmmigration::v1::TargetProject>,
      retry_policy(*current), backoff_policy(*current),
      idempotency_policy(*current)->CreateTargetProject(request),
      polling_policy(*current), __func__);
}

future<StatusOr<google::cloud::vmmigration::v1::TargetProject>>
VmMigrationConnectionImpl::UpdateTargetProject(
    google::cloud::vmmigration::v1::UpdateTargetProjectRequest const& request) {
  auto current = google::cloud::internal::SaveCurrentOptions();
  return google::cloud::internal::AsyncLongRunningOperation<
      google::cloud::vmmigration::v1::TargetProject>(
      background_->cq(), current, request,
      [stub = stub_](
          google::cloud::CompletionQueue& cq,
          std::shared_ptr<grpc::ClientContext> context, Options const& options,
          google::cloud::vmmigration::v1::UpdateTargetProjectRequest const&
              request) {
        return stub->AsyncUpdateTargetProject(cq, std::move(context), options,
                                              request);
      },
      [stub = stub_](google::cloud::CompletionQueue& cq,
                     std::shared_ptr<grpc::ClientContext> context,
                     Options const& options,
                     google::longrunning::GetOperationRequest const& request) {
        return stub->AsyncGetOperation(cq, std::move(context), options,
                                       request);
      },
      [stub = stub_](
          google::cloud::CompletionQueue& cq,
          std::shared_ptr<grpc::ClientContext> context, Options const& options,
          google::longrunning::CancelOperationRequest const& request) {
        return stub->AsyncCancelOperation(cq, std::move(context), options,
                                          request);
      },
      &google::cloud::internal::ExtractLongRunningResultResponse<
          google::cloud::vmmigration::v1::TargetProject>,
      retry_policy(*current), backoff_policy(*current),
      idempotency_policy(*current)->UpdateTargetProject(request),
      polling_policy(*current), __func__);
}

future<StatusOr<google::cloud::vmmigration::v1::OperationMetadata>>
VmMigrationConnectionImpl::DeleteTargetProject(
    google::cloud::vmmigration::v1::DeleteTargetProjectRequest const& request) {
  auto current = google::cloud::internal::SaveCurrentOptions();
  return google::cloud::internal::AsyncLongRunningOperation<
      google::cloud::vmmigration::v1::OperationMetadata>(
      background_->cq(), current, request,
      [stub = stub_](
          google::cloud::CompletionQueue& cq,
          std::shared_ptr<grpc::ClientContext> context, Options const& options,
          google::cloud::vmmigration::v1::DeleteTargetProjectRequest const&
              request) {
        return stub->AsyncDeleteTargetProject(cq, std::move(context), options,
                                              request);
      },
      [stub = stub_](google::cloud::CompletionQueue& cq,
                     std::shared_ptr<grpc::ClientContext> context,
                     Options const& options,
                     google::longrunning::GetOperationRequest const& request) {
        return stub->AsyncGetOperation(cq, std::move(context), options,
                                       request);
      },
      [stub = stub_](
          google::cloud::CompletionQueue& cq,
          std::shared_ptr<grpc::ClientContext> context, Options const& options,
          google::longrunning::CancelOperationRequest const& request) {
        return stub->AsyncCancelOperation(cq, std::move(context), options,
                                          request);
      },
      &google::cloud::internal::ExtractLongRunningResultMetadata<
          google::cloud::vmmigration::v1::OperationMetadata>,
      retry_policy(*current), backoff_policy(*current),
      idempotency_policy(*current)->DeleteTargetProject(request),
      polling_policy(*current), __func__);
}

StreamRange<google::cloud::vmmigration::v1::ReplicationCycle>
VmMigrationConnectionImpl::ListReplicationCycles(
    google::cloud::vmmigration::v1::ListReplicationCyclesRequest request) {
  request.clear_page_token();
  auto current = google::cloud::internal::SaveCurrentOptions();
  auto idempotency =
      idempotency_policy(*current)->ListReplicationCycles(request);
  char const* function_name = __func__;
  return google::cloud::internal::MakePaginationRange<
      StreamRange<google::cloud::vmmigration::v1::ReplicationCycle>>(
      std::move(request),
      [idempotency, function_name, stub = stub_,
       retry = std::shared_ptr<vmmigration_v1::VmMigrationRetryPolicy>(
           retry_policy(*current)),
       backoff = std::shared_ptr<BackoffPolicy>(backoff_policy(*current))](
          google::cloud::vmmigration::v1::ListReplicationCyclesRequest const&
              r) {
        return google::cloud::internal::RetryLoop(
            retry->clone(), backoff->clone(), idempotency,
            [stub](grpc::ClientContext& context,
                   google::cloud::vmmigration::v1::
                       ListReplicationCyclesRequest const& request) {
              return stub->ListReplicationCycles(context, request);
            },
            r, function_name);
      },
      [](google::cloud::vmmigration::v1::ListReplicationCyclesResponse r) {
        std::vector<google::cloud::vmmigration::v1::ReplicationCycle> result(
            r.replication_cycles().size());
        auto& messages = *r.mutable_replication_cycles();
        std::move(messages.begin(), messages.end(), result.begin());
        return result;
      });
}

StatusOr<google::cloud::vmmigration::v1::ReplicationCycle>
VmMigrationConnectionImpl::GetReplicationCycle(
    google::cloud::vmmigration::v1::GetReplicationCycleRequest const& request) {
  auto current = google::cloud::internal::SaveCurrentOptions();
  return google::cloud::internal::RetryLoop(
      retry_policy(*current), backoff_policy(*current),
      idempotency_policy(*current)->GetReplicationCycle(request),
      [this](grpc::ClientContext& context,
             google::cloud::vmmigration::v1::GetReplicationCycleRequest const&
                 request) {
        return stub_->GetReplicationCycle(context, request);
      },
      request, __func__);
}

GOOGLE_CLOUD_CPP_INLINE_NAMESPACE_END
}  // namespace vmmigration_v1_internal
}  // namespace cloud
}  // namespace google
