Skip to content

Commit 74e98fc

Browse files
authored
impl(v3): add generator support for bespoke WaitForConsistency method (googleapis#15914)
1 parent b62411b commit 74e98fc

13 files changed

Lines changed: 196 additions & 0 deletions

generator/generator_config.proto

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -167,6 +167,21 @@ message ServiceConfiguration {
167167
// RPCs. If set to false (the default), a no-op resumption function will be
168168
// generated.
169169
bool omit_streaming_updater = 29;
170+
171+
message BespokeMethod {
172+
string name = 1;
173+
string return_type = 2;
174+
string parameters = 3;
175+
}
176+
177+
// Only added to maintain feature parity when migrating from the handwritten
178+
// Bigtable Table Admin class to the generated class. While some attempts were
179+
// made to generalize this feature, it currently only supports the
180+
// WaitForConsistency method. This functionality can be enhanced later if we
181+
// ever need to use this again.
182+
// The implementation for this method in the ConnectionImpl class is not
183+
// generated and must be handwritten in a separate .cc file.
184+
repeated BespokeMethod bespoke_methods = 30;
170185
}
171186

172187
message DiscoveryDocumentDefinedProduct {

generator/integration_tests/golden/v1/golden_rest_only_client.cc

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,11 @@ GoldenRestOnlyClient::Noop(google::protobuf::Empty const& request, Options opts)
3838
return connection_->Noop(request);
3939
}
4040

41+
StatusOr<google::protobuf::Empty> GoldenRestOnlyClient::WaitForConsistency(google::protobuf::Empty const& request, Options opts) {
42+
internal::OptionsSpan span(internal::MergeOptions(std::move(opts), options_));
43+
return connection_->WaitForConsistency(request);
44+
}
45+
4146
GOOGLE_CLOUD_CPP_INLINE_NAMESPACE_END
4247
} // namespace golden_v1
4348
} // namespace cloud

generator/integration_tests/golden/v1/golden_rest_only_client.h

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,37 @@ class GoldenRestOnlyClient {
109109
Status
110110
Noop(google::protobuf::Empty const& request, Options opts = {});
111111

112+
113+
// clang-format off
114+
///
115+
/// Polls a table until it is consistent or the RetryPolicy is exhausted based
116+
/// on a consistency token, that is, if replication has caught up based on the
117+
/// provided conditions specified in the token and the check request.
118+
///
119+
/// @param request Unary RPCs, such as the one wrapped by this
120+
/// function, receive a single `request` proto message which includes all
121+
/// the inputs for the RPC. In this case, the proto message is a
122+
/// [google.bigtable.admin.v2.CheckConsistencyRequest].
123+
/// Proto messages are converted to C++ classes by Protobuf, using the
124+
/// [Protobuf mapping rules].
125+
/// @param opts Optional. Override the class-level options, such as retry and
126+
/// backoff policies.
127+
/// @return the result of the RPC. The response message type
128+
/// ([google.bigtable.admin.v2.CheckConsistencyResponse])
129+
/// is mapped to a C++ class using the [Protobuf mapping rules].
130+
/// If the request fails, the [`StatusOr`] contains the error details.
131+
///
132+
/// [Protobuf mapping rules]: https://protobuf.dev/reference/cpp/cpp-generated/
133+
/// [input iterator requirements]: https://en.cppreference.com/w/cpp/named_req/InputIterator
134+
/// [`std::string`]: https://en.cppreference.com/w/cpp/string/basic_string
135+
/// [`future`]: @ref google::cloud::future
136+
/// [`StatusOr`]: @ref google::cloud::StatusOr
137+
/// [`Status`]: @ref google::cloud::Status
138+
/// [google.bigtable.admin.v2.CheckConsistencyRequest]: @googleapis_reference_link{google/bigtable/admin/v2/bigtable_table_admin.proto#L909}
139+
/// [google.bigtable.admin.v2.CheckConsistencyResponse]: @googleapis_reference_link{google/bigtable/admin/v2/bigtable_table_admin.proto#L948}
140+
///
141+
// clang-format on
142+
StatusOr<google::protobuf::Empty> WaitForConsistency(google::protobuf::Empty const& request, Options opts = {});
112143
private:
113144
std::shared_ptr<GoldenRestOnlyConnection> connection_;
114145
Options options_;

generator/integration_tests/golden/v1/golden_rest_only_connection.cc

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,11 @@ GoldenRestOnlyConnection::Noop(
4141
return Status(StatusCode::kUnimplemented, "not implemented");
4242
}
4343

44+
StatusOr<google::protobuf::Empty> GoldenRestOnlyConnection::WaitForConsistency(google::protobuf::Empty const&) {
45+
return StatusOr<google::protobuf::Empty>(
46+
Status(StatusCode::kUnimplemented, "not implemented"));
47+
}
48+
4449
GOOGLE_CLOUD_CPP_INLINE_NAMESPACE_END
4550
} // namespace golden_v1
4651
} // namespace cloud

generator/integration_tests/golden/v1/golden_rest_only_connection.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -176,6 +176,8 @@ class GoldenRestOnlyConnection {
176176

177177
virtual Status
178178
Noop(google::protobuf::Empty const& request);
179+
180+
virtual StatusOr<google::protobuf::Empty> WaitForConsistency(google::protobuf::Empty const& request);
179181
};
180182

181183
GOOGLE_CLOUD_CPP_INLINE_NAMESPACE_END

generator/integration_tests/golden_config.textproto

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,13 @@ service {
5959
]
6060
override_service_config_yaml_name: "generator/integration_tests/test2.yaml"
6161
endpoint_location_style: LOCATION_OPTIONALLY_DEPENDENT
62+
bespoke_methods : [
63+
{
64+
name: "WaitForConsistency",
65+
return_type: "StatusOr<google::protobuf::Empty>",
66+
parameters: "(google::protobuf::Empty const& request, Options opts = {})"
67+
}
68+
]
6269
}
6370
6471
service {

generator/internal/client_generator.cc

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,12 +21,51 @@
2121
#include "generator/internal/predicate_utils.h"
2222
#include "generator/internal/printer.h"
2323
#include "absl/strings/str_cat.h"
24+
#include "absl/strings/str_replace.h"
2425
#include "google/api/client.pb.h"
2526
#include <google/protobuf/descriptor.h>
2627

2728
namespace google {
2829
namespace cloud {
2930
namespace generator_internal {
31+
namespace {
32+
std::string FormatBespokeMethodComments(std::string const& method_name) {
33+
if (method_name == "WaitForConsistency") {
34+
return R"""(
35+
// clang-format off
36+
///
37+
/// Polls a table until it is consistent or the RetryPolicy is exhausted based
38+
/// on a consistency token, that is, if replication has caught up based on the
39+
/// provided conditions specified in the token and the check request.
40+
///
41+
/// @param request Unary RPCs, such as the one wrapped by this
42+
/// function, receive a single `request` proto message which includes all
43+
/// the inputs for the RPC. In this case, the proto message is a
44+
/// [google.bigtable.admin.v2.CheckConsistencyRequest].
45+
/// Proto messages are converted to C++ classes by Protobuf, using the
46+
/// [Protobuf mapping rules].
47+
/// @param opts Optional. Override the class-level options, such as retry and
48+
/// backoff policies.
49+
/// @return the result of the RPC. The response message type
50+
/// ([google.bigtable.admin.v2.CheckConsistencyResponse])
51+
/// is mapped to a C++ class using the [Protobuf mapping rules].
52+
/// If the request fails, the [`StatusOr`] contains the error details.
53+
///
54+
/// [Protobuf mapping rules]: https://protobuf.dev/reference/cpp/cpp-generated/
55+
/// [input iterator requirements]: https://en.cppreference.com/w/cpp/named_req/InputIterator
56+
/// [`std::string`]: https://en.cppreference.com/w/cpp/string/basic_string
57+
/// [`future`]: @ref google::cloud::future
58+
/// [`StatusOr`]: @ref google::cloud::StatusOr
59+
/// [`Status`]: @ref google::cloud::Status
60+
/// [google.bigtable.admin.v2.CheckConsistencyRequest]: @googleapis_reference_link{google/bigtable/admin/v2/bigtable_table_admin.proto#L909}
61+
/// [google.bigtable.admin.v2.CheckConsistencyResponse]: @googleapis_reference_link{google/bigtable/admin/v2/bigtable_table_admin.proto#L948}
62+
///
63+
// clang-format on
64+
)""";
65+
}
66+
return "";
67+
}
68+
} // namespace
3069

3170
ClientGenerator::ClientGenerator(
3271
google::protobuf::ServiceDescriptor const* service_descriptor,
@@ -380,6 +419,13 @@ R"""( std::unique_ptr<::google::cloud::AsyncStreamingReadWriteRpc<
380419
__FILE__, __LINE__);
381420
}
382421

422+
for (auto const& method : bespoke_methods()) {
423+
HeaderPrint("\n");
424+
HeaderPrint(FormatBespokeMethodComments(method.name()));
425+
HeaderPrint(absl::StrCat(method.return_type(), " ", method.name(),
426+
method.parameters(), ";"));
427+
}
428+
383429
HeaderPrint( // clang-format off
384430
"\n"
385431
" private:\n"
@@ -716,6 +762,19 @@ std::unique_ptr<::google::cloud::AsyncStreamingReadWriteRpc<
716762
__FILE__, __LINE__);
717763
}
718764

765+
for (auto const& method : bespoke_methods()) {
766+
CcPrint("\n");
767+
CcPrint(absl::StrCat(
768+
method.return_type(), R"""( $client_class_name$::)""", method.name(),
769+
absl::StrReplaceAll(method.parameters(), {{" = {}", ""}}),
770+
absl::StrFormat(R"""( {
771+
internal::OptionsSpan span(internal::MergeOptions(std::move(opts), options_));
772+
return connection_->%s(request);
773+
}
774+
)""",
775+
method.name())));
776+
}
777+
719778
CcCloseNamespaces();
720779
return {};
721780
}

generator/internal/codegen_utils.cc

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,11 @@ void ProcessArgOmitRpc(
111111
ProcessRepeated("omit_rpc", "omitted_rpcs", command_line_args);
112112
}
113113

114+
void ProcessArgBespokeMethod(
115+
std::vector<std::pair<std::string, std::string>>& command_line_args) {
116+
ProcessRepeated("bespoke_method", "bespoke_methods", command_line_args);
117+
}
118+
114119
void ProcessArgServiceEndpointEnvVar(
115120
std::vector<std::pair<std::string, std::string>>& command_line_args) {
116121
auto service_endpoint_env_var =
@@ -269,6 +274,7 @@ ProcessCommandLineArgs(std::string const& parameters) {
269274
ProcessArgCopyrightYear(command_line_args);
270275
ProcessArgOmitService(command_line_args);
271276
ProcessArgOmitRpc(command_line_args);
277+
ProcessArgBespokeMethod(command_line_args);
272278
ProcessArgServiceEndpointEnvVar(command_line_args);
273279
ProcessArgEmulatorEndpointEnvVar(command_line_args);
274280
ProcessArgEndpointLocationStyle(command_line_args);

generator/internal/connection_generator.cc

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
#include "generator/internal/pagination.h"
2020
#include "generator/internal/predicate_utils.h"
2121
#include "generator/internal/printer.h"
22+
#include "absl/strings/str_replace.h"
2223
#include "absl/strings/str_split.h"
2324
#include <google/protobuf/descriptor.h>
2425

@@ -315,6 +316,14 @@ class $connection_class_name$ {
315316
__FILE__, __LINE__);
316317
}
317318

319+
for (auto const& method : bespoke_methods()) {
320+
HeaderPrint("\n");
321+
HeaderPrint(absl::StrCat(
322+
" virtual ", method.return_type(), " ", method.name(),
323+
absl::StrReplaceAll(method.parameters(), {{", Options opts = {}", ""}}),
324+
";\n"));
325+
}
326+
318327
// close abstract interface Connection base class
319328
HeaderPrint("};\n");
320329

@@ -490,6 +499,26 @@ future<StatusOr<$response_type$>>
490499
__FILE__, __LINE__);
491500
}
492501

502+
for (auto const& method : bespoke_methods()) {
503+
CcPrint("\n");
504+
std::string make_return =
505+
absl::StrContains(method.return_type(), "future")
506+
? absl::StrCat("google::cloud::make_ready_", method.return_type())
507+
: method.return_type();
508+
509+
CcPrint(
510+
absl::StrCat(method.return_type(), R"""( $connection_class_name$::)""",
511+
method.name(),
512+
absl::StrReplaceAll(method.parameters(),
513+
{{" request, Options opts = {}", ""}}),
514+
" {\n",
515+
absl::StrFormat(R"""( return %s(
516+
Status(StatusCode::kUnimplemented, "not implemented"));
517+
}
518+
)""",
519+
make_return)));
520+
}
521+
493522
if (HasGenerateGrpcTransport()) {
494523
EmitFactoryFunctionDefinition(EndpointLocationStyle());
495524
}

generator/internal/connection_impl_generator.cc

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
#include "generator/internal/predicate_utils.h"
2020
#include "generator/internal/printer.h"
2121
#include "absl/strings/str_cat.h"
22+
#include "absl/strings/str_replace.h"
2223
#include <google/protobuf/descriptor.h>
2324

2425
namespace google {
@@ -120,6 +121,14 @@ class $connection_class_name$Impl
120121
HeaderPrintMethod(method, __FILE__, __LINE__, AsyncMethodDeclaration());
121122
}
122123

124+
for (auto const& method : bespoke_methods()) {
125+
HeaderPrint("\n");
126+
HeaderPrint(absl::StrCat(
127+
method.return_type(), " ", method.name(),
128+
absl::StrReplaceAll(method.parameters(), {{", Options opts = {}", ""}}),
129+
" override;"));
130+
}
131+
123132
HeaderPrint(R"""(
124133
private:
125134
std::unique_ptr<google::cloud::BackgroundThreads> background_;

0 commit comments

Comments
 (0)