// 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/retail/v2/product_service.proto

#ifndef GOOGLE_CLOUD_CPP_GOOGLE_CLOUD_RETAIL_V2_PRODUCT_CLIENT_H
#define GOOGLE_CLOUD_CPP_GOOGLE_CLOUD_RETAIL_V2_PRODUCT_CLIENT_H

#include "google/cloud/retail/v2/product_connection.h"
#include "google/cloud/future.h"
#include "google/cloud/no_await_tag.h"
#include "google/cloud/options.h"
#include "google/cloud/polling_policy.h"
#include "google/cloud/status_or.h"
#include "google/cloud/version.h"
#include <google/longrunning/operations.grpc.pb.h>
#include <map>
#include <memory>
#include <string>

namespace google {
namespace cloud {
namespace retail_v2 {
GOOGLE_CLOUD_CPP_INLINE_NAMESPACE_BEGIN

///
/// Service for ingesting [Product][google.cloud.retail.v2.Product] information
/// of the customer's website.
///
/// @par Equality
///
/// Instances of this class created via copy-construction or copy-assignment
/// always compare equal. Instances created with equal
/// `std::shared_ptr<*Connection>` objects compare equal. Objects that compare
/// equal share the same underlying resources.
///
/// @par Performance
///
/// Creating a new instance of this class is a relatively expensive operation,
/// new objects establish new connections to the service. In contrast,
/// copy-construction, move-construction, and the corresponding assignment
/// operations are relatively efficient as the copies share all underlying
/// resources.
///
/// @par Thread Safety
///
/// Concurrent access to different instances of this class, even if they compare
/// equal, is guaranteed to work. Two or more threads operating on the same
/// instance of this class is not guaranteed to work. Since copy-construction
/// and move-construction is a relatively efficient operation, consider using
/// such a copy when using this class from multiple threads.
///
/// [google.cloud.retail.v2.Product]:
/// @googleapis_reference_link{google/cloud/retail/v2/product.proto#L43}
///
class ProductServiceClient {
 public:
  explicit ProductServiceClient(
      std::shared_ptr<ProductServiceConnection> connection, Options opts = {});
  ~ProductServiceClient();

  ///@{
  /// @name Copy and move support
  ProductServiceClient(ProductServiceClient const&) = default;
  ProductServiceClient& operator=(ProductServiceClient const&) = default;
  ProductServiceClient(ProductServiceClient&&) = default;
  ProductServiceClient& operator=(ProductServiceClient&&) = default;
  ///@}

  ///@{
  /// @name Equality
  friend bool operator==(ProductServiceClient const& a,
                         ProductServiceClient const& b) {
    return a.connection_ == b.connection_;
  }
  friend bool operator!=(ProductServiceClient const& a,
                         ProductServiceClient const& b) {
    return !(a == b);
  }
  ///@}

  // clang-format off
  ///
  /// Creates a [Product][google.cloud.retail.v2.Product].
  ///
  /// @param parent  Required. The parent catalog resource name, such as
  ///  `projects/*/locations/global/catalogs/default_catalog/branches/default_branch`.
  /// @param product  Required. The [Product][google.cloud.retail.v2.Product] to create.
  /// @param product_id  Required. The ID to use for the [Product][google.cloud.retail.v2.Product],
  ///  which will become the final component of the
  ///  [Product.name][google.cloud.retail.v2.Product.name].
  ///  @n
  ///  If the caller does not have permission to create the
  ///  [Product][google.cloud.retail.v2.Product], regardless of whether or not it
  ///  exists, a PERMISSION_DENIED error is returned.
  ///  @n
  ///  This field must be unique among all
  ///  [Product][google.cloud.retail.v2.Product]s with the same
  ///  [parent][google.cloud.retail.v2.CreateProductRequest.parent]. Otherwise, an
  ///  ALREADY_EXISTS error is returned.
  ///  @n
  ///  This field must be a UTF-8 encoded string with a length limit of 128
  ///  characters. Otherwise, an INVALID_ARGUMENT error is returned.
  /// @param opts Optional. Override the class-level options, such as retry and
  ///     backoff policies.
  /// @return the result of the RPC. The response message type
  ///     ([google.cloud.retail.v2.Product])
  ///     is mapped to a C++ class using the [Protobuf mapping rules].
  ///     If the request fails, the [`StatusOr`] contains the error details.
  ///
  /// [Protobuf mapping rules]: https://protobuf.dev/reference/cpp/cpp-generated/
  /// [input iterator requirements]: https://en.cppreference.com/w/cpp/named_req/InputIterator
  /// [`std::string`]: https://en.cppreference.com/w/cpp/string/basic_string
  /// [`future`]: @ref google::cloud::future
  /// [`StatusOr`]: @ref google::cloud::StatusOr
  /// [`Status`]: @ref google::cloud::Status
  /// [google.cloud.retail.v2.CreateProductRequest]: @googleapis_reference_link{google/cloud/retail/v2/product_service.proto#L369}
  /// [google.cloud.retail.v2.CreateProductRequest.parent]: @googleapis_reference_link{google/cloud/retail/v2/product_service.proto#L372}
  /// [google.cloud.retail.v2.Product]: @googleapis_reference_link{google/cloud/retail/v2/product.proto#L43}
  /// [google.cloud.retail.v2.Product.name]: @googleapis_reference_link{google/cloud/retail/v2/product.proto#L160}
  ///
  // clang-format on
  StatusOr<google::cloud::retail::v2::Product> CreateProduct(
      std::string const& parent,
      google::cloud::retail::v2::Product const& product,
      std::string const& product_id, Options opts = {});

  // clang-format off
  ///
  /// Creates a [Product][google.cloud.retail.v2.Product].
  ///
  /// @param request Unary RPCs, such as the one wrapped by this
  ///     function, receive a single `request` proto message which includes all
  ///     the inputs for the RPC. In this case, the proto message is a
  ///     [google.cloud.retail.v2.CreateProductRequest].
  ///     Proto messages are converted to C++ classes by Protobuf, using the
  ///     [Protobuf mapping rules].
  /// @param opts Optional. Override the class-level options, such as retry and
  ///     backoff policies.
  /// @return the result of the RPC. The response message type
  ///     ([google.cloud.retail.v2.Product])
  ///     is mapped to a C++ class using the [Protobuf mapping rules].
  ///     If the request fails, the [`StatusOr`] contains the error details.
  ///
  /// [Protobuf mapping rules]: https://protobuf.dev/reference/cpp/cpp-generated/
  /// [input iterator requirements]: https://en.cppreference.com/w/cpp/named_req/InputIterator
  /// [`std::string`]: https://en.cppreference.com/w/cpp/string/basic_string
  /// [`future`]: @ref google::cloud::future
  /// [`StatusOr`]: @ref google::cloud::StatusOr
  /// [`Status`]: @ref google::cloud::Status
  /// [google.cloud.retail.v2.CreateProductRequest]: @googleapis_reference_link{google/cloud/retail/v2/product_service.proto#L369}
  /// [google.cloud.retail.v2.Product]: @googleapis_reference_link{google/cloud/retail/v2/product.proto#L43}
  ///
  // clang-format on
  StatusOr<google::cloud::retail::v2::Product> CreateProduct(
      google::cloud::retail::v2::CreateProductRequest const& request,
      Options opts = {});

  // clang-format off
  ///
  /// Gets a [Product][google.cloud.retail.v2.Product].
  ///
  /// @param name  Required. Full resource name of [Product][google.cloud.retail.v2.Product],
  ///  such as
  ///  `projects/*/locations/global/catalogs/default_catalog/branches/default_branch/products/some_product_id`.
  ///  @n
  ///  If the caller does not have permission to access the
  ///  [Product][google.cloud.retail.v2.Product], regardless of whether or not it
  ///  exists, a PERMISSION_DENIED error is returned.
  ///  @n
  ///  If the requested [Product][google.cloud.retail.v2.Product] does not exist,
  ///  a NOT_FOUND error is returned.
  /// @param opts Optional. Override the class-level options, such as retry and
  ///     backoff policies.
  /// @return the result of the RPC. The response message type
  ///     ([google.cloud.retail.v2.Product])
  ///     is mapped to a C++ class using the [Protobuf mapping rules].
  ///     If the request fails, the [`StatusOr`] contains the error details.
  ///
  /// [Protobuf mapping rules]: https://protobuf.dev/reference/cpp/cpp-generated/
  /// [input iterator requirements]: https://en.cppreference.com/w/cpp/named_req/InputIterator
  /// [`std::string`]: https://en.cppreference.com/w/cpp/string/basic_string
  /// [`future`]: @ref google::cloud::future
  /// [`StatusOr`]: @ref google::cloud::StatusOr
  /// [`Status`]: @ref google::cloud::Status
  /// [google.cloud.retail.v2.GetProductRequest]: @googleapis_reference_link{google/cloud/retail/v2/product_service.proto#L401}
  /// [google.cloud.retail.v2.Product]: @googleapis_reference_link{google/cloud/retail/v2/product.proto#L43}
  ///
  // clang-format on
  StatusOr<google::cloud::retail::v2::Product> GetProduct(
      std::string const& name, Options opts = {});

  // clang-format off
  ///
  /// Gets a [Product][google.cloud.retail.v2.Product].
  ///
  /// @param request Unary RPCs, such as the one wrapped by this
  ///     function, receive a single `request` proto message which includes all
  ///     the inputs for the RPC. In this case, the proto message is a
  ///     [google.cloud.retail.v2.GetProductRequest].
  ///     Proto messages are converted to C++ classes by Protobuf, using the
  ///     [Protobuf mapping rules].
  /// @param opts Optional. Override the class-level options, such as retry and
  ///     backoff policies.
  /// @return the result of the RPC. The response message type
  ///     ([google.cloud.retail.v2.Product])
  ///     is mapped to a C++ class using the [Protobuf mapping rules].
  ///     If the request fails, the [`StatusOr`] contains the error details.
  ///
  /// [Protobuf mapping rules]: https://protobuf.dev/reference/cpp/cpp-generated/
  /// [input iterator requirements]: https://en.cppreference.com/w/cpp/named_req/InputIterator
  /// [`std::string`]: https://en.cppreference.com/w/cpp/string/basic_string
  /// [`future`]: @ref google::cloud::future
  /// [`StatusOr`]: @ref google::cloud::StatusOr
  /// [`Status`]: @ref google::cloud::Status
  /// [google.cloud.retail.v2.GetProductRequest]: @googleapis_reference_link{google/cloud/retail/v2/product_service.proto#L401}
  /// [google.cloud.retail.v2.Product]: @googleapis_reference_link{google/cloud/retail/v2/product.proto#L43}
  ///
  // clang-format on
  StatusOr<google::cloud::retail::v2::Product> GetProduct(
      google::cloud::retail::v2::GetProductRequest const& request,
      Options opts = {});

  // clang-format off
  ///
  /// Gets a list of [Product][google.cloud.retail.v2.Product]s.
  ///
  /// @param parent  Required. The parent branch resource name, such as
  ///  `projects/*/locations/global/catalogs/default_catalog/branches/0`. Use
  ///  `default_branch` as the branch ID, to list products under the default
  ///  branch.
  ///  @n
  ///  If the caller does not have permission to list
  ///  [Product][google.cloud.retail.v2.Product]s under this branch, regardless of
  ///  whether or not this branch exists, a PERMISSION_DENIED error is returned.
  /// @param opts Optional. Override the class-level options, such as retry and
  ///     backoff policies.
  /// @return a [StreamRange](@ref google::cloud::StreamRange)
  ///     to iterate of the results. See the documentation of this type for
  ///     details. In brief, this class has `begin()` and `end()` member
  ///     functions returning a iterator class meeting the
  ///     [input iterator requirements]. The value type for this iterator is a
  ///     [`StatusOr`] as the iteration may fail even after some values are
  ///     retrieved successfully, for example, if there is a network disconnect.
  ///     An empty set of results does not indicate an error, it indicates
  ///     that there are no resources meeting the request criteria.
  ///     On a successful iteration the `StatusOr<T>` contains elements of type
  ///     [google.cloud.retail.v2.Product], or rather,
  ///     the C++ class generated by Protobuf from that type. Please consult the
  ///     Protobuf documentation for details on the [Protobuf mapping rules].
  ///
  /// [Protobuf mapping rules]: https://protobuf.dev/reference/cpp/cpp-generated/
  /// [input iterator requirements]: https://en.cppreference.com/w/cpp/named_req/InputIterator
  /// [`std::string`]: https://en.cppreference.com/w/cpp/string/basic_string
  /// [`future`]: @ref google::cloud::future
  /// [`StatusOr`]: @ref google::cloud::StatusOr
  /// [`Status`]: @ref google::cloud::Status
  /// [google.cloud.retail.v2.ListProductsRequest]: @googleapis_reference_link{google/cloud/retail/v2/product_service.proto#L488}
  /// [google.cloud.retail.v2.Product]: @googleapis_reference_link{google/cloud/retail/v2/product.proto#L43}
  ///
  // clang-format on
  StreamRange<google::cloud::retail::v2::Product> ListProducts(
      std::string const& parent, Options opts = {});

  // clang-format off
  ///
  /// Gets a list of [Product][google.cloud.retail.v2.Product]s.
  ///
  /// @param request Unary RPCs, such as the one wrapped by this
  ///     function, receive a single `request` proto message which includes all
  ///     the inputs for the RPC. In this case, the proto message is a
  ///     [google.cloud.retail.v2.ListProductsRequest].
  ///     Proto messages are converted to C++ classes by Protobuf, using the
  ///     [Protobuf mapping rules].
  /// @param opts Optional. Override the class-level options, such as retry and
  ///     backoff policies.
  /// @return a [StreamRange](@ref google::cloud::StreamRange)
  ///     to iterate of the results. See the documentation of this type for
  ///     details. In brief, this class has `begin()` and `end()` member
  ///     functions returning a iterator class meeting the
  ///     [input iterator requirements]. The value type for this iterator is a
  ///     [`StatusOr`] as the iteration may fail even after some values are
  ///     retrieved successfully, for example, if there is a network disconnect.
  ///     An empty set of results does not indicate an error, it indicates
  ///     that there are no resources meeting the request criteria.
  ///     On a successful iteration the `StatusOr<T>` contains elements of type
  ///     [google.cloud.retail.v2.Product], or rather,
  ///     the C++ class generated by Protobuf from that type. Please consult the
  ///     Protobuf documentation for details on the [Protobuf mapping rules].
  ///
  /// [Protobuf mapping rules]: https://protobuf.dev/reference/cpp/cpp-generated/
  /// [input iterator requirements]: https://en.cppreference.com/w/cpp/named_req/InputIterator
  /// [`std::string`]: https://en.cppreference.com/w/cpp/string/basic_string
  /// [`future`]: @ref google::cloud::future
  /// [`StatusOr`]: @ref google::cloud::StatusOr
  /// [`Status`]: @ref google::cloud::Status
  /// [google.cloud.retail.v2.ListProductsRequest]: @googleapis_reference_link{google/cloud/retail/v2/product_service.proto#L488}
  /// [google.cloud.retail.v2.Product]: @googleapis_reference_link{google/cloud/retail/v2/product.proto#L43}
  ///
  // clang-format on
  StreamRange<google::cloud::retail::v2::Product> ListProducts(
      google::cloud::retail::v2::ListProductsRequest request,
      Options opts = {});

  // clang-format off
  ///
  /// Updates a [Product][google.cloud.retail.v2.Product].
  ///
  /// @param product  Required. The product to update/create.
  ///  @n
  ///  If the caller does not have permission to update the
  ///  [Product][google.cloud.retail.v2.Product], regardless of whether or not it
  ///  exists, a PERMISSION_DENIED error is returned.
  ///  @n
  ///  If the [Product][google.cloud.retail.v2.Product] to update does not exist
  ///  and
  ///  [allow_missing][google.cloud.retail.v2.UpdateProductRequest.allow_missing]
  ///  is not set, a NOT_FOUND error is returned.
  /// @param update_mask  Indicates which fields in the provided
  ///  [Product][google.cloud.retail.v2.Product] to update. The immutable and
  ///  output only fields are NOT supported. If not set, all supported fields (the
  ///  fields that are neither immutable nor output only) are updated.
  ///  @n
  ///  If an unsupported or unknown field is provided, an INVALID_ARGUMENT error
  ///  is returned.
  ///  @n
  ///  The attribute key can be updated by setting the mask path as
  ///  "attributes.${key_name}". If a key name is present in the mask but not in
  ///  the patching product from the request, this key will be deleted after the
  ///  update.
  /// @param opts Optional. Override the class-level options, such as retry and
  ///     backoff policies.
  /// @return the result of the RPC. The response message type
  ///     ([google.cloud.retail.v2.Product])
  ///     is mapped to a C++ class using the [Protobuf mapping rules].
  ///     If the request fails, the [`StatusOr`] contains the error details.
  ///
  /// [Protobuf mapping rules]: https://protobuf.dev/reference/cpp/cpp-generated/
  /// [input iterator requirements]: https://en.cppreference.com/w/cpp/named_req/InputIterator
  /// [`std::string`]: https://en.cppreference.com/w/cpp/string/basic_string
  /// [`future`]: @ref google::cloud::future
  /// [`StatusOr`]: @ref google::cloud::StatusOr
  /// [`Status`]: @ref google::cloud::Status
  /// [google.cloud.retail.v2.Product]: @googleapis_reference_link{google/cloud/retail/v2/product.proto#L43}
  /// [google.cloud.retail.v2.UpdateProductRequest]: @googleapis_reference_link{google/cloud/retail/v2/product_service.proto#L421}
  /// [google.cloud.retail.v2.UpdateProductRequest.allow_missing]: @googleapis_reference_link{google/cloud/retail/v2/product_service.proto#L451}
  ///
  // clang-format on
  StatusOr<google::cloud::retail::v2::Product> UpdateProduct(
      google::cloud::retail::v2::Product const& product,
      google::protobuf::FieldMask const& update_mask, Options opts = {});

  // clang-format off
  ///
  /// Updates a [Product][google.cloud.retail.v2.Product].
  ///
  /// @param request Unary RPCs, such as the one wrapped by this
  ///     function, receive a single `request` proto message which includes all
  ///     the inputs for the RPC. In this case, the proto message is a
  ///     [google.cloud.retail.v2.UpdateProductRequest].
  ///     Proto messages are converted to C++ classes by Protobuf, using the
  ///     [Protobuf mapping rules].
  /// @param opts Optional. Override the class-level options, such as retry and
  ///     backoff policies.
  /// @return the result of the RPC. The response message type
  ///     ([google.cloud.retail.v2.Product])
  ///     is mapped to a C++ class using the [Protobuf mapping rules].
  ///     If the request fails, the [`StatusOr`] contains the error details.
  ///
  /// [Protobuf mapping rules]: https://protobuf.dev/reference/cpp/cpp-generated/
  /// [input iterator requirements]: https://en.cppreference.com/w/cpp/named_req/InputIterator
  /// [`std::string`]: https://en.cppreference.com/w/cpp/string/basic_string
  /// [`future`]: @ref google::cloud::future
  /// [`StatusOr`]: @ref google::cloud::StatusOr
  /// [`Status`]: @ref google::cloud::Status
  /// [google.cloud.retail.v2.Product]: @googleapis_reference_link{google/cloud/retail/v2/product.proto#L43}
  /// [google.cloud.retail.v2.UpdateProductRequest]: @googleapis_reference_link{google/cloud/retail/v2/product_service.proto#L421}
  ///
  // clang-format on
  StatusOr<google::cloud::retail::v2::Product> UpdateProduct(
      google::cloud::retail::v2::UpdateProductRequest const& request,
      Options opts = {});

  // clang-format off
  ///
  /// Deletes a [Product][google.cloud.retail.v2.Product].
  ///
  /// @param name  Required. Full resource name of [Product][google.cloud.retail.v2.Product],
  ///  such as
  ///  `projects/*/locations/global/catalogs/default_catalog/branches/default_branch/products/some_product_id`.
  ///  @n
  ///  If the caller does not have permission to delete the
  ///  [Product][google.cloud.retail.v2.Product], regardless of whether or not it
  ///  exists, a PERMISSION_DENIED error is returned.
  ///  @n
  ///  If the [Product][google.cloud.retail.v2.Product] to delete does not exist,
  ///  a NOT_FOUND error is returned.
  ///  @n
  ///  The [Product][google.cloud.retail.v2.Product] to delete can neither be a
  ///  [Product.Type.COLLECTION][google.cloud.retail.v2.Product.Type.COLLECTION]
  ///  [Product][google.cloud.retail.v2.Product] member nor a
  ///  [Product.Type.PRIMARY][google.cloud.retail.v2.Product.Type.PRIMARY]
  ///  [Product][google.cloud.retail.v2.Product] with more than one
  ///  [variants][google.cloud.retail.v2.Product.Type.VARIANT]. Otherwise, an
  ///  INVALID_ARGUMENT error is returned.
  ///  @n
  ///  All inventory information for the named
  ///  [Product][google.cloud.retail.v2.Product] will be deleted.
  /// @param opts Optional. Override the class-level options, such as retry and
  ///     backoff policies.
  /// @return a [`Status`] object. If the request failed, the
  ///     status contains the details of the failure.
  ///
  /// [Protobuf mapping rules]: https://protobuf.dev/reference/cpp/cpp-generated/
  /// [input iterator requirements]: https://en.cppreference.com/w/cpp/named_req/InputIterator
  /// [`std::string`]: https://en.cppreference.com/w/cpp/string/basic_string
  /// [`future`]: @ref google::cloud::future
  /// [`StatusOr`]: @ref google::cloud::StatusOr
  /// [`Status`]: @ref google::cloud::Status
  /// [google.cloud.retail.v2.DeleteProductRequest]: @googleapis_reference_link{google/cloud/retail/v2/product_service.proto#L457}
  /// [google.cloud.retail.v2.Product]: @googleapis_reference_link{google/cloud/retail/v2/product.proto#L43}
  /// [google.cloud.retail.v2.Product.Type.COLLECTION]: @googleapis_reference_link{google/cloud/retail/v2/product.proto#L81}
  /// [google.cloud.retail.v2.Product.Type.PRIMARY]: @googleapis_reference_link{google/cloud/retail/v2/product.proto#L63}
  /// [google.cloud.retail.v2.Product.Type.VARIANT]: @googleapis_reference_link{google/cloud/retail/v2/product.proto#L73}
  ///
  // clang-format on
  Status DeleteProduct(std::string const& name, Options opts = {});

  // clang-format off
  ///
  /// Deletes a [Product][google.cloud.retail.v2.Product].
  ///
  /// @param request Unary RPCs, such as the one wrapped by this
  ///     function, receive a single `request` proto message which includes all
  ///     the inputs for the RPC. In this case, the proto message is a
  ///     [google.cloud.retail.v2.DeleteProductRequest].
  ///     Proto messages are converted to C++ classes by Protobuf, using the
  ///     [Protobuf mapping rules].
  /// @param opts Optional. Override the class-level options, such as retry and
  ///     backoff policies.
  /// @return a [`Status`] object. If the request failed, the
  ///     status contains the details of the failure.
  ///
  /// [Protobuf mapping rules]: https://protobuf.dev/reference/cpp/cpp-generated/
  /// [input iterator requirements]: https://en.cppreference.com/w/cpp/named_req/InputIterator
  /// [`std::string`]: https://en.cppreference.com/w/cpp/string/basic_string
  /// [`future`]: @ref google::cloud::future
  /// [`StatusOr`]: @ref google::cloud::StatusOr
  /// [`Status`]: @ref google::cloud::Status
  /// [google.cloud.retail.v2.DeleteProductRequest]: @googleapis_reference_link{google/cloud/retail/v2/product_service.proto#L457}
  /// [google.cloud.retail.v2.Product]: @googleapis_reference_link{google/cloud/retail/v2/product.proto#L43}
  ///
  // clang-format on
  Status DeleteProduct(
      google::cloud::retail::v2::DeleteProductRequest const& request,
      Options opts = {});

  // clang-format off
  ///
  /// Permanently deletes all selected [Product][google.cloud.retail.v2.Product]s
  /// under a branch.
  ///
  /// This process is asynchronous. If the request is valid, the removal will be
  /// enqueued and processed offline. Depending on the number of
  /// [Product][google.cloud.retail.v2.Product]s, this operation could take hours
  /// to complete. Before the operation completes, some
  /// [Product][google.cloud.retail.v2.Product]s may still be returned by
  /// [ProductService.GetProduct][google.cloud.retail.v2.ProductService.GetProduct]
  /// or
  /// [ProductService.ListProducts][google.cloud.retail.v2.ProductService.ListProducts].
  ///
  /// Depending on the number of [Product][google.cloud.retail.v2.Product]s, this
  /// operation could take hours to complete. To get a sample of
  /// [Product][google.cloud.retail.v2.Product]s that would be deleted, set
  /// [PurgeProductsRequest.force][google.cloud.retail.v2.PurgeProductsRequest.force]
  /// to false.
  ///
  /// @param request Unary RPCs, such as the one wrapped by this
  ///     function, receive a single `request` proto message which includes all
  ///     the inputs for the RPC. In this case, the proto message is a
  ///     [google.cloud.retail.v2.PurgeProductsRequest].
  ///     Proto messages are converted to C++ classes by Protobuf, using the
  ///     [Protobuf mapping rules].
  /// @param opts Optional. Override the class-level options, such as retry and
  ///     backoff policies.
  /// @return A [`future`] that becomes satisfied when the LRO
  ///     ([Long Running Operation]) completes or the polling policy in effect
  ///     for this call is exhausted. The future is satisfied with an error if
  ///     the LRO completes with an error or the polling policy is exhausted.
  ///     In this case the [`StatusOr`] returned by the future contains the
  ///     error. If the LRO completes successfully the value of the future
  ///     contains the LRO's result. For this RPC the result is a
  ///     [google.cloud.retail.v2.PurgeProductsResponse] proto message.
  ///     The C++ class representing this message is created by Protobuf, using
  ///     the [Protobuf mapping rules].
  ///
  /// [Protobuf mapping rules]: https://protobuf.dev/reference/cpp/cpp-generated/
  /// [input iterator requirements]: https://en.cppreference.com/w/cpp/named_req/InputIterator
  /// [Long Running Operation]: https://google.aip.dev/151
  /// [`std::string`]: https://en.cppreference.com/w/cpp/string/basic_string
  /// [`future`]: @ref google::cloud::future
  /// [`StatusOr`]: @ref google::cloud::StatusOr
  /// [`Status`]: @ref google::cloud::Status
  /// [google.cloud.retail.v2.Product]: @googleapis_reference_link{google/cloud/retail/v2/product.proto#L43}
  /// [google.cloud.retail.v2.ProductService.GetProduct]: @googleapis_reference_link{google/cloud/retail/v2/product_service.proto#L58}
  /// [google.cloud.retail.v2.ProductService.ListProducts]: @googleapis_reference_link{google/cloud/retail/v2/product_service.proto#L66}
  /// [google.cloud.retail.v2.PurgeProductsRequest]: @googleapis_reference_link{google/cloud/retail/v2/purge_config.proto#L54}
  /// [google.cloud.retail.v2.PurgeProductsRequest.force]: @googleapis_reference_link{google/cloud/retail/v2/purge_config.proto#L107}
  /// [google.cloud.retail.v2.PurgeProductsResponse]: @googleapis_reference_link{google/cloud/retail/v2/purge_config.proto#L113}
  ///
  // clang-format on
  future<StatusOr<google::cloud::retail::v2::PurgeProductsResponse>>
  PurgeProducts(google::cloud::retail::v2::PurgeProductsRequest const& request,
                Options opts = {});

  // clang-format off
  ///
  /// @copybrief PurgeProducts
  ///
  /// Specifying the [`NoAwaitTag`] immediately returns the
  /// [`google::longrunning::Operation`] that corresponds to the Long Running
  /// Operation that has been started. No polling for operation status occurs.
  ///
  /// [`NoAwaitTag`]: @ref google::cloud::NoAwaitTag
  ///
  // clang-format on
  StatusOr<google::longrunning::Operation> PurgeProducts(
      NoAwaitTag,
      google::cloud::retail::v2::PurgeProductsRequest const& request,
      Options opts = {});

  // clang-format off
  ///
  /// @copybrief PurgeProducts
  ///
  /// This method accepts a `google::longrunning::Operation` that corresponds
  /// to a previously started Long Running Operation (LRO) and polls the status
  /// of the LRO in the background.
  ///
  // clang-format on
  future<StatusOr<google::cloud::retail::v2::PurgeProductsResponse>>
  PurgeProducts(google::longrunning::Operation const& operation,
                Options opts = {});

  // clang-format off
  ///
  /// Bulk import of multiple [Product][google.cloud.retail.v2.Product]s.
  ///
  /// Request processing may be synchronous.
  /// Non-existing items are created.
  ///
  /// Note that it is possible for a subset of the
  /// [Product][google.cloud.retail.v2.Product]s to be successfully updated.
  ///
  /// @param request Unary RPCs, such as the one wrapped by this
  ///     function, receive a single `request` proto message which includes all
  ///     the inputs for the RPC. In this case, the proto message is a
  ///     [google.cloud.retail.v2.ImportProductsRequest].
  ///     Proto messages are converted to C++ classes by Protobuf, using the
  ///     [Protobuf mapping rules].
  /// @param opts Optional. Override the class-level options, such as retry and
  ///     backoff policies.
  /// @return A [`future`] that becomes satisfied when the LRO
  ///     ([Long Running Operation]) completes or the polling policy in effect
  ///     for this call is exhausted. The future is satisfied with an error if
  ///     the LRO completes with an error or the polling policy is exhausted.
  ///     In this case the [`StatusOr`] returned by the future contains the
  ///     error. If the LRO completes successfully the value of the future
  ///     contains the LRO's result. For this RPC the result is a
  ///     [google.cloud.retail.v2.ImportProductsResponse] proto message.
  ///     The C++ class representing this message is created by Protobuf, using
  ///     the [Protobuf mapping rules].
  ///
  /// [Protobuf mapping rules]: https://protobuf.dev/reference/cpp/cpp-generated/
  /// [input iterator requirements]: https://en.cppreference.com/w/cpp/named_req/InputIterator
  /// [Long Running Operation]: https://google.aip.dev/151
  /// [`std::string`]: https://en.cppreference.com/w/cpp/string/basic_string
  /// [`future`]: @ref google::cloud::future
  /// [`StatusOr`]: @ref google::cloud::StatusOr
  /// [`Status`]: @ref google::cloud::Status
  /// [google.cloud.retail.v2.ImportProductsRequest]: @googleapis_reference_link{google/cloud/retail/v2/import_config.proto#L161}
  /// [google.cloud.retail.v2.ImportProductsResponse]: @googleapis_reference_link{google/cloud/retail/v2/import_config.proto#L348}
  /// [google.cloud.retail.v2.Product]: @googleapis_reference_link{google/cloud/retail/v2/product.proto#L43}
  ///
  // clang-format on
  future<StatusOr<google::cloud::retail::v2::ImportProductsResponse>>
  ImportProducts(
      google::cloud::retail::v2::ImportProductsRequest const& request,
      Options opts = {});

  // clang-format off
  ///
  /// @copybrief ImportProducts
  ///
  /// Specifying the [`NoAwaitTag`] immediately returns the
  /// [`google::longrunning::Operation`] that corresponds to the Long Running
  /// Operation that has been started. No polling for operation status occurs.
  ///
  /// [`NoAwaitTag`]: @ref google::cloud::NoAwaitTag
  ///
  // clang-format on
  StatusOr<google::longrunning::Operation> ImportProducts(
      NoAwaitTag,
      google::cloud::retail::v2::ImportProductsRequest const& request,
      Options opts = {});

  // clang-format off
  ///
  /// @copybrief ImportProducts
  ///
  /// This method accepts a `google::longrunning::Operation` that corresponds
  /// to a previously started Long Running Operation (LRO) and polls the status
  /// of the LRO in the background.
  ///
  // clang-format on
  future<StatusOr<google::cloud::retail::v2::ImportProductsResponse>>
  ImportProducts(google::longrunning::Operation const& operation,
                 Options opts = {});

  // clang-format off
  ///
  /// Updates inventory information for a
  /// [Product][google.cloud.retail.v2.Product] while respecting the last update
  /// timestamps of each inventory field.
  ///
  /// This process is asynchronous and does not require the
  /// [Product][google.cloud.retail.v2.Product] to exist before updating
  /// fulfillment information. If the request is valid, the update is enqueued
  /// and processed downstream. As a consequence, when a response is returned,
  /// updates are not immediately manifested in the
  /// [Product][google.cloud.retail.v2.Product] queried by
  /// [ProductService.GetProduct][google.cloud.retail.v2.ProductService.GetProduct]
  /// or
  /// [ProductService.ListProducts][google.cloud.retail.v2.ProductService.ListProducts].
  ///
  /// When inventory is updated with
  /// [ProductService.CreateProduct][google.cloud.retail.v2.ProductService.CreateProduct]
  /// and
  /// [ProductService.UpdateProduct][google.cloud.retail.v2.ProductService.UpdateProduct],
  /// the specified inventory field value(s) overwrite any existing value(s)
  /// while ignoring the last update time for this field. Furthermore, the last
  /// update times for the specified inventory fields are overwritten by the
  /// times of the
  /// [ProductService.CreateProduct][google.cloud.retail.v2.ProductService.CreateProduct]
  /// or
  /// [ProductService.UpdateProduct][google.cloud.retail.v2.ProductService.UpdateProduct]
  /// request.
  ///
  /// If no inventory fields are set in
  /// [CreateProductRequest.product][google.cloud.retail.v2.CreateProductRequest.product],
  /// then any pre-existing inventory information for this product is used.
  ///
  /// If no inventory fields are set in
  /// [SetInventoryRequest.set_mask][google.cloud.retail.v2.SetInventoryRequest.set_mask],
  /// then any existing inventory information is preserved.
  ///
  /// Pre-existing inventory information can only be updated with
  /// [ProductService.SetInventory][google.cloud.retail.v2.ProductService.SetInventory],
  /// [ProductService.AddFulfillmentPlaces][google.cloud.retail.v2.ProductService.AddFulfillmentPlaces],
  /// and
  /// [ProductService.RemoveFulfillmentPlaces][google.cloud.retail.v2.ProductService.RemoveFulfillmentPlaces].
  ///
  /// The returned [Operation][google.longrunning.Operation]s is obsolete after
  /// one day, and the [GetOperation][google.longrunning.Operations.GetOperation]
  /// API returns `NOT_FOUND` afterwards.
  ///
  /// If conflicting updates are issued, the
  /// [Operation][google.longrunning.Operation]s associated with the stale
  /// updates are not marked as [done][google.longrunning.Operation.done] until
  /// they are obsolete.
  ///
  /// @param inventory  Required. The inventory information to update.
  ///  @n
  ///  For more information, see [SetInventoryRequest][google.cloud.retail.v2.SetInventoryRequest].
  /// @param set_mask  Indicates which inventory fields in the provided
  ///  [Product][google.cloud.retail.v2.Product] to update.
  ///  @n
  ///  At least one field must be provided.
  ///  @n
  ///  If an unsupported or unknown field is provided, an INVALID_ARGUMENT error
  ///  is returned and the entire update will be ignored.
  /// @param opts Optional. Override the class-level options, such as retry and
  ///     backoff policies.
  /// @return A [`future`] that becomes satisfied when the LRO
  ///     ([Long Running Operation]) completes or the polling policy in effect
  ///     for this call is exhausted. The future is satisfied with an error if
  ///     the LRO completes with an error or the polling policy is exhausted.
  ///     In this case the [`StatusOr`] returned by the future contains the
  ///     error. If the LRO completes successfully the value of the future
  ///     contains the LRO's result. For this RPC the result is a
  ///     [google.cloud.retail.v2.SetInventoryResponse] proto message.
  ///     The C++ class representing this message is created by Protobuf, using
  ///     the [Protobuf mapping rules].
  ///
  /// [Protobuf mapping rules]: https://protobuf.dev/reference/cpp/cpp-generated/
  /// [input iterator requirements]: https://en.cppreference.com/w/cpp/named_req/InputIterator
  /// [Long Running Operation]: https://google.aip.dev/151
  /// [`std::string`]: https://en.cppreference.com/w/cpp/string/basic_string
  /// [`future`]: @ref google::cloud::future
  /// [`StatusOr`]: @ref google::cloud::StatusOr
  /// [`Status`]: @ref google::cloud::Status
  /// [google.cloud.retail.v2.CreateProductRequest.product]: @googleapis_reference_link{google/cloud/retail/v2/product_service.proto#L378}
  /// [google.cloud.retail.v2.Product]: @googleapis_reference_link{google/cloud/retail/v2/product.proto#L43}
  /// [google.cloud.retail.v2.ProductService.AddFulfillmentPlaces]: @googleapis_reference_link{google/cloud/retail/v2/product_service.proto#L229}
  /// [google.cloud.retail.v2.ProductService.CreateProduct]: @googleapis_reference_link{google/cloud/retail/v2/product_service.proto#L49}
  /// [google.cloud.retail.v2.ProductService.GetProduct]: @googleapis_reference_link{google/cloud/retail/v2/product_service.proto#L58}
  /// [google.cloud.retail.v2.ProductService.ListProducts]: @googleapis_reference_link{google/cloud/retail/v2/product_service.proto#L66}
  /// [google.cloud.retail.v2.ProductService.RemoveFulfillmentPlaces]: @googleapis_reference_link{google/cloud/retail/v2/product_service.proto#L272}
  /// [google.cloud.retail.v2.ProductService.SetInventory]: @googleapis_reference_link{google/cloud/retail/v2/product_service.proto#L187}
  /// [google.cloud.retail.v2.ProductService.UpdateProduct]: @googleapis_reference_link{google/cloud/retail/v2/product_service.proto#L74}
  /// [google.cloud.retail.v2.SetInventoryRequest]: @googleapis_reference_link{google/cloud/retail/v2/product_service.proto#L588}
  /// [google.cloud.retail.v2.SetInventoryRequest.set_mask]: @googleapis_reference_link{google/cloud/retail/v2/product_service.proto#L656}
  /// [google.cloud.retail.v2.SetInventoryResponse]: @googleapis_reference_link{google/cloud/retail/v2/product_service.proto#L682}
  /// [google.longrunning.Operation]: @googleapis_reference_link{google/longrunning/operations.proto#L121}
  /// [google.longrunning.Operation.done]: @googleapis_reference_link{google/longrunning/operations.proto#L136}
  /// [google.longrunning.Operations.GetOperation]: @googleapis_reference_link{google/longrunning/operations.proto#L70}
  ///
  // clang-format on
  future<StatusOr<google::cloud::retail::v2::SetInventoryResponse>>
  SetInventory(google::cloud::retail::v2::Product const& inventory,
               google::protobuf::FieldMask const& set_mask, Options opts = {});

  // clang-format off
  ///
  /// @copybrief SetInventory
  ///
  /// Specifying the [`NoAwaitTag`] immediately returns the
  /// [`google::longrunning::Operation`] that corresponds to the Long Running
  /// Operation that has been started. No polling for operation status occurs.
  ///
  /// [`NoAwaitTag`]: @ref google::cloud::NoAwaitTag
  ///
  // clang-format on
  StatusOr<google::longrunning::Operation> SetInventory(
      NoAwaitTag, google::cloud::retail::v2::Product const& inventory,
      google::protobuf::FieldMask const& set_mask, Options opts = {});

  // clang-format off
  ///
  /// Updates inventory information for a
  /// [Product][google.cloud.retail.v2.Product] while respecting the last update
  /// timestamps of each inventory field.
  ///
  /// This process is asynchronous and does not require the
  /// [Product][google.cloud.retail.v2.Product] to exist before updating
  /// fulfillment information. If the request is valid, the update is enqueued
  /// and processed downstream. As a consequence, when a response is returned,
  /// updates are not immediately manifested in the
  /// [Product][google.cloud.retail.v2.Product] queried by
  /// [ProductService.GetProduct][google.cloud.retail.v2.ProductService.GetProduct]
  /// or
  /// [ProductService.ListProducts][google.cloud.retail.v2.ProductService.ListProducts].
  ///
  /// When inventory is updated with
  /// [ProductService.CreateProduct][google.cloud.retail.v2.ProductService.CreateProduct]
  /// and
  /// [ProductService.UpdateProduct][google.cloud.retail.v2.ProductService.UpdateProduct],
  /// the specified inventory field value(s) overwrite any existing value(s)
  /// while ignoring the last update time for this field. Furthermore, the last
  /// update times for the specified inventory fields are overwritten by the
  /// times of the
  /// [ProductService.CreateProduct][google.cloud.retail.v2.ProductService.CreateProduct]
  /// or
  /// [ProductService.UpdateProduct][google.cloud.retail.v2.ProductService.UpdateProduct]
  /// request.
  ///
  /// If no inventory fields are set in
  /// [CreateProductRequest.product][google.cloud.retail.v2.CreateProductRequest.product],
  /// then any pre-existing inventory information for this product is used.
  ///
  /// If no inventory fields are set in
  /// [SetInventoryRequest.set_mask][google.cloud.retail.v2.SetInventoryRequest.set_mask],
  /// then any existing inventory information is preserved.
  ///
  /// Pre-existing inventory information can only be updated with
  /// [ProductService.SetInventory][google.cloud.retail.v2.ProductService.SetInventory],
  /// [ProductService.AddFulfillmentPlaces][google.cloud.retail.v2.ProductService.AddFulfillmentPlaces],
  /// and
  /// [ProductService.RemoveFulfillmentPlaces][google.cloud.retail.v2.ProductService.RemoveFulfillmentPlaces].
  ///
  /// The returned [Operation][google.longrunning.Operation]s is obsolete after
  /// one day, and the [GetOperation][google.longrunning.Operations.GetOperation]
  /// API returns `NOT_FOUND` afterwards.
  ///
  /// If conflicting updates are issued, the
  /// [Operation][google.longrunning.Operation]s associated with the stale
  /// updates are not marked as [done][google.longrunning.Operation.done] until
  /// they are obsolete.
  ///
  /// @param request Unary RPCs, such as the one wrapped by this
  ///     function, receive a single `request` proto message which includes all
  ///     the inputs for the RPC. In this case, the proto message is a
  ///     [google.cloud.retail.v2.SetInventoryRequest].
  ///     Proto messages are converted to C++ classes by Protobuf, using the
  ///     [Protobuf mapping rules].
  /// @param opts Optional. Override the class-level options, such as retry and
  ///     backoff policies.
  /// @return A [`future`] that becomes satisfied when the LRO
  ///     ([Long Running Operation]) completes or the polling policy in effect
  ///     for this call is exhausted. The future is satisfied with an error if
  ///     the LRO completes with an error or the polling policy is exhausted.
  ///     In this case the [`StatusOr`] returned by the future contains the
  ///     error. If the LRO completes successfully the value of the future
  ///     contains the LRO's result. For this RPC the result is a
  ///     [google.cloud.retail.v2.SetInventoryResponse] proto message.
  ///     The C++ class representing this message is created by Protobuf, using
  ///     the [Protobuf mapping rules].
  ///
  /// [Protobuf mapping rules]: https://protobuf.dev/reference/cpp/cpp-generated/
  /// [input iterator requirements]: https://en.cppreference.com/w/cpp/named_req/InputIterator
  /// [Long Running Operation]: https://google.aip.dev/151
  /// [`std::string`]: https://en.cppreference.com/w/cpp/string/basic_string
  /// [`future`]: @ref google::cloud::future
  /// [`StatusOr`]: @ref google::cloud::StatusOr
  /// [`Status`]: @ref google::cloud::Status
  /// [google.cloud.retail.v2.CreateProductRequest.product]: @googleapis_reference_link{google/cloud/retail/v2/product_service.proto#L378}
  /// [google.cloud.retail.v2.Product]: @googleapis_reference_link{google/cloud/retail/v2/product.proto#L43}
  /// [google.cloud.retail.v2.ProductService.AddFulfillmentPlaces]: @googleapis_reference_link{google/cloud/retail/v2/product_service.proto#L229}
  /// [google.cloud.retail.v2.ProductService.CreateProduct]: @googleapis_reference_link{google/cloud/retail/v2/product_service.proto#L49}
  /// [google.cloud.retail.v2.ProductService.GetProduct]: @googleapis_reference_link{google/cloud/retail/v2/product_service.proto#L58}
  /// [google.cloud.retail.v2.ProductService.ListProducts]: @googleapis_reference_link{google/cloud/retail/v2/product_service.proto#L66}
  /// [google.cloud.retail.v2.ProductService.RemoveFulfillmentPlaces]: @googleapis_reference_link{google/cloud/retail/v2/product_service.proto#L272}
  /// [google.cloud.retail.v2.ProductService.SetInventory]: @googleapis_reference_link{google/cloud/retail/v2/product_service.proto#L187}
  /// [google.cloud.retail.v2.ProductService.UpdateProduct]: @googleapis_reference_link{google/cloud/retail/v2/product_service.proto#L74}
  /// [google.cloud.retail.v2.SetInventoryRequest]: @googleapis_reference_link{google/cloud/retail/v2/product_service.proto#L588}
  /// [google.cloud.retail.v2.SetInventoryRequest.set_mask]: @googleapis_reference_link{google/cloud/retail/v2/product_service.proto#L656}
  /// [google.cloud.retail.v2.SetInventoryResponse]: @googleapis_reference_link{google/cloud/retail/v2/product_service.proto#L682}
  /// [google.longrunning.Operation]: @googleapis_reference_link{google/longrunning/operations.proto#L121}
  /// [google.longrunning.Operation.done]: @googleapis_reference_link{google/longrunning/operations.proto#L136}
  /// [google.longrunning.Operations.GetOperation]: @googleapis_reference_link{google/longrunning/operations.proto#L70}
  ///
  // clang-format on
  future<StatusOr<google::cloud::retail::v2::SetInventoryResponse>>
  SetInventory(google::cloud::retail::v2::SetInventoryRequest const& request,
               Options opts = {});

  // clang-format off
  ///
  /// @copybrief SetInventory
  ///
  /// Specifying the [`NoAwaitTag`] immediately returns the
  /// [`google::longrunning::Operation`] that corresponds to the Long Running
  /// Operation that has been started. No polling for operation status occurs.
  ///
  /// [`NoAwaitTag`]: @ref google::cloud::NoAwaitTag
  ///
  // clang-format on
  StatusOr<google::longrunning::Operation> SetInventory(
      NoAwaitTag, google::cloud::retail::v2::SetInventoryRequest const& request,
      Options opts = {});

  // clang-format off
  ///
  /// @copybrief SetInventory
  ///
  /// This method accepts a `google::longrunning::Operation` that corresponds
  /// to a previously started Long Running Operation (LRO) and polls the status
  /// of the LRO in the background.
  ///
  // clang-format on
  future<StatusOr<google::cloud::retail::v2::SetInventoryResponse>>
  SetInventory(google::longrunning::Operation const& operation,
               Options opts = {});

  // clang-format off
  ///
  /// We recommend that you use the
  /// [ProductService.AddLocalInventories][google.cloud.retail.v2.ProductService.AddLocalInventories]
  /// method instead of the
  /// [ProductService.AddFulfillmentPlaces][google.cloud.retail.v2.ProductService.AddFulfillmentPlaces]
  /// method.
  /// [ProductService.AddLocalInventories][google.cloud.retail.v2.ProductService.AddLocalInventories]
  /// achieves the same results but provides more fine-grained control over
  /// ingesting local inventory data.
  ///
  /// Incrementally adds place IDs to
  /// [Product.fulfillment_info.place_ids][google.cloud.retail.v2.FulfillmentInfo.place_ids].
  ///
  /// This process is asynchronous and does not require the
  /// [Product][google.cloud.retail.v2.Product] to exist before updating
  /// fulfillment information. If the request is valid, the update will be
  /// enqueued and processed downstream. As a consequence, when a response is
  /// returned, the added place IDs are not immediately manifested in the
  /// [Product][google.cloud.retail.v2.Product] queried by
  /// [ProductService.GetProduct][google.cloud.retail.v2.ProductService.GetProduct]
  /// or
  /// [ProductService.ListProducts][google.cloud.retail.v2.ProductService.ListProducts].
  ///
  /// The returned [Operation][google.longrunning.Operation]s will be obsolete
  /// after 1 day, and [GetOperation][google.longrunning.Operations.GetOperation]
  /// API will return NOT_FOUND afterwards.
  ///
  /// If conflicting updates are issued, the
  /// [Operation][google.longrunning.Operation]s associated with the stale
  /// updates will not be marked as [done][google.longrunning.Operation.done]
  /// until being obsolete.
  ///
  /// @param product  Required. Full resource name of [Product][google.cloud.retail.v2.Product],
  ///  such as
  ///  `projects/*/locations/global/catalogs/default_catalog/branches/default_branch/products/some_product_id`.
  ///  @n
  ///  If the caller does not have permission to access the
  ///  [Product][google.cloud.retail.v2.Product], regardless of whether or not it
  ///  exists, a PERMISSION_DENIED error is returned.
  /// @param opts Optional. Override the class-level options, such as retry and
  ///     backoff policies.
  /// @return A [`future`] that becomes satisfied when the LRO
  ///     ([Long Running Operation]) completes or the polling policy in effect
  ///     for this call is exhausted. The future is satisfied with an error if
  ///     the LRO completes with an error or the polling policy is exhausted.
  ///     In this case the [`StatusOr`] returned by the future contains the
  ///     error. If the LRO completes successfully the value of the future
  ///     contains the LRO's result. For this RPC the result is a
  ///     [google.cloud.retail.v2.AddFulfillmentPlacesResponse] proto message.
  ///     The C++ class representing this message is created by Protobuf, using
  ///     the [Protobuf mapping rules].
  ///
  /// [Protobuf mapping rules]: https://protobuf.dev/reference/cpp/cpp-generated/
  /// [input iterator requirements]: https://en.cppreference.com/w/cpp/named_req/InputIterator
  /// [Long Running Operation]: https://google.aip.dev/151
  /// [`std::string`]: https://en.cppreference.com/w/cpp/string/basic_string
  /// [`future`]: @ref google::cloud::future
  /// [`StatusOr`]: @ref google::cloud::StatusOr
  /// [`Status`]: @ref google::cloud::Status
  /// [google.cloud.retail.v2.AddFulfillmentPlacesRequest]: @googleapis_reference_link{google/cloud/retail/v2/product_service.proto#L687}
  /// [google.cloud.retail.v2.AddFulfillmentPlacesResponse]: @googleapis_reference_link{google/cloud/retail/v2/product_service.proto#L763}
  /// [google.cloud.retail.v2.FulfillmentInfo.place_ids]: @googleapis_reference_link{google/cloud/retail/v2/common.proto#L614}
  /// [google.cloud.retail.v2.Product]: @googleapis_reference_link{google/cloud/retail/v2/product.proto#L43}
  /// [google.cloud.retail.v2.ProductService.AddFulfillmentPlaces]: @googleapis_reference_link{google/cloud/retail/v2/product_service.proto#L229}
  /// [google.cloud.retail.v2.ProductService.AddLocalInventories]: @googleapis_reference_link{google/cloud/retail/v2/product_service.proto#L313}
  /// [google.cloud.retail.v2.ProductService.GetProduct]: @googleapis_reference_link{google/cloud/retail/v2/product_service.proto#L58}
  /// [google.cloud.retail.v2.ProductService.ListProducts]: @googleapis_reference_link{google/cloud/retail/v2/product_service.proto#L66}
  /// [google.longrunning.Operation]: @googleapis_reference_link{google/longrunning/operations.proto#L121}
  /// [google.longrunning.Operation.done]: @googleapis_reference_link{google/longrunning/operations.proto#L136}
  /// [google.longrunning.Operations.GetOperation]: @googleapis_reference_link{google/longrunning/operations.proto#L70}
  ///
  // clang-format on
  future<StatusOr<google::cloud::retail::v2::AddFulfillmentPlacesResponse>>
  AddFulfillmentPlaces(std::string const& product, Options opts = {});

  // clang-format off
  ///
  /// @copybrief AddFulfillmentPlaces
  ///
  /// Specifying the [`NoAwaitTag`] immediately returns the
  /// [`google::longrunning::Operation`] that corresponds to the Long Running
  /// Operation that has been started. No polling for operation status occurs.
  ///
  /// [`NoAwaitTag`]: @ref google::cloud::NoAwaitTag
  ///
  // clang-format on
  StatusOr<google::longrunning::Operation> AddFulfillmentPlaces(
      NoAwaitTag, std::string const& product, Options opts = {});

  // clang-format off
  ///
  /// We recommend that you use the
  /// [ProductService.AddLocalInventories][google.cloud.retail.v2.ProductService.AddLocalInventories]
  /// method instead of the
  /// [ProductService.AddFulfillmentPlaces][google.cloud.retail.v2.ProductService.AddFulfillmentPlaces]
  /// method.
  /// [ProductService.AddLocalInventories][google.cloud.retail.v2.ProductService.AddLocalInventories]
  /// achieves the same results but provides more fine-grained control over
  /// ingesting local inventory data.
  ///
  /// Incrementally adds place IDs to
  /// [Product.fulfillment_info.place_ids][google.cloud.retail.v2.FulfillmentInfo.place_ids].
  ///
  /// This process is asynchronous and does not require the
  /// [Product][google.cloud.retail.v2.Product] to exist before updating
  /// fulfillment information. If the request is valid, the update will be
  /// enqueued and processed downstream. As a consequence, when a response is
  /// returned, the added place IDs are not immediately manifested in the
  /// [Product][google.cloud.retail.v2.Product] queried by
  /// [ProductService.GetProduct][google.cloud.retail.v2.ProductService.GetProduct]
  /// or
  /// [ProductService.ListProducts][google.cloud.retail.v2.ProductService.ListProducts].
  ///
  /// The returned [Operation][google.longrunning.Operation]s will be obsolete
  /// after 1 day, and [GetOperation][google.longrunning.Operations.GetOperation]
  /// API will return NOT_FOUND afterwards.
  ///
  /// If conflicting updates are issued, the
  /// [Operation][google.longrunning.Operation]s associated with the stale
  /// updates will not be marked as [done][google.longrunning.Operation.done]
  /// until being obsolete.
  ///
  /// @param request Unary RPCs, such as the one wrapped by this
  ///     function, receive a single `request` proto message which includes all
  ///     the inputs for the RPC. In this case, the proto message is a
  ///     [google.cloud.retail.v2.AddFulfillmentPlacesRequest].
  ///     Proto messages are converted to C++ classes by Protobuf, using the
  ///     [Protobuf mapping rules].
  /// @param opts Optional. Override the class-level options, such as retry and
  ///     backoff policies.
  /// @return A [`future`] that becomes satisfied when the LRO
  ///     ([Long Running Operation]) completes or the polling policy in effect
  ///     for this call is exhausted. The future is satisfied with an error if
  ///     the LRO completes with an error or the polling policy is exhausted.
  ///     In this case the [`StatusOr`] returned by the future contains the
  ///     error. If the LRO completes successfully the value of the future
  ///     contains the LRO's result. For this RPC the result is a
  ///     [google.cloud.retail.v2.AddFulfillmentPlacesResponse] proto message.
  ///     The C++ class representing this message is created by Protobuf, using
  ///     the [Protobuf mapping rules].
  ///
  /// [Protobuf mapping rules]: https://protobuf.dev/reference/cpp/cpp-generated/
  /// [input iterator requirements]: https://en.cppreference.com/w/cpp/named_req/InputIterator
  /// [Long Running Operation]: https://google.aip.dev/151
  /// [`std::string`]: https://en.cppreference.com/w/cpp/string/basic_string
  /// [`future`]: @ref google::cloud::future
  /// [`StatusOr`]: @ref google::cloud::StatusOr
  /// [`Status`]: @ref google::cloud::Status
  /// [google.cloud.retail.v2.AddFulfillmentPlacesRequest]: @googleapis_reference_link{google/cloud/retail/v2/product_service.proto#L687}
  /// [google.cloud.retail.v2.AddFulfillmentPlacesResponse]: @googleapis_reference_link{google/cloud/retail/v2/product_service.proto#L763}
  /// [google.cloud.retail.v2.FulfillmentInfo.place_ids]: @googleapis_reference_link{google/cloud/retail/v2/common.proto#L614}
  /// [google.cloud.retail.v2.Product]: @googleapis_reference_link{google/cloud/retail/v2/product.proto#L43}
  /// [google.cloud.retail.v2.ProductService.AddFulfillmentPlaces]: @googleapis_reference_link{google/cloud/retail/v2/product_service.proto#L229}
  /// [google.cloud.retail.v2.ProductService.AddLocalInventories]: @googleapis_reference_link{google/cloud/retail/v2/product_service.proto#L313}
  /// [google.cloud.retail.v2.ProductService.GetProduct]: @googleapis_reference_link{google/cloud/retail/v2/product_service.proto#L58}
  /// [google.cloud.retail.v2.ProductService.ListProducts]: @googleapis_reference_link{google/cloud/retail/v2/product_service.proto#L66}
  /// [google.longrunning.Operation]: @googleapis_reference_link{google/longrunning/operations.proto#L121}
  /// [google.longrunning.Operation.done]: @googleapis_reference_link{google/longrunning/operations.proto#L136}
  /// [google.longrunning.Operations.GetOperation]: @googleapis_reference_link{google/longrunning/operations.proto#L70}
  ///
  // clang-format on
  future<StatusOr<google::cloud::retail::v2::AddFulfillmentPlacesResponse>>
  AddFulfillmentPlaces(
      google::cloud::retail::v2::AddFulfillmentPlacesRequest const& request,
      Options opts = {});

  // clang-format off
  ///
  /// @copybrief AddFulfillmentPlaces
  ///
  /// Specifying the [`NoAwaitTag`] immediately returns the
  /// [`google::longrunning::Operation`] that corresponds to the Long Running
  /// Operation that has been started. No polling for operation status occurs.
  ///
  /// [`NoAwaitTag`]: @ref google::cloud::NoAwaitTag
  ///
  // clang-format on
  StatusOr<google::longrunning::Operation> AddFulfillmentPlaces(
      NoAwaitTag,
      google::cloud::retail::v2::AddFulfillmentPlacesRequest const& request,
      Options opts = {});

  // clang-format off
  ///
  /// @copybrief AddFulfillmentPlaces
  ///
  /// This method accepts a `google::longrunning::Operation` that corresponds
  /// to a previously started Long Running Operation (LRO) and polls the status
  /// of the LRO in the background.
  ///
  // clang-format on
  future<StatusOr<google::cloud::retail::v2::AddFulfillmentPlacesResponse>>
  AddFulfillmentPlaces(google::longrunning::Operation const& operation,
                       Options opts = {});

  // clang-format off
  ///
  /// We recommend that you use the
  /// [ProductService.RemoveLocalInventories][google.cloud.retail.v2.ProductService.RemoveLocalInventories]
  /// method instead of the
  /// [ProductService.RemoveFulfillmentPlaces][google.cloud.retail.v2.ProductService.RemoveFulfillmentPlaces]
  /// method.
  /// [ProductService.RemoveLocalInventories][google.cloud.retail.v2.ProductService.RemoveLocalInventories]
  /// achieves the same results but provides more fine-grained control over
  /// ingesting local inventory data.
  ///
  /// Incrementally removes place IDs from a
  /// [Product.fulfillment_info.place_ids][google.cloud.retail.v2.FulfillmentInfo.place_ids].
  ///
  /// This process is asynchronous and does not require the
  /// [Product][google.cloud.retail.v2.Product] to exist before updating
  /// fulfillment information. If the request is valid, the update will be
  /// enqueued and processed downstream. As a consequence, when a response is
  /// returned, the removed place IDs are not immediately manifested in the
  /// [Product][google.cloud.retail.v2.Product] queried by
  /// [ProductService.GetProduct][google.cloud.retail.v2.ProductService.GetProduct]
  /// or
  /// [ProductService.ListProducts][google.cloud.retail.v2.ProductService.ListProducts].
  ///
  /// The returned [Operation][google.longrunning.Operation]s will be obsolete
  /// after 1 day, and [GetOperation][google.longrunning.Operations.GetOperation]
  /// API will return NOT_FOUND afterwards.
  ///
  /// If conflicting updates are issued, the
  /// [Operation][google.longrunning.Operation]s associated with the stale
  /// updates will not be marked as [done][google.longrunning.Operation.done]
  /// until being obsolete.
  ///
  /// @param product  Required. Full resource name of [Product][google.cloud.retail.v2.Product],
  ///  such as
  ///  `projects/*/locations/global/catalogs/default_catalog/branches/default_branch/products/some_product_id`.
  ///  @n
  ///  If the caller does not have permission to access the
  ///  [Product][google.cloud.retail.v2.Product], regardless of whether or not it
  ///  exists, a PERMISSION_DENIED error is returned.
  /// @param opts Optional. Override the class-level options, such as retry and
  ///     backoff policies.
  /// @return A [`future`] that becomes satisfied when the LRO
  ///     ([Long Running Operation]) completes or the polling policy in effect
  ///     for this call is exhausted. The future is satisfied with an error if
  ///     the LRO completes with an error or the polling policy is exhausted.
  ///     In this case the [`StatusOr`] returned by the future contains the
  ///     error. If the LRO completes successfully the value of the future
  ///     contains the LRO's result. For this RPC the result is a
  ///     [google.cloud.retail.v2.RemoveFulfillmentPlacesResponse] proto message.
  ///     The C++ class representing this message is created by Protobuf, using
  ///     the [Protobuf mapping rules].
  ///
  /// [Protobuf mapping rules]: https://protobuf.dev/reference/cpp/cpp-generated/
  /// [input iterator requirements]: https://en.cppreference.com/w/cpp/named_req/InputIterator
  /// [Long Running Operation]: https://google.aip.dev/151
  /// [`std::string`]: https://en.cppreference.com/w/cpp/string/basic_string
  /// [`future`]: @ref google::cloud::future
  /// [`StatusOr`]: @ref google::cloud::StatusOr
  /// [`Status`]: @ref google::cloud::Status
  /// [google.cloud.retail.v2.FulfillmentInfo.place_ids]: @googleapis_reference_link{google/cloud/retail/v2/common.proto#L614}
  /// [google.cloud.retail.v2.Product]: @googleapis_reference_link{google/cloud/retail/v2/product.proto#L43}
  /// [google.cloud.retail.v2.ProductService.GetProduct]: @googleapis_reference_link{google/cloud/retail/v2/product_service.proto#L58}
  /// [google.cloud.retail.v2.ProductService.ListProducts]: @googleapis_reference_link{google/cloud/retail/v2/product_service.proto#L66}
  /// [google.cloud.retail.v2.ProductService.RemoveFulfillmentPlaces]: @googleapis_reference_link{google/cloud/retail/v2/product_service.proto#L272}
  /// [google.cloud.retail.v2.ProductService.RemoveLocalInventories]: @googleapis_reference_link{google/cloud/retail/v2/product_service.proto#L352}
  /// [google.cloud.retail.v2.RemoveFulfillmentPlacesRequest]: @googleapis_reference_link{google/cloud/retail/v2/product_service.proto#L882}
  /// [google.cloud.retail.v2.RemoveFulfillmentPlacesResponse]: @googleapis_reference_link{google/cloud/retail/v2/product_service.proto#L953}
  /// [google.longrunning.Operation]: @googleapis_reference_link{google/longrunning/operations.proto#L121}
  /// [google.longrunning.Operation.done]: @googleapis_reference_link{google/longrunning/operations.proto#L136}
  /// [google.longrunning.Operations.GetOperation]: @googleapis_reference_link{google/longrunning/operations.proto#L70}
  ///
  // clang-format on
  future<StatusOr<google::cloud::retail::v2::RemoveFulfillmentPlacesResponse>>
  RemoveFulfillmentPlaces(std::string const& product, Options opts = {});

  // clang-format off
  ///
  /// @copybrief RemoveFulfillmentPlaces
  ///
  /// Specifying the [`NoAwaitTag`] immediately returns the
  /// [`google::longrunning::Operation`] that corresponds to the Long Running
  /// Operation that has been started. No polling for operation status occurs.
  ///
  /// [`NoAwaitTag`]: @ref google::cloud::NoAwaitTag
  ///
  // clang-format on
  StatusOr<google::longrunning::Operation> RemoveFulfillmentPlaces(
      NoAwaitTag, std::string const& product, Options opts = {});

  // clang-format off
  ///
  /// We recommend that you use the
  /// [ProductService.RemoveLocalInventories][google.cloud.retail.v2.ProductService.RemoveLocalInventories]
  /// method instead of the
  /// [ProductService.RemoveFulfillmentPlaces][google.cloud.retail.v2.ProductService.RemoveFulfillmentPlaces]
  /// method.
  /// [ProductService.RemoveLocalInventories][google.cloud.retail.v2.ProductService.RemoveLocalInventories]
  /// achieves the same results but provides more fine-grained control over
  /// ingesting local inventory data.
  ///
  /// Incrementally removes place IDs from a
  /// [Product.fulfillment_info.place_ids][google.cloud.retail.v2.FulfillmentInfo.place_ids].
  ///
  /// This process is asynchronous and does not require the
  /// [Product][google.cloud.retail.v2.Product] to exist before updating
  /// fulfillment information. If the request is valid, the update will be
  /// enqueued and processed downstream. As a consequence, when a response is
  /// returned, the removed place IDs are not immediately manifested in the
  /// [Product][google.cloud.retail.v2.Product] queried by
  /// [ProductService.GetProduct][google.cloud.retail.v2.ProductService.GetProduct]
  /// or
  /// [ProductService.ListProducts][google.cloud.retail.v2.ProductService.ListProducts].
  ///
  /// The returned [Operation][google.longrunning.Operation]s will be obsolete
  /// after 1 day, and [GetOperation][google.longrunning.Operations.GetOperation]
  /// API will return NOT_FOUND afterwards.
  ///
  /// If conflicting updates are issued, the
  /// [Operation][google.longrunning.Operation]s associated with the stale
  /// updates will not be marked as [done][google.longrunning.Operation.done]
  /// until being obsolete.
  ///
  /// @param request Unary RPCs, such as the one wrapped by this
  ///     function, receive a single `request` proto message which includes all
  ///     the inputs for the RPC. In this case, the proto message is a
  ///     [google.cloud.retail.v2.RemoveFulfillmentPlacesRequest].
  ///     Proto messages are converted to C++ classes by Protobuf, using the
  ///     [Protobuf mapping rules].
  /// @param opts Optional. Override the class-level options, such as retry and
  ///     backoff policies.
  /// @return A [`future`] that becomes satisfied when the LRO
  ///     ([Long Running Operation]) completes or the polling policy in effect
  ///     for this call is exhausted. The future is satisfied with an error if
  ///     the LRO completes with an error or the polling policy is exhausted.
  ///     In this case the [`StatusOr`] returned by the future contains the
  ///     error. If the LRO completes successfully the value of the future
  ///     contains the LRO's result. For this RPC the result is a
  ///     [google.cloud.retail.v2.RemoveFulfillmentPlacesResponse] proto message.
  ///     The C++ class representing this message is created by Protobuf, using
  ///     the [Protobuf mapping rules].
  ///
  /// [Protobuf mapping rules]: https://protobuf.dev/reference/cpp/cpp-generated/
  /// [input iterator requirements]: https://en.cppreference.com/w/cpp/named_req/InputIterator
  /// [Long Running Operation]: https://google.aip.dev/151
  /// [`std::string`]: https://en.cppreference.com/w/cpp/string/basic_string
  /// [`future`]: @ref google::cloud::future
  /// [`StatusOr`]: @ref google::cloud::StatusOr
  /// [`Status`]: @ref google::cloud::Status
  /// [google.cloud.retail.v2.FulfillmentInfo.place_ids]: @googleapis_reference_link{google/cloud/retail/v2/common.proto#L614}
  /// [google.cloud.retail.v2.Product]: @googleapis_reference_link{google/cloud/retail/v2/product.proto#L43}
  /// [google.cloud.retail.v2.ProductService.GetProduct]: @googleapis_reference_link{google/cloud/retail/v2/product_service.proto#L58}
  /// [google.cloud.retail.v2.ProductService.ListProducts]: @googleapis_reference_link{google/cloud/retail/v2/product_service.proto#L66}
  /// [google.cloud.retail.v2.ProductService.RemoveFulfillmentPlaces]: @googleapis_reference_link{google/cloud/retail/v2/product_service.proto#L272}
  /// [google.cloud.retail.v2.ProductService.RemoveLocalInventories]: @googleapis_reference_link{google/cloud/retail/v2/product_service.proto#L352}
  /// [google.cloud.retail.v2.RemoveFulfillmentPlacesRequest]: @googleapis_reference_link{google/cloud/retail/v2/product_service.proto#L882}
  /// [google.cloud.retail.v2.RemoveFulfillmentPlacesResponse]: @googleapis_reference_link{google/cloud/retail/v2/product_service.proto#L953}
  /// [google.longrunning.Operation]: @googleapis_reference_link{google/longrunning/operations.proto#L121}
  /// [google.longrunning.Operation.done]: @googleapis_reference_link{google/longrunning/operations.proto#L136}
  /// [google.longrunning.Operations.GetOperation]: @googleapis_reference_link{google/longrunning/operations.proto#L70}
  ///
  // clang-format on
  future<StatusOr<google::cloud::retail::v2::RemoveFulfillmentPlacesResponse>>
  RemoveFulfillmentPlaces(
      google::cloud::retail::v2::RemoveFulfillmentPlacesRequest const& request,
      Options opts = {});

  // clang-format off
  ///
  /// @copybrief RemoveFulfillmentPlaces
  ///
  /// Specifying the [`NoAwaitTag`] immediately returns the
  /// [`google::longrunning::Operation`] that corresponds to the Long Running
  /// Operation that has been started. No polling for operation status occurs.
  ///
  /// [`NoAwaitTag`]: @ref google::cloud::NoAwaitTag
  ///
  // clang-format on
  StatusOr<google::longrunning::Operation> RemoveFulfillmentPlaces(
      NoAwaitTag,
      google::cloud::retail::v2::RemoveFulfillmentPlacesRequest const& request,
      Options opts = {});

  // clang-format off
  ///
  /// @copybrief RemoveFulfillmentPlaces
  ///
  /// This method accepts a `google::longrunning::Operation` that corresponds
  /// to a previously started Long Running Operation (LRO) and polls the status
  /// of the LRO in the background.
  ///
  // clang-format on
  future<StatusOr<google::cloud::retail::v2::RemoveFulfillmentPlacesResponse>>
  RemoveFulfillmentPlaces(google::longrunning::Operation const& operation,
                          Options opts = {});

  // clang-format off
  ///
  /// Updates local inventory information for a
  /// [Product][google.cloud.retail.v2.Product] at a list of places, while
  /// respecting the last update timestamps of each inventory field.
  ///
  /// This process is asynchronous and does not require the
  /// [Product][google.cloud.retail.v2.Product] to exist before updating
  /// inventory information. If the request is valid, the update will be enqueued
  /// and processed downstream. As a consequence, when a response is returned,
  /// updates are not immediately manifested in the
  /// [Product][google.cloud.retail.v2.Product] queried by
  /// [ProductService.GetProduct][google.cloud.retail.v2.ProductService.GetProduct]
  /// or
  /// [ProductService.ListProducts][google.cloud.retail.v2.ProductService.ListProducts].
  ///
  /// Local inventory information can only be modified using this method.
  /// [ProductService.CreateProduct][google.cloud.retail.v2.ProductService.CreateProduct]
  /// and
  /// [ProductService.UpdateProduct][google.cloud.retail.v2.ProductService.UpdateProduct]
  /// has no effect on local inventories.
  ///
  /// The returned [Operation][google.longrunning.Operation]s will be obsolete
  /// after 1 day, and [GetOperation][google.longrunning.Operations.GetOperation]
  /// API will return NOT_FOUND afterwards.
  ///
  /// If conflicting updates are issued, the
  /// [Operation][google.longrunning.Operation]s associated with the stale
  /// updates will not be marked as [done][google.longrunning.Operation.done]
  /// until being obsolete.
  ///
  /// @param product  Required. Full resource name of [Product][google.cloud.retail.v2.Product],
  ///  such as
  ///  `projects/*/locations/global/catalogs/default_catalog/branches/default_branch/products/some_product_id`.
  ///  @n
  ///  If the caller does not have permission to access the
  ///  [Product][google.cloud.retail.v2.Product], regardless of whether or not it
  ///  exists, a PERMISSION_DENIED error is returned.
  /// @param opts Optional. Override the class-level options, such as retry and
  ///     backoff policies.
  /// @return A [`future`] that becomes satisfied when the LRO
  ///     ([Long Running Operation]) completes or the polling policy in effect
  ///     for this call is exhausted. The future is satisfied with an error if
  ///     the LRO completes with an error or the polling policy is exhausted.
  ///     In this case the [`StatusOr`] returned by the future contains the
  ///     error. If the LRO completes successfully the value of the future
  ///     contains the LRO's result. For this RPC the result is a
  ///     [google.cloud.retail.v2.AddLocalInventoriesResponse] proto message.
  ///     The C++ class representing this message is created by Protobuf, using
  ///     the [Protobuf mapping rules].
  ///
  /// [Protobuf mapping rules]: https://protobuf.dev/reference/cpp/cpp-generated/
  /// [input iterator requirements]: https://en.cppreference.com/w/cpp/named_req/InputIterator
  /// [Long Running Operation]: https://google.aip.dev/151
  /// [`std::string`]: https://en.cppreference.com/w/cpp/string/basic_string
  /// [`future`]: @ref google::cloud::future
  /// [`StatusOr`]: @ref google::cloud::StatusOr
  /// [`Status`]: @ref google::cloud::Status
  /// [google.cloud.retail.v2.AddLocalInventoriesRequest]: @googleapis_reference_link{google/cloud/retail/v2/product_service.proto#L768}
  /// [google.cloud.retail.v2.AddLocalInventoriesResponse]: @googleapis_reference_link{google/cloud/retail/v2/product_service.proto#L829}
  /// [google.cloud.retail.v2.Product]: @googleapis_reference_link{google/cloud/retail/v2/product.proto#L43}
  /// [google.cloud.retail.v2.ProductService.CreateProduct]: @googleapis_reference_link{google/cloud/retail/v2/product_service.proto#L49}
  /// [google.cloud.retail.v2.ProductService.GetProduct]: @googleapis_reference_link{google/cloud/retail/v2/product_service.proto#L58}
  /// [google.cloud.retail.v2.ProductService.ListProducts]: @googleapis_reference_link{google/cloud/retail/v2/product_service.proto#L66}
  /// [google.cloud.retail.v2.ProductService.UpdateProduct]: @googleapis_reference_link{google/cloud/retail/v2/product_service.proto#L74}
  /// [google.longrunning.Operation]: @googleapis_reference_link{google/longrunning/operations.proto#L121}
  /// [google.longrunning.Operation.done]: @googleapis_reference_link{google/longrunning/operations.proto#L136}
  /// [google.longrunning.Operations.GetOperation]: @googleapis_reference_link{google/longrunning/operations.proto#L70}
  ///
  // clang-format on
  future<StatusOr<google::cloud::retail::v2::AddLocalInventoriesResponse>>
  AddLocalInventories(std::string const& product, Options opts = {});

  // clang-format off
  ///
  /// @copybrief AddLocalInventories
  ///
  /// Specifying the [`NoAwaitTag`] immediately returns the
  /// [`google::longrunning::Operation`] that corresponds to the Long Running
  /// Operation that has been started. No polling for operation status occurs.
  ///
  /// [`NoAwaitTag`]: @ref google::cloud::NoAwaitTag
  ///
  // clang-format on
  StatusOr<google::longrunning::Operation> AddLocalInventories(
      NoAwaitTag, std::string const& product, Options opts = {});

  // clang-format off
  ///
  /// Updates local inventory information for a
  /// [Product][google.cloud.retail.v2.Product] at a list of places, while
  /// respecting the last update timestamps of each inventory field.
  ///
  /// This process is asynchronous and does not require the
  /// [Product][google.cloud.retail.v2.Product] to exist before updating
  /// inventory information. If the request is valid, the update will be enqueued
  /// and processed downstream. As a consequence, when a response is returned,
  /// updates are not immediately manifested in the
  /// [Product][google.cloud.retail.v2.Product] queried by
  /// [ProductService.GetProduct][google.cloud.retail.v2.ProductService.GetProduct]
  /// or
  /// [ProductService.ListProducts][google.cloud.retail.v2.ProductService.ListProducts].
  ///
  /// Local inventory information can only be modified using this method.
  /// [ProductService.CreateProduct][google.cloud.retail.v2.ProductService.CreateProduct]
  /// and
  /// [ProductService.UpdateProduct][google.cloud.retail.v2.ProductService.UpdateProduct]
  /// has no effect on local inventories.
  ///
  /// The returned [Operation][google.longrunning.Operation]s will be obsolete
  /// after 1 day, and [GetOperation][google.longrunning.Operations.GetOperation]
  /// API will return NOT_FOUND afterwards.
  ///
  /// If conflicting updates are issued, the
  /// [Operation][google.longrunning.Operation]s associated with the stale
  /// updates will not be marked as [done][google.longrunning.Operation.done]
  /// until being obsolete.
  ///
  /// @param request Unary RPCs, such as the one wrapped by this
  ///     function, receive a single `request` proto message which includes all
  ///     the inputs for the RPC. In this case, the proto message is a
  ///     [google.cloud.retail.v2.AddLocalInventoriesRequest].
  ///     Proto messages are converted to C++ classes by Protobuf, using the
  ///     [Protobuf mapping rules].
  /// @param opts Optional. Override the class-level options, such as retry and
  ///     backoff policies.
  /// @return A [`future`] that becomes satisfied when the LRO
  ///     ([Long Running Operation]) completes or the polling policy in effect
  ///     for this call is exhausted. The future is satisfied with an error if
  ///     the LRO completes with an error or the polling policy is exhausted.
  ///     In this case the [`StatusOr`] returned by the future contains the
  ///     error. If the LRO completes successfully the value of the future
  ///     contains the LRO's result. For this RPC the result is a
  ///     [google.cloud.retail.v2.AddLocalInventoriesResponse] proto message.
  ///     The C++ class representing this message is created by Protobuf, using
  ///     the [Protobuf mapping rules].
  ///
  /// [Protobuf mapping rules]: https://protobuf.dev/reference/cpp/cpp-generated/
  /// [input iterator requirements]: https://en.cppreference.com/w/cpp/named_req/InputIterator
  /// [Long Running Operation]: https://google.aip.dev/151
  /// [`std::string`]: https://en.cppreference.com/w/cpp/string/basic_string
  /// [`future`]: @ref google::cloud::future
  /// [`StatusOr`]: @ref google::cloud::StatusOr
  /// [`Status`]: @ref google::cloud::Status
  /// [google.cloud.retail.v2.AddLocalInventoriesRequest]: @googleapis_reference_link{google/cloud/retail/v2/product_service.proto#L768}
  /// [google.cloud.retail.v2.AddLocalInventoriesResponse]: @googleapis_reference_link{google/cloud/retail/v2/product_service.proto#L829}
  /// [google.cloud.retail.v2.Product]: @googleapis_reference_link{google/cloud/retail/v2/product.proto#L43}
  /// [google.cloud.retail.v2.ProductService.CreateProduct]: @googleapis_reference_link{google/cloud/retail/v2/product_service.proto#L49}
  /// [google.cloud.retail.v2.ProductService.GetProduct]: @googleapis_reference_link{google/cloud/retail/v2/product_service.proto#L58}
  /// [google.cloud.retail.v2.ProductService.ListProducts]: @googleapis_reference_link{google/cloud/retail/v2/product_service.proto#L66}
  /// [google.cloud.retail.v2.ProductService.UpdateProduct]: @googleapis_reference_link{google/cloud/retail/v2/product_service.proto#L74}
  /// [google.longrunning.Operation]: @googleapis_reference_link{google/longrunning/operations.proto#L121}
  /// [google.longrunning.Operation.done]: @googleapis_reference_link{google/longrunning/operations.proto#L136}
  /// [google.longrunning.Operations.GetOperation]: @googleapis_reference_link{google/longrunning/operations.proto#L70}
  ///
  // clang-format on
  future<StatusOr<google::cloud::retail::v2::AddLocalInventoriesResponse>>
  AddLocalInventories(
      google::cloud::retail::v2::AddLocalInventoriesRequest const& request,
      Options opts = {});

  // clang-format off
  ///
  /// @copybrief AddLocalInventories
  ///
  /// Specifying the [`NoAwaitTag`] immediately returns the
  /// [`google::longrunning::Operation`] that corresponds to the Long Running
  /// Operation that has been started. No polling for operation status occurs.
  ///
  /// [`NoAwaitTag`]: @ref google::cloud::NoAwaitTag
  ///
  // clang-format on
  StatusOr<google::longrunning::Operation> AddLocalInventories(
      NoAwaitTag,
      google::cloud::retail::v2::AddLocalInventoriesRequest const& request,
      Options opts = {});

  // clang-format off
  ///
  /// @copybrief AddLocalInventories
  ///
  /// This method accepts a `google::longrunning::Operation` that corresponds
  /// to a previously started Long Running Operation (LRO) and polls the status
  /// of the LRO in the background.
  ///
  // clang-format on
  future<StatusOr<google::cloud::retail::v2::AddLocalInventoriesResponse>>
  AddLocalInventories(google::longrunning::Operation const& operation,
                      Options opts = {});

  // clang-format off
  ///
  /// Remove local inventory information for a
  /// [Product][google.cloud.retail.v2.Product] at a list of places at a removal
  /// timestamp.
  ///
  /// This process is asynchronous. If the request is valid, the removal will be
  /// enqueued and processed downstream. As a consequence, when a response is
  /// returned, removals are not immediately manifested in the
  /// [Product][google.cloud.retail.v2.Product] queried by
  /// [ProductService.GetProduct][google.cloud.retail.v2.ProductService.GetProduct]
  /// or
  /// [ProductService.ListProducts][google.cloud.retail.v2.ProductService.ListProducts].
  ///
  /// Local inventory information can only be removed using this method.
  /// [ProductService.CreateProduct][google.cloud.retail.v2.ProductService.CreateProduct]
  /// and
  /// [ProductService.UpdateProduct][google.cloud.retail.v2.ProductService.UpdateProduct]
  /// has no effect on local inventories.
  ///
  /// The returned [Operation][google.longrunning.Operation]s will be obsolete
  /// after 1 day, and [GetOperation][google.longrunning.Operations.GetOperation]
  /// API will return NOT_FOUND afterwards.
  ///
  /// If conflicting updates are issued, the
  /// [Operation][google.longrunning.Operation]s associated with the stale
  /// updates will not be marked as [done][google.longrunning.Operation.done]
  /// until being obsolete.
  ///
  /// @param product  Required. Full resource name of [Product][google.cloud.retail.v2.Product],
  ///  such as
  ///  `projects/*/locations/global/catalogs/default_catalog/branches/default_branch/products/some_product_id`.
  ///  @n
  ///  If the caller does not have permission to access the
  ///  [Product][google.cloud.retail.v2.Product], regardless of whether or not it
  ///  exists, a PERMISSION_DENIED error is returned.
  /// @param opts Optional. Override the class-level options, such as retry and
  ///     backoff policies.
  /// @return A [`future`] that becomes satisfied when the LRO
  ///     ([Long Running Operation]) completes or the polling policy in effect
  ///     for this call is exhausted. The future is satisfied with an error if
  ///     the LRO completes with an error or the polling policy is exhausted.
  ///     In this case the [`StatusOr`] returned by the future contains the
  ///     error. If the LRO completes successfully the value of the future
  ///     contains the LRO's result. For this RPC the result is a
  ///     [google.cloud.retail.v2.RemoveLocalInventoriesResponse] proto message.
  ///     The C++ class representing this message is created by Protobuf, using
  ///     the [Protobuf mapping rules].
  ///
  /// [Protobuf mapping rules]: https://protobuf.dev/reference/cpp/cpp-generated/
  /// [input iterator requirements]: https://en.cppreference.com/w/cpp/named_req/InputIterator
  /// [Long Running Operation]: https://google.aip.dev/151
  /// [`std::string`]: https://en.cppreference.com/w/cpp/string/basic_string
  /// [`future`]: @ref google::cloud::future
  /// [`StatusOr`]: @ref google::cloud::StatusOr
  /// [`Status`]: @ref google::cloud::Status
  /// [google.cloud.retail.v2.Product]: @googleapis_reference_link{google/cloud/retail/v2/product.proto#L43}
  /// [google.cloud.retail.v2.ProductService.CreateProduct]: @googleapis_reference_link{google/cloud/retail/v2/product_service.proto#L49}
  /// [google.cloud.retail.v2.ProductService.GetProduct]: @googleapis_reference_link{google/cloud/retail/v2/product_service.proto#L58}
  /// [google.cloud.retail.v2.ProductService.ListProducts]: @googleapis_reference_link{google/cloud/retail/v2/product_service.proto#L66}
  /// [google.cloud.retail.v2.ProductService.UpdateProduct]: @googleapis_reference_link{google/cloud/retail/v2/product_service.proto#L74}
  /// [google.cloud.retail.v2.RemoveLocalInventoriesRequest]: @googleapis_reference_link{google/cloud/retail/v2/product_service.proto#L834}
  /// [google.cloud.retail.v2.RemoveLocalInventoriesResponse]: @googleapis_reference_link{google/cloud/retail/v2/product_service.proto#L877}
  /// [google.longrunning.Operation]: @googleapis_reference_link{google/longrunning/operations.proto#L121}
  /// [google.longrunning.Operation.done]: @googleapis_reference_link{google/longrunning/operations.proto#L136}
  /// [google.longrunning.Operations.GetOperation]: @googleapis_reference_link{google/longrunning/operations.proto#L70}
  ///
  // clang-format on
  future<StatusOr<google::cloud::retail::v2::RemoveLocalInventoriesResponse>>
  RemoveLocalInventories(std::string const& product, Options opts = {});

  // clang-format off
  ///
  /// @copybrief RemoveLocalInventories
  ///
  /// Specifying the [`NoAwaitTag`] immediately returns the
  /// [`google::longrunning::Operation`] that corresponds to the Long Running
  /// Operation that has been started. No polling for operation status occurs.
  ///
  /// [`NoAwaitTag`]: @ref google::cloud::NoAwaitTag
  ///
  // clang-format on
  StatusOr<google::longrunning::Operation> RemoveLocalInventories(
      NoAwaitTag, std::string const& product, Options opts = {});

  // clang-format off
  ///
  /// Remove local inventory information for a
  /// [Product][google.cloud.retail.v2.Product] at a list of places at a removal
  /// timestamp.
  ///
  /// This process is asynchronous. If the request is valid, the removal will be
  /// enqueued and processed downstream. As a consequence, when a response is
  /// returned, removals are not immediately manifested in the
  /// [Product][google.cloud.retail.v2.Product] queried by
  /// [ProductService.GetProduct][google.cloud.retail.v2.ProductService.GetProduct]
  /// or
  /// [ProductService.ListProducts][google.cloud.retail.v2.ProductService.ListProducts].
  ///
  /// Local inventory information can only be removed using this method.
  /// [ProductService.CreateProduct][google.cloud.retail.v2.ProductService.CreateProduct]
  /// and
  /// [ProductService.UpdateProduct][google.cloud.retail.v2.ProductService.UpdateProduct]
  /// has no effect on local inventories.
  ///
  /// The returned [Operation][google.longrunning.Operation]s will be obsolete
  /// after 1 day, and [GetOperation][google.longrunning.Operations.GetOperation]
  /// API will return NOT_FOUND afterwards.
  ///
  /// If conflicting updates are issued, the
  /// [Operation][google.longrunning.Operation]s associated with the stale
  /// updates will not be marked as [done][google.longrunning.Operation.done]
  /// until being obsolete.
  ///
  /// @param request Unary RPCs, such as the one wrapped by this
  ///     function, receive a single `request` proto message which includes all
  ///     the inputs for the RPC. In this case, the proto message is a
  ///     [google.cloud.retail.v2.RemoveLocalInventoriesRequest].
  ///     Proto messages are converted to C++ classes by Protobuf, using the
  ///     [Protobuf mapping rules].
  /// @param opts Optional. Override the class-level options, such as retry and
  ///     backoff policies.
  /// @return A [`future`] that becomes satisfied when the LRO
  ///     ([Long Running Operation]) completes or the polling policy in effect
  ///     for this call is exhausted. The future is satisfied with an error if
  ///     the LRO completes with an error or the polling policy is exhausted.
  ///     In this case the [`StatusOr`] returned by the future contains the
  ///     error. If the LRO completes successfully the value of the future
  ///     contains the LRO's result. For this RPC the result is a
  ///     [google.cloud.retail.v2.RemoveLocalInventoriesResponse] proto message.
  ///     The C++ class representing this message is created by Protobuf, using
  ///     the [Protobuf mapping rules].
  ///
  /// [Protobuf mapping rules]: https://protobuf.dev/reference/cpp/cpp-generated/
  /// [input iterator requirements]: https://en.cppreference.com/w/cpp/named_req/InputIterator
  /// [Long Running Operation]: https://google.aip.dev/151
  /// [`std::string`]: https://en.cppreference.com/w/cpp/string/basic_string
  /// [`future`]: @ref google::cloud::future
  /// [`StatusOr`]: @ref google::cloud::StatusOr
  /// [`Status`]: @ref google::cloud::Status
  /// [google.cloud.retail.v2.Product]: @googleapis_reference_link{google/cloud/retail/v2/product.proto#L43}
  /// [google.cloud.retail.v2.ProductService.CreateProduct]: @googleapis_reference_link{google/cloud/retail/v2/product_service.proto#L49}
  /// [google.cloud.retail.v2.ProductService.GetProduct]: @googleapis_reference_link{google/cloud/retail/v2/product_service.proto#L58}
  /// [google.cloud.retail.v2.ProductService.ListProducts]: @googleapis_reference_link{google/cloud/retail/v2/product_service.proto#L66}
  /// [google.cloud.retail.v2.ProductService.UpdateProduct]: @googleapis_reference_link{google/cloud/retail/v2/product_service.proto#L74}
  /// [google.cloud.retail.v2.RemoveLocalInventoriesRequest]: @googleapis_reference_link{google/cloud/retail/v2/product_service.proto#L834}
  /// [google.cloud.retail.v2.RemoveLocalInventoriesResponse]: @googleapis_reference_link{google/cloud/retail/v2/product_service.proto#L877}
  /// [google.longrunning.Operation]: @googleapis_reference_link{google/longrunning/operations.proto#L121}
  /// [google.longrunning.Operation.done]: @googleapis_reference_link{google/longrunning/operations.proto#L136}
  /// [google.longrunning.Operations.GetOperation]: @googleapis_reference_link{google/longrunning/operations.proto#L70}
  ///
  // clang-format on
  future<StatusOr<google::cloud::retail::v2::RemoveLocalInventoriesResponse>>
  RemoveLocalInventories(
      google::cloud::retail::v2::RemoveLocalInventoriesRequest const& request,
      Options opts = {});

  // clang-format off
  ///
  /// @copybrief RemoveLocalInventories
  ///
  /// Specifying the [`NoAwaitTag`] immediately returns the
  /// [`google::longrunning::Operation`] that corresponds to the Long Running
  /// Operation that has been started. No polling for operation status occurs.
  ///
  /// [`NoAwaitTag`]: @ref google::cloud::NoAwaitTag
  ///
  // clang-format on
  StatusOr<google::longrunning::Operation> RemoveLocalInventories(
      NoAwaitTag,
      google::cloud::retail::v2::RemoveLocalInventoriesRequest const& request,
      Options opts = {});

  // clang-format off
  ///
  /// @copybrief RemoveLocalInventories
  ///
  /// This method accepts a `google::longrunning::Operation` that corresponds
  /// to a previously started Long Running Operation (LRO) and polls the status
  /// of the LRO in the background.
  ///
  // clang-format on
  future<StatusOr<google::cloud::retail::v2::RemoveLocalInventoriesResponse>>
  RemoveLocalInventories(google::longrunning::Operation const& operation,
                         Options opts = {});

  // clang-format off
  ///
  /// Lists operations that match the specified filter in the request. If the
  /// server doesn't support this method, it returns `UNIMPLEMENTED`.
  ///
  /// @param name  The name of the operation's parent resource.
  /// @param filter  The standard list filter.
  /// @param opts Optional. Override the class-level options, such as retry and
  ///     backoff policies.
  /// @return a [StreamRange](@ref google::cloud::StreamRange)
  ///     to iterate of the results. See the documentation of this type for
  ///     details. In brief, this class has `begin()` and `end()` member
  ///     functions returning a iterator class meeting the
  ///     [input iterator requirements]. The value type for this iterator is a
  ///     [`StatusOr`] as the iteration may fail even after some values are
  ///     retrieved successfully, for example, if there is a network disconnect.
  ///     An empty set of results does not indicate an error, it indicates
  ///     that there are no resources meeting the request criteria.
  ///     On a successful iteration the `StatusOr<T>` contains elements of type
  ///     [google.longrunning.Operation], or rather,
  ///     the C++ class generated by Protobuf from that type. Please consult the
  ///     Protobuf documentation for details on the [Protobuf mapping rules].
  ///
  /// [Protobuf mapping rules]: https://protobuf.dev/reference/cpp/cpp-generated/
  /// [input iterator requirements]: https://en.cppreference.com/w/cpp/named_req/InputIterator
  /// [`std::string`]: https://en.cppreference.com/w/cpp/string/basic_string
  /// [`future`]: @ref google::cloud::future
  /// [`StatusOr`]: @ref google::cloud::StatusOr
  /// [`Status`]: @ref google::cloud::Status
  /// [google.longrunning.ListOperationsRequest]: @googleapis_reference_link{google/longrunning/operations.proto#L167}
  /// [google.longrunning.Operation]: @googleapis_reference_link{google/longrunning/operations.proto#L121}
  ///
  // clang-format on
  StreamRange<google::longrunning::Operation> ListOperations(
      std::string const& name, std::string const& filter, Options opts = {});

  // clang-format off
  ///
  /// Lists operations that match the specified filter in the request. If the
  /// server doesn't support this method, it returns `UNIMPLEMENTED`.
  ///
  /// @param request Unary RPCs, such as the one wrapped by this
  ///     function, receive a single `request` proto message which includes all
  ///     the inputs for the RPC. In this case, the proto message is a
  ///     [google.longrunning.ListOperationsRequest].
  ///     Proto messages are converted to C++ classes by Protobuf, using the
  ///     [Protobuf mapping rules].
  /// @param opts Optional. Override the class-level options, such as retry and
  ///     backoff policies.
  /// @return a [StreamRange](@ref google::cloud::StreamRange)
  ///     to iterate of the results. See the documentation of this type for
  ///     details. In brief, this class has `begin()` and `end()` member
  ///     functions returning a iterator class meeting the
  ///     [input iterator requirements]. The value type for this iterator is a
  ///     [`StatusOr`] as the iteration may fail even after some values are
  ///     retrieved successfully, for example, if there is a network disconnect.
  ///     An empty set of results does not indicate an error, it indicates
  ///     that there are no resources meeting the request criteria.
  ///     On a successful iteration the `StatusOr<T>` contains elements of type
  ///     [google.longrunning.Operation], or rather,
  ///     the C++ class generated by Protobuf from that type. Please consult the
  ///     Protobuf documentation for details on the [Protobuf mapping rules].
  ///
  /// [Protobuf mapping rules]: https://protobuf.dev/reference/cpp/cpp-generated/
  /// [input iterator requirements]: https://en.cppreference.com/w/cpp/named_req/InputIterator
  /// [`std::string`]: https://en.cppreference.com/w/cpp/string/basic_string
  /// [`future`]: @ref google::cloud::future
  /// [`StatusOr`]: @ref google::cloud::StatusOr
  /// [`Status`]: @ref google::cloud::Status
  /// [google.longrunning.ListOperationsRequest]: @googleapis_reference_link{google/longrunning/operations.proto#L167}
  /// [google.longrunning.Operation]: @googleapis_reference_link{google/longrunning/operations.proto#L121}
  ///
  // clang-format on
  StreamRange<google::longrunning::Operation> ListOperations(
      google::longrunning::ListOperationsRequest request, Options opts = {});

  // clang-format off
  ///
  /// Gets the latest state of a long-running operation.  Clients can use this
  /// method to poll the operation result at intervals as recommended by the API
  /// service.
  ///
  /// @param name  The name of the operation resource.
  /// @param opts Optional. Override the class-level options, such as retry and
  ///     backoff policies.
  /// @return the result of the RPC. The response message type
  ///     ([google.longrunning.Operation])
  ///     is mapped to a C++ class using the [Protobuf mapping rules].
  ///     If the request fails, the [`StatusOr`] contains the error details.
  ///
  /// [Protobuf mapping rules]: https://protobuf.dev/reference/cpp/cpp-generated/
  /// [input iterator requirements]: https://en.cppreference.com/w/cpp/named_req/InputIterator
  /// [`std::string`]: https://en.cppreference.com/w/cpp/string/basic_string
  /// [`future`]: @ref google::cloud::future
  /// [`StatusOr`]: @ref google::cloud::StatusOr
  /// [`Status`]: @ref google::cloud::Status
  /// [google.longrunning.GetOperationRequest]: @googleapis_reference_link{google/longrunning/operations.proto#L160}
  /// [google.longrunning.Operation]: @googleapis_reference_link{google/longrunning/operations.proto#L121}
  ///
  // clang-format on
  StatusOr<google::longrunning::Operation> GetOperation(std::string const& name,
                                                        Options opts = {});

  // clang-format off
  ///
  /// Gets the latest state of a long-running operation.  Clients can use this
  /// method to poll the operation result at intervals as recommended by the API
  /// service.
  ///
  /// @param request Unary RPCs, such as the one wrapped by this
  ///     function, receive a single `request` proto message which includes all
  ///     the inputs for the RPC. In this case, the proto message is a
  ///     [google.longrunning.GetOperationRequest].
  ///     Proto messages are converted to C++ classes by Protobuf, using the
  ///     [Protobuf mapping rules].
  /// @param opts Optional. Override the class-level options, such as retry and
  ///     backoff policies.
  /// @return the result of the RPC. The response message type
  ///     ([google.longrunning.Operation])
  ///     is mapped to a C++ class using the [Protobuf mapping rules].
  ///     If the request fails, the [`StatusOr`] contains the error details.
  ///
  /// [Protobuf mapping rules]: https://protobuf.dev/reference/cpp/cpp-generated/
  /// [input iterator requirements]: https://en.cppreference.com/w/cpp/named_req/InputIterator
  /// [`std::string`]: https://en.cppreference.com/w/cpp/string/basic_string
  /// [`future`]: @ref google::cloud::future
  /// [`StatusOr`]: @ref google::cloud::StatusOr
  /// [`Status`]: @ref google::cloud::Status
  /// [google.longrunning.GetOperationRequest]: @googleapis_reference_link{google/longrunning/operations.proto#L160}
  /// [google.longrunning.Operation]: @googleapis_reference_link{google/longrunning/operations.proto#L121}
  ///
  // clang-format on
  StatusOr<google::longrunning::Operation> GetOperation(
      google::longrunning::GetOperationRequest const& request,
      Options opts = {});

 private:
  std::shared_ptr<ProductServiceConnection> connection_;
  Options options_;
};

GOOGLE_CLOUD_CPP_INLINE_NAMESPACE_END
}  // namespace retail_v2
}  // namespace cloud
}  // namespace google

#endif  // GOOGLE_CLOUD_CPP_GOOGLE_CLOUD_RETAIL_V2_PRODUCT_CLIENT_H
