Skip to content
Open
24 changes: 24 additions & 0 deletions generator/internal/discovery_type_vertex.cc
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@
#include "google/cloud/internal/algorithm.h"
#include "google/cloud/internal/make_status.h"
#include "google/cloud/log.h"
#include "absl/strings/ascii.h"
#include "absl/strings/match.h"
#include "absl/strings/str_format.h"
#include "absl/strings/str_join.h"
#include "absl/strings/str_replace.h"
Expand All @@ -43,6 +45,22 @@ std::optional<std::string> CheckForScalarType(nlohmann::json const& j) {
return std::nullopt;
}

bool IsStringOrBytes(nlohmann::json const& field_json) {
std::string const type = field_json.value("type", "");
if (type == "string" || type == "bytes") return true;
if (type == "array" && field_json.contains("items")) {
std::string const item_type = field_json["items"].value("type", "");
if (item_type == "string" || item_type == "bytes") return true;
}
return false;
}

bool ContainsKeyWord(std::string_view s) {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Prefer using string matching functions from absl (e.g. StrContains) and the absl Suffix/Prefix functions instead of std::string::find and iterators directly.

auto const tokens = absl::StrSplit(s, '_');
return std::any_of(tokens.begin(), tokens.end(),
[](absl::string_view token) { return token == "key"; });
}

} // namespace

DiscoveryTypeVertex::DiscoveryTypeVertex(
Expand Down Expand Up @@ -495,6 +513,10 @@ std::string DiscoveryTypeVertex::FormatFieldOptions(
absl::StrCat("\"", field_name, "\""));
}

if (IsStringOrBytes(field_json) && ContainsKeyWord(field_name)) {
field_options.emplace_back("debug_redact", "true");
}

// Discovery doc defined field names that are not always in strict
// camelCase, leading to translation issue between json and protobuf. Thus,
// the emitted proto fields need to have their name as it appears in the
Expand All @@ -512,6 +534,8 @@ std::string DiscoveryTypeVertex::FormatFieldOptions(
std::pair<std::string, std::string> const& p) {
if (p.first == "json_name") {
*s += absl::StrFormat("%s=\"%s\"", p.first, p.second);
} else if (p.first == "debug_redact") {
*s += absl::StrFormat("%s = %s", p.first, p.second);
} else {
*s += absl::StrFormat("(%s) = %s", p.first, p.second);
}
Expand Down
146 changes: 146 additions & 0 deletions generator/internal/discovery_type_vertex_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -182,6 +182,111 @@ TEST(DiscoveryTypeVertexTest, FormatFieldOptionsRequiredIsResource) {
"REQUIRED,json_name=\"__json_request_body\"]"));
}

TEST(DiscoveryTypeVertexTest, FormatFieldOptionsDebugRedactString) {
auto constexpr kFieldJson = R"""(
{
"type": "string"
}
)""";
auto json = nlohmann::json::parse(kFieldJson, nullptr, false);
ASSERT_TRUE(json.is_object());
EXPECT_THAT(
DiscoveryTypeVertex::FormatFieldOptions("raw_key", "rawKey", json),
Eq(" [debug_redact = true,json_name=\"rawKey\"]"));
}

TEST(DiscoveryTypeVertexTest, FormatFieldOptionsDebugRedactBytes) {
auto constexpr kFieldJson = R"""(
{
"type": "bytes"
}
)""";
auto json = nlohmann::json::parse(kFieldJson, nullptr, false);
ASSERT_TRUE(json.is_object());
EXPECT_THAT(
DiscoveryTypeVertex::FormatFieldOptions("raw_key", "rawKey", json),
Eq(" [debug_redact = true,json_name=\"rawKey\"]"));
}

TEST(DiscoveryTypeVertexTest, FormatFieldOptionsDebugRedactArrayString) {
auto constexpr kFieldJson = R"""(
{
"type": "array",
"items": {
"type": "string"
}
}
)""";
auto json = nlohmann::json::parse(kFieldJson, nullptr, false);
ASSERT_TRUE(json.is_object());
EXPECT_THAT(
DiscoveryTypeVertex::FormatFieldOptions("raw_key", "rawKey", json),
Eq(" [debug_redact = true,json_name=\"rawKey\"]"));
}

TEST(DiscoveryTypeVertexTest, FormatFieldOptionsDebugRedactArrayBytes) {
auto constexpr kFieldJson = R"""(
{
"type": "array",
"items": {
"type": "bytes"
}
}
)""";
auto json = nlohmann::json::parse(kFieldJson, nullptr, false);
ASSERT_TRUE(json.is_object());
EXPECT_THAT(
DiscoveryTypeVertex::FormatFieldOptions("raw_key", "rawKey", json),
Eq(" [debug_redact = true,json_name=\"rawKey\"]"));
}

TEST(DiscoveryTypeVertexTest, FormatFieldOptionsDebugRedactNonMatches) {
auto constexpr kFieldJson = R"""(
{
"type": "string"
}
)""";
auto json = nlohmann::json::parse(kFieldJson, nullptr, false);
ASSERT_TRUE(json.is_object());
EXPECT_THAT(DiscoveryTypeVertex::FormatFieldOptions("monkey", "monkey", json),
Eq(" [json_name=\"monkey\"]"));
EXPECT_THAT(
DiscoveryTypeVertex::FormatFieldOptions("keyboard", "keyboard", json),
Eq(" [json_name=\"keyboard\"]"));
EXPECT_THAT(DiscoveryTypeVertex::FormatFieldOptions("hockey", "hockey", json),
Eq(" [json_name=\"hockey\"]"));
EXPECT_THAT(DiscoveryTypeVertex::FormatFieldOptions("keypad", "keypad", json),
Eq(" [json_name=\"keypad\"]"));
}

TEST(DiscoveryTypeVertexTest,
FormatFieldOptionsDebugRedactNonStringNotRedacted) {
auto constexpr kFieldJson = R"""(
{
"type": "integer"
}
)""";
auto json = nlohmann::json::parse(kFieldJson, nullptr, false);
ASSERT_TRUE(json.is_object());
EXPECT_THAT(DiscoveryTypeVertex::FormatFieldOptions("key_id", "keyId", json),
Eq(" [json_name=\"keyId\"]"));
}

TEST(DiscoveryTypeVertexTest, FormatFieldOptionsDebugRedactRequired) {
auto constexpr kFieldJson = R"""(
{
"type": "string",
"required": true
}
)""";
auto json = nlohmann::json::parse(kFieldJson, nullptr, false);
ASSERT_TRUE(json.is_object());
EXPECT_THAT(
DiscoveryTypeVertex::FormatFieldOptions("raw_key", "rawKey", json),
Eq(" [(google.api.field_behavior) = "
"REQUIRED,debug_redact = true,json_name=\"rawKey\"]"));
}

struct DetermineTypesSuccess {
std::string name;
std::string json;
Expand Down Expand Up @@ -1312,6 +1417,47 @@ message TestSchema {
"optional string to: optional double")));
}

TEST_F(DiscoveryTypeVertexDescriptorTest, JsonToProtobufCustomerEncryptionKey) {
auto constexpr kSchemaJson = R"""(
{
"id": "CustomerEncryptionKey",
"properties": {
"kmsKeyName": {
"type": "string"
},
"rawKey": {
"type": "string"
},
"rsaEncryptedKey": {
"type": "string"
},
"sha256": {
"type": "string"
}
}
}
)""";

auto constexpr kExpectedProto = R"""(message CustomerEncryptionKey {
optional string kms_key_name = 1 [debug_redact = true,json_name="kmsKeyName"];

optional string raw_key = 2 [debug_redact = true,json_name="rawKey"];

optional string rsa_encrypted_key = 3 [debug_redact = true,json_name="rsaEncryptedKey"];

optional string sha256 = 4 [json_name="sha256"];
}
)""";

auto json = nlohmann::json::parse(kSchemaJson, nullptr, false);
ASSERT_TRUE(json.is_object());
DiscoveryTypeVertex t("CustomerEncryptionKey", "test.package", json, &pool());
std::map<std::string, DiscoveryTypeVertex> types;
auto result = t.JsonToProtobufMessage(types, "test.package");
ASSERT_THAT(result, ::google::cloud::testing_util::IsOk());
EXPECT_THAT(*result, Eq(kExpectedProto));
}

} // namespace
} // namespace generator_internal
} // namespace cloud
Expand Down
40 changes: 20 additions & 20 deletions google/cloud/compute/backend_buckets/v1/backend_buckets_client.h
Original file line number Diff line number Diff line change
Expand Up @@ -565,7 +565,7 @@ class BackendBucketsClient {
/// [`future`]: @ref google::cloud::future
/// [`StatusOr`]: @ref google::cloud::StatusOr
/// [`Status`]: @ref google::cloud::Status
/// [google.cloud.cpp.compute.backend_buckets.v1.GetBackendBucketRequest]: @cloud_cpp_reference_link{google/cloud/compute/backend_buckets/v1/backend_buckets.proto#L435}
/// [google.cloud.cpp.compute.backend_buckets.v1.GetBackendBucketRequest]: @cloud_cpp_reference_link{google/cloud/compute/backend_buckets/v1/backend_buckets.proto#L438}
/// [google.cloud.cpp.compute.v1.BackendBucket]: @cloud_cpp_reference_link{google/cloud/compute/v1/internal/common_012.proto#L28}
///
// clang-format on
Expand Down Expand Up @@ -597,7 +597,7 @@ class BackendBucketsClient {
/// [`future`]: @ref google::cloud::future
/// [`StatusOr`]: @ref google::cloud::StatusOr
/// [`Status`]: @ref google::cloud::Status
/// [google.cloud.cpp.compute.backend_buckets.v1.GetBackendBucketRequest]: @cloud_cpp_reference_link{google/cloud/compute/backend_buckets/v1/backend_buckets.proto#L435}
/// [google.cloud.cpp.compute.backend_buckets.v1.GetBackendBucketRequest]: @cloud_cpp_reference_link{google/cloud/compute/backend_buckets/v1/backend_buckets.proto#L438}
/// [google.cloud.cpp.compute.v1.BackendBucket]: @cloud_cpp_reference_link{google/cloud/compute/v1/internal/common_012.proto#L28}
///
// clang-format on
Expand Down Expand Up @@ -627,7 +627,7 @@ class BackendBucketsClient {
/// [`future`]: @ref google::cloud::future
/// [`StatusOr`]: @ref google::cloud::StatusOr
/// [`Status`]: @ref google::cloud::Status
/// [google.cloud.cpp.compute.backend_buckets.v1.GetIamPolicyRequest]: @cloud_cpp_reference_link{google/cloud/compute/backend_buckets/v1/backend_buckets.proto#L446}
/// [google.cloud.cpp.compute.backend_buckets.v1.GetIamPolicyRequest]: @cloud_cpp_reference_link{google/cloud/compute/backend_buckets/v1/backend_buckets.proto#L449}
/// [google.cloud.cpp.compute.v1.Policy]: @cloud_cpp_reference_link{google/cloud/compute/v1/internal/common_009.proto#L317}
///
// clang-format on
Expand Down Expand Up @@ -660,7 +660,7 @@ class BackendBucketsClient {
/// [`future`]: @ref google::cloud::future
/// [`StatusOr`]: @ref google::cloud::StatusOr
/// [`Status`]: @ref google::cloud::Status
/// [google.cloud.cpp.compute.backend_buckets.v1.GetIamPolicyRequest]: @cloud_cpp_reference_link{google/cloud/compute/backend_buckets/v1/backend_buckets.proto#L446}
/// [google.cloud.cpp.compute.backend_buckets.v1.GetIamPolicyRequest]: @cloud_cpp_reference_link{google/cloud/compute/backend_buckets/v1/backend_buckets.proto#L449}
/// [google.cloud.cpp.compute.v1.Policy]: @cloud_cpp_reference_link{google/cloud/compute/v1/internal/common_009.proto#L317}
///
// clang-format on
Expand Down Expand Up @@ -697,7 +697,7 @@ class BackendBucketsClient {
/// [`future`]: @ref google::cloud::future
/// [`StatusOr`]: @ref google::cloud::StatusOr
/// [`Status`]: @ref google::cloud::Status
/// [google.cloud.cpp.compute.backend_buckets.v1.InsertBackendBucketRequest]: @cloud_cpp_reference_link{google/cloud/compute/backend_buckets/v1/backend_buckets.proto#L461}
/// [google.cloud.cpp.compute.backend_buckets.v1.InsertBackendBucketRequest]: @cloud_cpp_reference_link{google/cloud/compute/backend_buckets/v1/backend_buckets.proto#L464}
///
// clang-format on
future<StatusOr<google::cloud::cpp::compute::v1::Operation>>
Expand Down Expand Up @@ -755,7 +755,7 @@ class BackendBucketsClient {
/// [`future`]: @ref google::cloud::future
/// [`StatusOr`]: @ref google::cloud::StatusOr
/// [`Status`]: @ref google::cloud::Status
/// [google.cloud.cpp.compute.backend_buckets.v1.InsertBackendBucketRequest]: @cloud_cpp_reference_link{google/cloud/compute/backend_buckets/v1/backend_buckets.proto#L461}
/// [google.cloud.cpp.compute.backend_buckets.v1.InsertBackendBucketRequest]: @cloud_cpp_reference_link{google/cloud/compute/backend_buckets/v1/backend_buckets.proto#L464}
///
// clang-format on
future<StatusOr<google::cloud::cpp::compute::v1::Operation>>
Expand Down Expand Up @@ -823,7 +823,7 @@ class BackendBucketsClient {
/// [`future`]: @ref google::cloud::future
/// [`StatusOr`]: @ref google::cloud::StatusOr
/// [`Status`]: @ref google::cloud::Status
/// [google.cloud.cpp.compute.backend_buckets.v1.ListBackendBucketsRequest]: @cloud_cpp_reference_link{google/cloud/compute/backend_buckets/v1/backend_buckets.proto#L490}
/// [google.cloud.cpp.compute.backend_buckets.v1.ListBackendBucketsRequest]: @cloud_cpp_reference_link{google/cloud/compute/backend_buckets/v1/backend_buckets.proto#L493}
/// [google.cloud.cpp.compute.v1.BackendBucket]: @cloud_cpp_reference_link{google/cloud/compute/v1/internal/common_012.proto#L28}
///
// clang-format on
Expand Down Expand Up @@ -864,7 +864,7 @@ class BackendBucketsClient {
/// [`future`]: @ref google::cloud::future
/// [`StatusOr`]: @ref google::cloud::StatusOr
/// [`Status`]: @ref google::cloud::Status
/// [google.cloud.cpp.compute.backend_buckets.v1.ListBackendBucketsRequest]: @cloud_cpp_reference_link{google/cloud/compute/backend_buckets/v1/backend_buckets.proto#L490}
/// [google.cloud.cpp.compute.backend_buckets.v1.ListBackendBucketsRequest]: @cloud_cpp_reference_link{google/cloud/compute/backend_buckets/v1/backend_buckets.proto#L493}
/// [google.cloud.cpp.compute.v1.BackendBucket]: @cloud_cpp_reference_link{google/cloud/compute/v1/internal/common_012.proto#L28}
///
// clang-format on
Expand Down Expand Up @@ -901,7 +901,7 @@ class BackendBucketsClient {
/// [`future`]: @ref google::cloud::future
/// [`StatusOr`]: @ref google::cloud::StatusOr
/// [`Status`]: @ref google::cloud::Status
/// [google.cloud.cpp.compute.backend_buckets.v1.ListUsableRequest]: @cloud_cpp_reference_link{google/cloud/compute/backend_buckets/v1/backend_buckets.proto#L591}
/// [google.cloud.cpp.compute.backend_buckets.v1.ListUsableRequest]: @cloud_cpp_reference_link{google/cloud/compute/backend_buckets/v1/backend_buckets.proto#L594}
/// [google.cloud.cpp.compute.v1.BackendBucket]: @cloud_cpp_reference_link{google/cloud/compute/v1/internal/common_012.proto#L28}
///
// clang-format on
Expand Down Expand Up @@ -941,7 +941,7 @@ class BackendBucketsClient {
/// [`future`]: @ref google::cloud::future
/// [`StatusOr`]: @ref google::cloud::StatusOr
/// [`Status`]: @ref google::cloud::Status
/// [google.cloud.cpp.compute.backend_buckets.v1.ListUsableRequest]: @cloud_cpp_reference_link{google/cloud/compute/backend_buckets/v1/backend_buckets.proto#L591}
/// [google.cloud.cpp.compute.backend_buckets.v1.ListUsableRequest]: @cloud_cpp_reference_link{google/cloud/compute/backend_buckets/v1/backend_buckets.proto#L594}
/// [google.cloud.cpp.compute.v1.BackendBucket]: @cloud_cpp_reference_link{google/cloud/compute/v1/internal/common_012.proto#L28}
///
// clang-format on
Expand Down Expand Up @@ -981,7 +981,7 @@ class BackendBucketsClient {
/// [`future`]: @ref google::cloud::future
/// [`StatusOr`]: @ref google::cloud::StatusOr
/// [`Status`]: @ref google::cloud::Status
/// [google.cloud.cpp.compute.backend_buckets.v1.PatchBackendBucketRequest]: @cloud_cpp_reference_link{google/cloud/compute/backend_buckets/v1/backend_buckets.proto#L692}
/// [google.cloud.cpp.compute.backend_buckets.v1.PatchBackendBucketRequest]: @cloud_cpp_reference_link{google/cloud/compute/backend_buckets/v1/backend_buckets.proto#L695}
///
// clang-format on
future<StatusOr<google::cloud::cpp::compute::v1::Operation>>
Expand Down Expand Up @@ -1042,7 +1042,7 @@ class BackendBucketsClient {
/// [`future`]: @ref google::cloud::future
/// [`StatusOr`]: @ref google::cloud::StatusOr
/// [`Status`]: @ref google::cloud::Status
/// [google.cloud.cpp.compute.backend_buckets.v1.PatchBackendBucketRequest]: @cloud_cpp_reference_link{google/cloud/compute/backend_buckets/v1/backend_buckets.proto#L692}
/// [google.cloud.cpp.compute.backend_buckets.v1.PatchBackendBucketRequest]: @cloud_cpp_reference_link{google/cloud/compute/backend_buckets/v1/backend_buckets.proto#L695}
///
// clang-format on
future<StatusOr<google::cloud::cpp::compute::v1::Operation>>
Expand Down Expand Up @@ -1110,7 +1110,7 @@ class BackendBucketsClient {
/// [`future`]: @ref google::cloud::future
/// [`StatusOr`]: @ref google::cloud::StatusOr
/// [`Status`]: @ref google::cloud::Status
/// [google.cloud.cpp.compute.backend_buckets.v1.SetEdgeSecurityPolicyRequest]: @cloud_cpp_reference_link{google/cloud/compute/backend_buckets/v1/backend_buckets.proto#L725}
/// [google.cloud.cpp.compute.backend_buckets.v1.SetEdgeSecurityPolicyRequest]: @cloud_cpp_reference_link{google/cloud/compute/backend_buckets/v1/backend_buckets.proto#L728}
///
// clang-format on
future<StatusOr<google::cloud::cpp::compute::v1::Operation>>
Expand Down Expand Up @@ -1168,7 +1168,7 @@ class BackendBucketsClient {
/// [`future`]: @ref google::cloud::future
/// [`StatusOr`]: @ref google::cloud::StatusOr
/// [`Status`]: @ref google::cloud::Status
/// [google.cloud.cpp.compute.backend_buckets.v1.SetEdgeSecurityPolicyRequest]: @cloud_cpp_reference_link{google/cloud/compute/backend_buckets/v1/backend_buckets.proto#L725}
/// [google.cloud.cpp.compute.backend_buckets.v1.SetEdgeSecurityPolicyRequest]: @cloud_cpp_reference_link{google/cloud/compute/backend_buckets/v1/backend_buckets.proto#L728}
///
// clang-format on
future<StatusOr<google::cloud::cpp::compute::v1::Operation>>
Expand Down Expand Up @@ -1229,7 +1229,7 @@ class BackendBucketsClient {
/// [`future`]: @ref google::cloud::future
/// [`StatusOr`]: @ref google::cloud::StatusOr
/// [`Status`]: @ref google::cloud::Status
/// [google.cloud.cpp.compute.backend_buckets.v1.SetIamPolicyRequest]: @cloud_cpp_reference_link{google/cloud/compute/backend_buckets/v1/backend_buckets.proto#L760}
/// [google.cloud.cpp.compute.backend_buckets.v1.SetIamPolicyRequest]: @cloud_cpp_reference_link{google/cloud/compute/backend_buckets/v1/backend_buckets.proto#L763}
/// [google.cloud.cpp.compute.v1.Policy]: @cloud_cpp_reference_link{google/cloud/compute/v1/internal/common_009.proto#L317}
///
// clang-format on
Expand Down Expand Up @@ -1264,7 +1264,7 @@ class BackendBucketsClient {
/// [`future`]: @ref google::cloud::future
/// [`StatusOr`]: @ref google::cloud::StatusOr
/// [`Status`]: @ref google::cloud::Status
/// [google.cloud.cpp.compute.backend_buckets.v1.SetIamPolicyRequest]: @cloud_cpp_reference_link{google/cloud/compute/backend_buckets/v1/backend_buckets.proto#L760}
/// [google.cloud.cpp.compute.backend_buckets.v1.SetIamPolicyRequest]: @cloud_cpp_reference_link{google/cloud/compute/backend_buckets/v1/backend_buckets.proto#L763}
/// [google.cloud.cpp.compute.v1.Policy]: @cloud_cpp_reference_link{google/cloud/compute/v1/internal/common_009.proto#L317}
///
// clang-format on
Expand Down Expand Up @@ -1294,7 +1294,7 @@ class BackendBucketsClient {
/// [`future`]: @ref google::cloud::future
/// [`StatusOr`]: @ref google::cloud::StatusOr
/// [`Status`]: @ref google::cloud::Status
/// [google.cloud.cpp.compute.backend_buckets.v1.TestIamPermissionsRequest]: @cloud_cpp_reference_link{google/cloud/compute/backend_buckets/v1/backend_buckets.proto#L776}
/// [google.cloud.cpp.compute.backend_buckets.v1.TestIamPermissionsRequest]: @cloud_cpp_reference_link{google/cloud/compute/backend_buckets/v1/backend_buckets.proto#L779}
/// [google.cloud.cpp.compute.v1.TestPermissionsResponse]: @cloud_cpp_reference_link{google/cloud/compute/v1/internal/common_171.proto#L30}
///
// clang-format on
Expand Down Expand Up @@ -1329,7 +1329,7 @@ class BackendBucketsClient {
/// [`future`]: @ref google::cloud::future
/// [`StatusOr`]: @ref google::cloud::StatusOr
/// [`Status`]: @ref google::cloud::Status
/// [google.cloud.cpp.compute.backend_buckets.v1.TestIamPermissionsRequest]: @cloud_cpp_reference_link{google/cloud/compute/backend_buckets/v1/backend_buckets.proto#L776}
/// [google.cloud.cpp.compute.backend_buckets.v1.TestIamPermissionsRequest]: @cloud_cpp_reference_link{google/cloud/compute/backend_buckets/v1/backend_buckets.proto#L779}
/// [google.cloud.cpp.compute.v1.TestPermissionsResponse]: @cloud_cpp_reference_link{google/cloud/compute/v1/internal/common_171.proto#L30}
///
// clang-format on
Expand Down Expand Up @@ -1367,7 +1367,7 @@ class BackendBucketsClient {
/// [`future`]: @ref google::cloud::future
/// [`StatusOr`]: @ref google::cloud::StatusOr
/// [`Status`]: @ref google::cloud::Status
/// [google.cloud.cpp.compute.backend_buckets.v1.UpdateBackendBucketRequest]: @cloud_cpp_reference_link{google/cloud/compute/backend_buckets/v1/backend_buckets.proto#L791}
/// [google.cloud.cpp.compute.backend_buckets.v1.UpdateBackendBucketRequest]: @cloud_cpp_reference_link{google/cloud/compute/backend_buckets/v1/backend_buckets.proto#L794}
///
// clang-format on
future<StatusOr<google::cloud::cpp::compute::v1::Operation>>
Expand Down Expand Up @@ -1426,7 +1426,7 @@ class BackendBucketsClient {
/// [`future`]: @ref google::cloud::future
/// [`StatusOr`]: @ref google::cloud::StatusOr
/// [`Status`]: @ref google::cloud::Status
/// [google.cloud.cpp.compute.backend_buckets.v1.UpdateBackendBucketRequest]: @cloud_cpp_reference_link{google/cloud/compute/backend_buckets/v1/backend_buckets.proto#L791}
/// [google.cloud.cpp.compute.backend_buckets.v1.UpdateBackendBucketRequest]: @cloud_cpp_reference_link{google/cloud/compute/backend_buckets/v1/backend_buckets.proto#L794}
///
// clang-format on
future<StatusOr<google::cloud::cpp::compute::v1::Operation>>
Expand Down
Loading
Loading