From 92cee51e2d12e2f2175c9660e241984e8a37d2de Mon Sep 17 00:00:00 2001 From: vam-google Date: Wed, 21 Apr 2021 01:57:36 -0700 Subject: [PATCH 01/16] diregapic initial implementaion --- BUILD.bazel | 26 + dependencies.properties | 1 - rules_java_gapic/java_gapic.bzl | 14 +- .../com/google/api/generator/MainDumper.java | 50 ++ .../google/api/generator/MainFromFile.java | 60 ++ .../api/generator/gapic/composer/BUILD.bazel | 3 + .../generator/gapic/composer/Composer.java | 57 +- .../comment/SettingsCommentComposer.java | 2 +- .../composer/comment/StubCommentComposer.java | 29 +- ...tServiceCallableFactoryClassComposer.java} | 214 +++--- ...stractServiceClientTestClassComposer.java} | 653 +++--------------- ...AbstractServiceSettingsClassComposer.java} | 105 +-- .../AbstractServiceStubClassComposer.java} | 552 +++++---------- ...ractServiceStubSettingsClassComposer.java} | 284 +++----- .../gapic/composer/common/BUILD.bazel | 50 ++ .../BatchingDescriptorComposer.java | 2 +- .../composer/{ => common}/ClassComposer.java | 2 +- .../{ => common}/RetrySettingsComposer.java | 2 +- .../ServiceClientClassComposer.java | 2 +- .../ServiceStubClassComposer.java | 2 +- .../generator/gapic/composer/grpc/BUILD.bazel | 51 ++ ...pcServiceCallableFactoryClassComposer.java | 204 ++++++ .../grpc/GrpcServiceStubClassComposer.java | 338 +++++++++ .../{ => grpc}/MockServiceClassComposer.java | 3 +- .../MockServiceImplClassComposer.java | 3 +- .../grpc/ServiceClientTestClassComposer.java | 582 ++++++++++++++++ .../grpc/ServiceSettingsClassComposer.java | 42 ++ .../ServiceStubSettingsClassComposer.java | 184 +++++ .../gapic/composer/httpjson/BUILD.bazel | 52 ++ ...onServiceCallableFactoryClassComposer.java | 100 +++ .../HttpJsonServiceStubClassComposer.java | 513 ++++++++++++++ .../ServiceClientTestClassComposer.java | 508 ++++++++++++++ .../ServiceSettingsClassComposer.java | 42 ++ .../ServiceStubSettingsClassComposer.java | 176 +++++ .../gapic/composer/store/TypeStore.java | 12 +- .../gapic/composer/utils/ClassNames.java | 23 +- .../generator/gapic/model/GapicContext.java | 5 + .../gapic/model/HttpRuleBindings.java | 58 ++ .../api/generator/gapic/model/Method.java | 9 +- .../api/generator/gapic/model/Transport.java} | 17 +- .../gapic/protoparser/HttpRuleParser.java | 85 ++- .../generator/gapic/protoparser/Parser.java | 11 +- .../protoparser/PluginArgumentParser.java | 33 +- .../api/generator/gapic/composer/BUILD.bazel | 24 +- .../gapic/composer/ComposerTest.java | 3 +- .../gapic/composer/common/BUILD.bazel | 100 +++ .../BatchingDescriptorComposerTest.java | 15 +- .../RetrySettingsComposerTest.java | 31 +- .../ServiceClientClassComposerTest.java | 15 +- .../ServiceStubClassComposerTest.java | 11 +- .../TestProtoLoader.java} | 53 +- .../gapic/composer/common/goldens/BUILD.bazel | 6 + ...DescriptorComposerTestNoSubresponse.golden | 0 ...ngDescriptorComposerTestSubresponse.golden | 0 .../goldens/DeprecatedServiceClient.golden | 0 .../goldens/DeprecatedServiceStub.golden | 0 .../{ => common}/goldens/EchoClient.golden | 0 .../{ => common}/goldens/EchoStub.golden | 0 .../goldens/IdentityClient.golden | 0 .../gapic/composer/constants/BUILD.bazel | 13 - .../generator/gapic/composer/grpc/BUILD.bazel | 100 +++ ...rviceCallableFactoryClassComposerTest.java | 11 +- .../GrpcServiceStubClassComposerTest.java | 19 +- .../composer/grpc/GrpcTestProtoLoader.java | 30 + .../MockServiceClassComposerTest.java | 11 +- .../MockServiceImplClassComposerTest.java | 11 +- .../ServiceClientTestClassComposerTest.java | 26 +- .../ServiceSettingsClassComposerTest.java | 12 +- .../ServiceStubSettingsClassComposerTest.java | 29 +- .../gapic/composer/grpc/goldens/BUILD.bazel | 6 + .../DeprecatedServiceClientTest.golden | 0 .../goldens/DeprecatedServiceSettings.golden | 0 .../DeprecatedServiceStubSettings.golden | 0 .../{ => grpc}/goldens/EchoClientTest.golden | 0 .../{ => grpc}/goldens/EchoSettings.golden | 0 .../goldens/EchoStubSettings.golden | 0 ...rpcDeprecatedServiceCallableFactory.golden | 0 .../goldens/GrpcDeprecatedServiceStub.golden | 0 .../goldens/GrpcEchoCallableFactory.golden | 0 .../{ => grpc}/goldens/GrpcEchoStub.golden | 0 .../goldens/GrpcPublisherStub.golden | 0 .../{ => grpc}/goldens/GrpcTestingStub.golden | 0 .../goldens/LoggingClientTest.golden | 0 .../LoggingServiceV2StubSettings.golden | 0 .../goldens/MockDeprecatedService.golden | 0 .../goldens/MockDeprecatedServiceImpl.golden | 0 .../{ => grpc}/goldens/MockEcho.golden | 0 .../{ => grpc}/goldens/MockEchoImpl.golden | 0 .../goldens/PublisherStubSettings.golden | 0 .../goldens/SubscriberClientTest.golden | 0 .../goldens/TestingClientTest.golden | 0 .../gapic/composer/resourcename/BUILD.bazel | 69 +- .../ResourceNameHelperClassComposerTest.java | 11 +- .../goldens/AgentName.golden | 0 .../composer/resourcename/goldens/BUILD.bazel | 6 + .../goldens/BillingAccountLocationName.golden | 0 .../goldens/FoobarName.golden | 0 .../goldens/SessionName.golden | 0 .../goldens/TestName.golden | 0 .../gapic/protoparser/HttpRuleParserTest.java | 23 +- .../api/generator/test/framework/Differ.java | 18 +- 101 files changed, 4231 insertions(+), 1583 deletions(-) create mode 100644 src/main/java/com/google/api/generator/MainDumper.java create mode 100644 src/main/java/com/google/api/generator/MainFromFile.java rename src/main/java/com/google/api/generator/gapic/composer/{GrpcServiceCallableFactoryClassComposer.java => common/AbstractServiceCallableFactoryClassComposer.java} (57%) rename src/main/java/com/google/api/generator/gapic/composer/{ServiceClientTestClassComposer.java => common/AbstractServiceClientTestClassComposer.java} (69%) rename src/main/java/com/google/api/generator/gapic/composer/{ServiceSettingsClassComposer.java => common/AbstractServiceSettingsClassComposer.java} (91%) rename src/main/java/com/google/api/generator/gapic/composer/{GrpcServiceStubClassComposer.java => common/AbstractServiceStubClassComposer.java} (67%) rename src/main/java/com/google/api/generator/gapic/composer/{ServiceStubSettingsClassComposer.java => common/AbstractServiceStubSettingsClassComposer.java} (89%) create mode 100644 src/main/java/com/google/api/generator/gapic/composer/common/BUILD.bazel rename src/main/java/com/google/api/generator/gapic/composer/{ => common}/BatchingDescriptorComposer.java (99%) rename src/main/java/com/google/api/generator/gapic/composer/{ => common}/ClassComposer.java (93%) rename src/main/java/com/google/api/generator/gapic/composer/{ => common}/RetrySettingsComposer.java (99%) rename src/main/java/com/google/api/generator/gapic/composer/{ => common}/ServiceClientClassComposer.java (99%) rename src/main/java/com/google/api/generator/gapic/composer/{ => common}/ServiceStubClassComposer.java (99%) create mode 100644 src/main/java/com/google/api/generator/gapic/composer/grpc/BUILD.bazel create mode 100644 src/main/java/com/google/api/generator/gapic/composer/grpc/GrpcServiceCallableFactoryClassComposer.java create mode 100644 src/main/java/com/google/api/generator/gapic/composer/grpc/GrpcServiceStubClassComposer.java rename src/main/java/com/google/api/generator/gapic/composer/{ => grpc}/MockServiceClassComposer.java (98%) rename src/main/java/com/google/api/generator/gapic/composer/{ => grpc}/MockServiceImplClassComposer.java (99%) create mode 100644 src/main/java/com/google/api/generator/gapic/composer/grpc/ServiceClientTestClassComposer.java create mode 100644 src/main/java/com/google/api/generator/gapic/composer/grpc/ServiceSettingsClassComposer.java create mode 100644 src/main/java/com/google/api/generator/gapic/composer/grpc/ServiceStubSettingsClassComposer.java create mode 100644 src/main/java/com/google/api/generator/gapic/composer/httpjson/BUILD.bazel create mode 100644 src/main/java/com/google/api/generator/gapic/composer/httpjson/HttpJsonServiceCallableFactoryClassComposer.java create mode 100644 src/main/java/com/google/api/generator/gapic/composer/httpjson/HttpJsonServiceStubClassComposer.java create mode 100644 src/main/java/com/google/api/generator/gapic/composer/httpjson/ServiceClientTestClassComposer.java create mode 100644 src/main/java/com/google/api/generator/gapic/composer/httpjson/ServiceSettingsClassComposer.java create mode 100644 src/main/java/com/google/api/generator/gapic/composer/httpjson/ServiceStubSettingsClassComposer.java create mode 100644 src/main/java/com/google/api/generator/gapic/model/HttpRuleBindings.java rename src/{test/java/com/google/api/generator/gapic/composer/constants/ComposerConstants.java => main/java/com/google/api/generator/gapic/model/Transport.java} (60%) create mode 100644 src/test/java/com/google/api/generator/gapic/composer/common/BUILD.bazel rename src/test/java/com/google/api/generator/gapic/composer/{ => common}/BatchingDescriptorComposerTest.java (92%) rename src/test/java/com/google/api/generator/gapic/composer/{ => common}/RetrySettingsComposerTest.java (94%) rename src/test/java/com/google/api/generator/gapic/composer/{ => common}/ServiceClientClassComposerTest.java (80%) rename src/test/java/com/google/api/generator/gapic/composer/{ => common}/ServiceStubClassComposerTest.java (81%) rename src/test/java/com/google/api/generator/gapic/composer/{TestProtoLoaderUtil.java => common/TestProtoLoader.java} (86%) create mode 100644 src/test/java/com/google/api/generator/gapic/composer/common/goldens/BUILD.bazel rename src/test/java/com/google/api/generator/gapic/composer/{ => common}/goldens/BatchingDescriptorComposerTestNoSubresponse.golden (100%) rename src/test/java/com/google/api/generator/gapic/composer/{ => common}/goldens/BatchingDescriptorComposerTestSubresponse.golden (100%) rename src/test/java/com/google/api/generator/gapic/composer/{ => common}/goldens/DeprecatedServiceClient.golden (100%) rename src/test/java/com/google/api/generator/gapic/composer/{ => common}/goldens/DeprecatedServiceStub.golden (100%) rename src/test/java/com/google/api/generator/gapic/composer/{ => common}/goldens/EchoClient.golden (100%) rename src/test/java/com/google/api/generator/gapic/composer/{ => common}/goldens/EchoStub.golden (100%) rename src/test/java/com/google/api/generator/gapic/composer/{ => common}/goldens/IdentityClient.golden (100%) create mode 100644 src/test/java/com/google/api/generator/gapic/composer/grpc/BUILD.bazel rename src/test/java/com/google/api/generator/gapic/composer/{ => grpc}/GrpcServiceCallableFactoryClassComposerTest.java (82%) rename src/test/java/com/google/api/generator/gapic/composer/{ => grpc}/GrpcServiceStubClassComposerTest.java (79%) create mode 100644 src/test/java/com/google/api/generator/gapic/composer/grpc/GrpcTestProtoLoader.java rename src/test/java/com/google/api/generator/gapic/composer/{ => grpc}/MockServiceClassComposerTest.java (81%) rename src/test/java/com/google/api/generator/gapic/composer/{ => grpc}/MockServiceImplClassComposerTest.java (81%) rename src/test/java/com/google/api/generator/gapic/composer/{ => grpc}/ServiceClientTestClassComposerTest.java (77%) rename src/test/java/com/google/api/generator/gapic/composer/{ => grpc}/ServiceSettingsClassComposerTest.java (80%) rename src/test/java/com/google/api/generator/gapic/composer/{ => grpc}/ServiceStubSettingsClassComposerTest.java (75%) create mode 100644 src/test/java/com/google/api/generator/gapic/composer/grpc/goldens/BUILD.bazel rename src/test/java/com/google/api/generator/gapic/composer/{ => grpc}/goldens/DeprecatedServiceClientTest.golden (100%) rename src/test/java/com/google/api/generator/gapic/composer/{ => grpc}/goldens/DeprecatedServiceSettings.golden (100%) rename src/test/java/com/google/api/generator/gapic/composer/{ => grpc}/goldens/DeprecatedServiceStubSettings.golden (100%) rename src/test/java/com/google/api/generator/gapic/composer/{ => grpc}/goldens/EchoClientTest.golden (100%) rename src/test/java/com/google/api/generator/gapic/composer/{ => grpc}/goldens/EchoSettings.golden (100%) rename src/test/java/com/google/api/generator/gapic/composer/{ => grpc}/goldens/EchoStubSettings.golden (100%) rename src/test/java/com/google/api/generator/gapic/composer/{ => grpc}/goldens/GrpcDeprecatedServiceCallableFactory.golden (100%) rename src/test/java/com/google/api/generator/gapic/composer/{ => grpc}/goldens/GrpcDeprecatedServiceStub.golden (100%) rename src/test/java/com/google/api/generator/gapic/composer/{ => grpc}/goldens/GrpcEchoCallableFactory.golden (100%) rename src/test/java/com/google/api/generator/gapic/composer/{ => grpc}/goldens/GrpcEchoStub.golden (100%) rename src/test/java/com/google/api/generator/gapic/composer/{ => grpc}/goldens/GrpcPublisherStub.golden (100%) rename src/test/java/com/google/api/generator/gapic/composer/{ => grpc}/goldens/GrpcTestingStub.golden (100%) rename src/test/java/com/google/api/generator/gapic/composer/{ => grpc}/goldens/LoggingClientTest.golden (100%) rename src/test/java/com/google/api/generator/gapic/composer/{ => grpc}/goldens/LoggingServiceV2StubSettings.golden (100%) rename src/test/java/com/google/api/generator/gapic/composer/{ => grpc}/goldens/MockDeprecatedService.golden (100%) rename src/test/java/com/google/api/generator/gapic/composer/{ => grpc}/goldens/MockDeprecatedServiceImpl.golden (100%) rename src/test/java/com/google/api/generator/gapic/composer/{ => grpc}/goldens/MockEcho.golden (100%) rename src/test/java/com/google/api/generator/gapic/composer/{ => grpc}/goldens/MockEchoImpl.golden (100%) rename src/test/java/com/google/api/generator/gapic/composer/{ => grpc}/goldens/PublisherStubSettings.golden (100%) rename src/test/java/com/google/api/generator/gapic/composer/{ => grpc}/goldens/SubscriberClientTest.golden (100%) rename src/test/java/com/google/api/generator/gapic/composer/{ => grpc}/goldens/TestingClientTest.golden (100%) rename src/test/java/com/google/api/generator/gapic/composer/{ => resourcename}/goldens/AgentName.golden (100%) create mode 100644 src/test/java/com/google/api/generator/gapic/composer/resourcename/goldens/BUILD.bazel rename src/test/java/com/google/api/generator/gapic/composer/{ => resourcename}/goldens/BillingAccountLocationName.golden (100%) rename src/test/java/com/google/api/generator/gapic/composer/{ => resourcename}/goldens/FoobarName.golden (100%) rename src/test/java/com/google/api/generator/gapic/composer/{ => resourcename}/goldens/SessionName.golden (100%) rename src/test/java/com/google/api/generator/gapic/composer/{ => resourcename}/goldens/TestName.golden (100%) diff --git a/BUILD.bazel b/BUILD.bazel index 8823250fca..fa2b80f062 100644 --- a/BUILD.bazel +++ b/BUILD.bazel @@ -45,6 +45,32 @@ java_binary( ], ) +java_binary( + name = "protoc-gen-java_dumper", + main_class = "com.google.api.generator.MainDumper", + runtime_deps = [ + "//src/main/java/com/google/api/generator", + "//src/main/java/com/google/api/generator/gapic", + "@com_google_googleapis//google/api:api_java_proto", + "@com_google_googleapis//google/longrunning:longrunning_java_proto", + "@com_google_guava_guava", + "@com_google_protobuf//:protobuf_java", + ], +) + +java_binary( + name = "protoc-gen-java_gapicfromfile", + main_class = "com.google.api.generator.MainFromFile", + runtime_deps = [ + "//src/main/java/com/google/api/generator", + "//src/main/java/com/google/api/generator/gapic", + "@com_google_googleapis//google/api:api_java_proto", + "@com_google_googleapis//google/longrunning:longrunning_java_proto", + "@com_google_guava_guava", + "@com_google_protobuf//:protobuf_java", + ], +) + # google-java-format java_binary( name = "google_java_format_binary", diff --git a/dependencies.properties b/dependencies.properties index 53a7e8ee12..2a2383286a 100644 --- a/dependencies.properties +++ b/dependencies.properties @@ -11,7 +11,6 @@ version.com_google_protobuf=3.13.0 # Version of google-java-format is downgraded from 1.8 to 1.7, because 1.8 supports java 11 minimum, while our JRE is java 8. version.google_java_format=1.7 version.com_google_api_common_java=1.9.3 -# TODO(miraleung): Update this. version.com_google_gax_java=1.62.0 version.io_grpc_java=1.30.2 diff --git a/rules_java_gapic/java_gapic.bzl b/rules_java_gapic/java_gapic.bzl index e9cb1ec064..f366e42897 100644 --- a/rules_java_gapic/java_gapic.bzl +++ b/rules_java_gapic/java_gapic.bzl @@ -127,12 +127,14 @@ def java_gapic_library( service_yaml = None, deps = [], test_deps = [], + transport = None, + java_generator_name = "java_gapic", **kwargs): file_args_dict = {} if grpc_service_config: file_args_dict[grpc_service_config] = "grpc-service-config" - else: + elif transport != "rest": for keyword in NO_GRPC_CONFIG_ALLOWLIST: if keyword not in name: fail("Missing a gRPC service config file") @@ -157,21 +159,25 @@ def java_gapic_library( srcjar_name = name + "_srcjar" raw_srcjar_name = srcjar_name + "_raw" output_suffix = ".srcjar" + opt_args = [] + + if transport: + opt_args.append("transport=%s" % transport) # Produces the GAPIC metadata file if this flag is set. to any value. # Protoc invocation: --java_gapic_opt=metadata plugin_args = ["metadata"] - _java_generator_name = "java_gapic" proto_custom_library( name = raw_srcjar_name, deps = srcs, - plugin = Label("@gapic_generator_java//:protoc-gen-%s" % _java_generator_name), + plugin = Label("@gapic_generator_java//:protoc-gen-%s" % java_generator_name), plugin_args = plugin_args, plugin_file_args = {}, opt_file_args = file_args_dict, - output_type = _java_generator_name, + output_type = java_generator_name, output_suffix = output_suffix, + opt_args = opt_args, **kwargs ) diff --git a/src/main/java/com/google/api/generator/MainDumper.java b/src/main/java/com/google/api/generator/MainDumper.java new file mode 100644 index 0000000000..018106b883 --- /dev/null +++ b/src/main/java/com/google/api/generator/MainDumper.java @@ -0,0 +1,50 @@ +// Copyright 2021 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 +// +// http://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. + +package com.google.api.generator; + +import com.google.api.AnnotationsProto; +import com.google.api.ClientProto; +import com.google.api.FieldBehaviorProto; +import com.google.api.ResourceProto; +import com.google.longrunning.OperationsProto; +import com.google.protobuf.ExtensionRegistry; +import com.google.protobuf.compiler.PluginProtos.CodeGeneratorRequest; +import com.google.protobuf.compiler.PluginProtos.CodeGeneratorResponse; +import java.io.IOException; + +public class MainDumper { + public static void main(String[] args) throws IOException { + ExtensionRegistry registry = ExtensionRegistry.newInstance(); + registerAllExtensions(registry); + CodeGeneratorRequest request = CodeGeneratorRequest.parseFrom(System.in, registry); + + CodeGeneratorResponse.Builder response = CodeGeneratorResponse.newBuilder(); + response + .setSupportedFeatures(CodeGeneratorResponse.Feature.FEATURE_PROTO3_OPTIONAL_VALUE) + .addFileBuilder() + .setName("desc-dump.bin") + .setContentBytes(request.toByteString()); + response.build().writeTo(System.out); + } + + /** Register all extensions needed to process API protofiles. */ + private static void registerAllExtensions(ExtensionRegistry extensionRegistry) { + OperationsProto.registerAllExtensions(extensionRegistry); + AnnotationsProto.registerAllExtensions(extensionRegistry); + ClientProto.registerAllExtensions(extensionRegistry); + ResourceProto.registerAllExtensions(extensionRegistry); + FieldBehaviorProto.registerAllExtensions(extensionRegistry); + } +} diff --git a/src/main/java/com/google/api/generator/MainFromFile.java b/src/main/java/com/google/api/generator/MainFromFile.java new file mode 100644 index 0000000000..e93f2db6ca --- /dev/null +++ b/src/main/java/com/google/api/generator/MainFromFile.java @@ -0,0 +1,60 @@ +// Copyright 2021 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 +// +// http://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. + +package com.google.api.generator; + +import com.google.api.AnnotationsProto; +import com.google.api.ClientProto; +import com.google.api.FieldBehaviorProto; +import com.google.api.ResourceProto; +import com.google.api.generator.gapic.Generator; +import com.google.longrunning.OperationsProto; +import com.google.protobuf.Descriptors.DescriptorValidationException; +import com.google.protobuf.ExtensionRegistry; +import com.google.protobuf.compiler.PluginProtos.CodeGeneratorRequest; +import com.google.protobuf.compiler.PluginProtos.CodeGeneratorResponse; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; + +public class MainFromFile { + public static void main(String[] args) + throws IOException, InterruptedException, DescriptorValidationException { + ExtensionRegistry registry = ExtensionRegistry.newInstance(); + registerAllExtensions(registry); + + String inputFile = args[0]; + String outputFile = args[1]; + + try (InputStream inputStream = new FileInputStream(inputFile); + OutputStream outputStream = new FileOutputStream(outputFile); ) { + CodeGeneratorRequest request = CodeGeneratorRequest.parseFrom(inputStream, registry); + CodeGeneratorResponse response = Generator.generateGapic(request); + response.writeTo(outputStream); + } catch (IOException ex) { + ex.printStackTrace(); + } + } + + /** Register all extensions needed to process API protofiles. */ + private static void registerAllExtensions(ExtensionRegistry extensionRegistry) { + OperationsProto.registerAllExtensions(extensionRegistry); + AnnotationsProto.registerAllExtensions(extensionRegistry); + ClientProto.registerAllExtensions(extensionRegistry); + ResourceProto.registerAllExtensions(extensionRegistry); + FieldBehaviorProto.registerAllExtensions(extensionRegistry); + } +} diff --git a/src/main/java/com/google/api/generator/gapic/composer/BUILD.bazel b/src/main/java/com/google/api/generator/gapic/composer/BUILD.bazel index 58993a3eae..6610ba4f91 100644 --- a/src/main/java/com/google/api/generator/gapic/composer/BUILD.bazel +++ b/src/main/java/com/google/api/generator/gapic/composer/BUILD.bazel @@ -18,7 +18,10 @@ java_library( "//src/main/java/com/google/api/generator/engine/writer", "//src/main/java/com/google/api/generator/gapic:status_java_proto", "//src/main/java/com/google/api/generator/gapic/composer/comment", + "//src/main/java/com/google/api/generator/gapic/composer/common", "//src/main/java/com/google/api/generator/gapic/composer/defaultvalue", + "//src/main/java/com/google/api/generator/gapic/composer/grpc", + "//src/main/java/com/google/api/generator/gapic/composer/httpjson", "//src/main/java/com/google/api/generator/gapic/composer/resourcename", "//src/main/java/com/google/api/generator/gapic/composer/samplecode", "//src/main/java/com/google/api/generator/gapic/composer/store", diff --git a/src/main/java/com/google/api/generator/gapic/composer/Composer.java b/src/main/java/com/google/api/generator/gapic/composer/Composer.java index 85f5e80ce2..2d5b7c0e75 100644 --- a/src/main/java/com/google/api/generator/gapic/composer/Composer.java +++ b/src/main/java/com/google/api/generator/gapic/composer/Composer.java @@ -17,6 +17,17 @@ import com.google.api.generator.engine.ast.ClassDefinition; import com.google.api.generator.engine.ast.ScopeNode; import com.google.api.generator.gapic.composer.comment.CommentComposer; +import com.google.api.generator.gapic.composer.common.ServiceClientClassComposer; +import com.google.api.generator.gapic.composer.common.ServiceStubClassComposer; +import com.google.api.generator.gapic.composer.grpc.GrpcServiceCallableFactoryClassComposer; +import com.google.api.generator.gapic.composer.grpc.GrpcServiceStubClassComposer; +import com.google.api.generator.gapic.composer.grpc.MockServiceClassComposer; +import com.google.api.generator.gapic.composer.grpc.MockServiceImplClassComposer; +import com.google.api.generator.gapic.composer.grpc.ServiceClientTestClassComposer; +import com.google.api.generator.gapic.composer.grpc.ServiceSettingsClassComposer; +import com.google.api.generator.gapic.composer.grpc.ServiceStubSettingsClassComposer; +import com.google.api.generator.gapic.composer.httpjson.HttpJsonServiceCallableFactoryClassComposer; +import com.google.api.generator.gapic.composer.httpjson.HttpJsonServiceStubClassComposer; import com.google.api.generator.gapic.composer.resourcename.ResourceNameHelperClassComposer; import com.google.api.generator.gapic.model.GapicClass; import com.google.api.generator.gapic.model.GapicClass.Kind; @@ -24,6 +35,7 @@ import com.google.api.generator.gapic.model.GapicPackageInfo; import com.google.api.generator.gapic.model.ResourceName; import com.google.api.generator.gapic.model.Service; +import com.google.api.generator.gapic.model.Transport; import com.google.common.annotations.VisibleForTesting; import java.util.ArrayList; import java.util.List; @@ -71,9 +83,20 @@ public static List generateStubClasses(GapicContext context) { .forEach( s -> { clazzes.add(ServiceStubClassComposer.instance().generate(context, s)); - clazzes.add(ServiceStubSettingsClassComposer.instance().generate(context, s)); - clazzes.add(GrpcServiceCallableFactoryClassComposer.instance().generate(context, s)); - clazzes.add(GrpcServiceStubClassComposer.instance().generate(context, s)); + if (context.transport() == Transport.REST) { + clazzes.add( + com.google.api.generator.gapic.composer.httpjson + .ServiceStubSettingsClassComposer.instance() + .generate(context, s)); + clazzes.add( + HttpJsonServiceCallableFactoryClassComposer.instance().generate(context, s)); + clazzes.add(HttpJsonServiceStubClassComposer.instance().generate(context, s)); + } else { + clazzes.add(ServiceStubSettingsClassComposer.instance().generate(context, s)); + clazzes.add( + GrpcServiceCallableFactoryClassComposer.instance().generate(context, s)); + clazzes.add(GrpcServiceStubClassComposer.instance().generate(context, s)); + } }); return clazzes; } @@ -85,7 +108,14 @@ public static List generateClientSettingsClasses(GapicContext contex .forEach( s -> { clazzes.add(ServiceClientClassComposer.instance().generate(context, s)); - clazzes.add(ServiceSettingsClassComposer.instance().generate(context, s)); + if (context.transport() == Transport.REST) { + clazzes.add( + com.google.api.generator.gapic.composer.httpjson.ServiceSettingsClassComposer + .instance() + .generate(context, s)); + } else { + clazzes.add(ServiceSettingsClassComposer.instance().generate(context, s)); + } }); return clazzes; } @@ -94,15 +124,28 @@ public static List generateMockClasses(GapicContext context, List clazzes = new ArrayList<>(); services.forEach( s -> { - clazzes.add(MockServiceClassComposer.instance().generate(context, s)); - clazzes.add(MockServiceImplClassComposer.instance().generate(context, s)); + if (context.transport() == Transport.REST) { + // REST transport tests donot not use mock services. + } else { + clazzes.add(MockServiceClassComposer.instance().generate(context, s)); + clazzes.add(MockServiceImplClassComposer.instance().generate(context, s)); + } }); return clazzes; } public static List generateTestClasses(GapicContext context) { return context.services().stream() - .map(s -> ServiceClientTestClassComposer.instance().generate(context, s)) + .map( + s -> { + if (context.transport() == Transport.REST) { + return com.google.api.generator.gapic.composer.httpjson + .ServiceClientTestClassComposer.instance() + .generate(context, s); + } else { + return ServiceClientTestClassComposer.instance().generate(context, s); + } + }) .collect(Collectors.toList()); } diff --git a/src/main/java/com/google/api/generator/gapic/composer/comment/SettingsCommentComposer.java b/src/main/java/com/google/api/generator/gapic/composer/comment/SettingsCommentComposer.java index 8ae59bb055..5e10eb9cd5 100644 --- a/src/main/java/com/google/api/generator/gapic/composer/comment/SettingsCommentComposer.java +++ b/src/main/java/com/google/api/generator/gapic/composer/comment/SettingsCommentComposer.java @@ -67,7 +67,7 @@ public class SettingsCommentComposer { public static final CommentStatement DEFAULT_CREDENTIALS_PROVIDER_BUILDER_METHOD_COMMENT = toSimpleComment("Returns a builder for the default credentials for this service."); - public static final CommentStatement DEFAULT_GRPC_TRANSPORT_PROVIDER_BUILDER_METHOD_COMMENT = + public static final CommentStatement DEFAULT_TRANSPORT_PROVIDER_BUILDER_METHOD_COMMENT = toSimpleComment("Returns a builder for the default ChannelProvider for this service."); public static final CommentStatement NEW_BUILDER_METHOD_COMMENT = diff --git a/src/main/java/com/google/api/generator/gapic/composer/comment/StubCommentComposer.java b/src/main/java/com/google/api/generator/gapic/composer/comment/StubCommentComposer.java index ac20d5845c..8ce682188f 100644 --- a/src/main/java/com/google/api/generator/gapic/composer/comment/StubCommentComposer.java +++ b/src/main/java/com/google/api/generator/gapic/composer/comment/StubCommentComposer.java @@ -22,44 +22,53 @@ public class StubCommentComposer { private static final String STUB_CLASS_HEADER_SUMMARY_PATTERN = "Base stub class for the %s service API."; - private static final String GRPC_CALLABLE_FACTORY_CLASS_HEADER_SUMMARY_PATTERN = - "gRPC callable factory implementation for the %s service API."; - private static final String GRPC_STUB_CLASS_HEADER_SUMMARY_PATTERN = - "gRPC stub implementation for the %s service API."; + private static final String TRANSPORT_CALLABLE_FACTORY_CLASS_HEADER_SUMMARY_PATTERN = + "%s callable factory implementation for the %s service API."; + private static final String TRANSPORT_STUB_CLASS_HEADER_SUMMARY_PATTERN = + "%s stub implementation for the %s service API."; private static final String ADVANCED_USAGE_DESCRIPTION = "This class is for advanced usage."; private static final String ADVANCED_USAGE_API_REFLECTION_DESCRIPTION = "This class is for advanced usage and reflects the underlying API directly."; - public static List createGrpcServiceStubClassHeaderComments( + private final String transportPrefix; + + public StubCommentComposer(String transportPrefix) { + this.transportPrefix = transportPrefix; + } + + public List createTransportServiceStubClassHeaderComments( String serviceName, boolean isDeprecated) { JavaDocComment.Builder javaDocBuilder = JavaDocComment.builder(); if (isDeprecated) { javaDocBuilder = javaDocBuilder.setDeprecated(CommentComposer.DEPRECATED_CLASS_STRING); } - return Arrays.asList( CommentComposer.AUTO_GENERATED_CLASS_COMMENT, CommentStatement.withComment( javaDocBuilder - .addComment(String.format(GRPC_STUB_CLASS_HEADER_SUMMARY_PATTERN, serviceName)) + .addComment( + String.format( + TRANSPORT_STUB_CLASS_HEADER_SUMMARY_PATTERN, transportPrefix, serviceName)) .addParagraph(ADVANCED_USAGE_API_REFLECTION_DESCRIPTION) .build())); } - public static List createGrpcServiceCallableFactoryClassHeaderComments( + public List createTransportServiceCallableFactoryClassHeaderComments( String serviceName, boolean isDeprecated) { JavaDocComment.Builder javaDocBuilder = JavaDocComment.builder(); if (isDeprecated) { javaDocBuilder = javaDocBuilder.setDeprecated(CommentComposer.DEPRECATED_CLASS_STRING); } - return Arrays.asList( CommentComposer.AUTO_GENERATED_CLASS_COMMENT, CommentStatement.withComment( javaDocBuilder .addComment( - String.format(GRPC_CALLABLE_FACTORY_CLASS_HEADER_SUMMARY_PATTERN, serviceName)) + String.format( + TRANSPORT_CALLABLE_FACTORY_CLASS_HEADER_SUMMARY_PATTERN, + transportPrefix, + serviceName)) .addParagraph(ADVANCED_USAGE_DESCRIPTION) .build())); } diff --git a/src/main/java/com/google/api/generator/gapic/composer/GrpcServiceCallableFactoryClassComposer.java b/src/main/java/com/google/api/generator/gapic/composer/common/AbstractServiceCallableFactoryClassComposer.java similarity index 57% rename from src/main/java/com/google/api/generator/gapic/composer/GrpcServiceCallableFactoryClassComposer.java rename to src/main/java/com/google/api/generator/gapic/composer/common/AbstractServiceCallableFactoryClassComposer.java index c770d7cd76..649fb50954 100644 --- a/src/main/java/com/google/api/generator/gapic/composer/GrpcServiceCallableFactoryClassComposer.java +++ b/src/main/java/com/google/api/generator/gapic/composer/common/AbstractServiceCallableFactoryClassComposer.java @@ -12,12 +12,9 @@ // See the License for the specific language governing permissions and // limitations under the License. -package com.google.api.generator.gapic.composer; +package com.google.api.generator.gapic.composer.common; import com.google.api.core.BetaApi; -import com.google.api.gax.grpc.GrpcCallSettings; -import com.google.api.gax.grpc.GrpcCallableFactory; -import com.google.api.gax.grpc.GrpcStubCallableFactory; import com.google.api.gax.rpc.BatchingCallSettings; import com.google.api.gax.rpc.BidiStreamingCallable; import com.google.api.gax.rpc.ClientContext; @@ -47,28 +44,42 @@ import com.google.api.generator.gapic.model.GapicContext; import com.google.api.generator.gapic.model.Service; import com.google.common.base.Preconditions; -import com.google.longrunning.Operation; import java.util.ArrayList; import java.util.Arrays; import java.util.List; import java.util.stream.Collectors; import javax.annotation.Generated; -public class GrpcServiceCallableFactoryClassComposer implements ClassComposer { - private static final GrpcServiceCallableFactoryClassComposer INSTANCE = - new GrpcServiceCallableFactoryClassComposer(); - private static final String DOT = "."; +public abstract class AbstractServiceCallableFactoryClassComposer implements ClassComposer { - private GrpcServiceCallableFactoryClassComposer() {} + private final TypeStore fixedTypeStore; + private final StubCommentComposer commentComposer; + private final ClassNames classNames; + private final Class transportCallSettingsClass; + private final Class transportCallableFactoryClass; + private final Class operationStubClass; + private final String transportCallSettingsName; - public static GrpcServiceCallableFactoryClassComposer instance() { - return INSTANCE; + protected AbstractServiceCallableFactoryClassComposer( + TypeStore fixedTypeStore, + StubCommentComposer commentComposer, + ClassNames classNames, + Class transportCallSettingsClass, + Class transportCallableFactoryClass, + Class operationStubClass, + String transportCallSettingsName) { + this.fixedTypeStore = fixedTypeStore; + this.commentComposer = commentComposer; + this.classNames = classNames; + this.transportCallSettingsClass = transportCallSettingsClass; + this.transportCallableFactoryClass = transportCallableFactoryClass; + this.operationStubClass = operationStubClass; + this.transportCallSettingsName = transportCallSettingsName; } @Override public GapicClass generate(GapicContext ignored, Service service) { - TypeStore typeStore = createTypes(service); - String className = ClassNames.getGrpcServiceCallableFactoryClassName(service); + String className = getClassNames().getTransportServiceCallableFactoryClassName(service); GapicClass.Kind kind = Kind.STUB; String pakkage = String.format("%s.stub", service.pakkage()); @@ -76,18 +87,46 @@ public GapicClass generate(GapicContext ignored, Service service) { ClassDefinition.builder() .setPackageString(pakkage) .setHeaderCommentStatements( - StubCommentComposer.createGrpcServiceCallableFactoryClassHeaderComments( + getCommentComposer().createTransportServiceCallableFactoryClassHeaderComments( service.name(), service.isDeprecated())) - .setAnnotations(createClassAnnotations(service, typeStore)) - .setImplementsTypes(createClassImplements(typeStore)) + .setAnnotations(createClassAnnotations(service, fixedTypeStore)) + .setImplementsTypes(createClassImplements(fixedTypeStore)) .setName(className) - .setMethods(createClassMethods(typeStore)) + .setMethods(createClassMethods(fixedTypeStore)) .setScope(ScopeNode.PUBLIC) .build(); return GapicClass.create(kind, classDef); } - private static List createClassAnnotations(Service service, TypeStore typeStore) { + protected TypeStore getFixedTypeStore() { + return fixedTypeStore; + } + + protected StubCommentComposer getCommentComposer() { + return commentComposer; + } + + protected ClassNames getClassNames() { + return classNames; + } + + protected Class getTransportCallSettingsClass() { + return transportCallSettingsClass; + } + + protected Class getTransportCallableFactoryClass() { + return transportCallableFactoryClass; + } + + protected Class getOperationStubClass() { + return operationStubClass; + } + + protected String getTransportCallSettingsName() { + return transportCallSettingsName; + } + + protected List createClassAnnotations(Service service, TypeStore typeStore) { List annotations = new ArrayList<>(); if (!PackageChecker.isGaApi(service.pakkage())) { annotations.add(AnnotationNode.withType(typeStore.get("BetaApi"))); @@ -105,22 +144,17 @@ private static List createClassAnnotations(Service service, Type return annotations; } - private static List createClassImplements(TypeStore typeStore) { - return Arrays.asList(typeStore.get("GrpcStubCallableFactory")); - } + protected abstract List createClassImplements(TypeStore typeStore); - private static List createClassMethods(TypeStore typeStore) { + protected List createClassMethods(TypeStore typeStore) { return Arrays.asList( createUnaryCallableMethod(typeStore), createPagedCallableMethod(typeStore), createBatchingCallableMethod(typeStore), - createOperationCallableMethod(typeStore), - createBidiStreamingCallableMethod(typeStore), - createServerStreamingCallableMethod(typeStore), - createClientStreamingCallableMethod(typeStore)); + createOperationCallableMethod(typeStore)); } - private static MethodDefinition createUnaryCallableMethod(TypeStore typeStore) { + protected MethodDefinition createUnaryCallableMethod(TypeStore typeStore) { String methodVariantName = "Unary"; String requestTemplateName = "RequestT"; String responseTemplateName = "ResponseT"; @@ -131,7 +165,7 @@ private static MethodDefinition createUnaryCallableMethod(TypeStore typeStore) { /*returnCallableKindName=*/ methodVariantName, /*returnCallableTemplateNames=*/ methodTemplateNames, /*methodVariantName=*/ methodVariantName, - /*grpcCallSettingsTemplateObjects=*/ methodTemplateNames.stream() + /*transportCallSettingsTemplateObjects=*/ methodTemplateNames.stream() .map(n -> (Object) n) .collect(Collectors.toList()), /*callSettingsVariantName=*/ methodVariantName, @@ -140,7 +174,7 @@ private static MethodDefinition createUnaryCallableMethod(TypeStore typeStore) { .collect(Collectors.toList())); } - private static MethodDefinition createPagedCallableMethod(TypeStore typeStore) { + protected MethodDefinition createPagedCallableMethod(TypeStore typeStore) { String methodVariantName = "Paged"; String requestTemplateName = "RequestT"; String pagedResponseTemplateName = "PagedListResponseT"; @@ -154,7 +188,7 @@ private static MethodDefinition createPagedCallableMethod(TypeStore typeStore) { /*returnCallableTemplateNames=*/ Arrays.asList( requestTemplateName, pagedResponseTemplateName), /*methodVariantName=*/ methodVariantName, - /*grpcCallSettingsTemplateObjects=*/ Arrays.asList( + /*transportCallSettingsTemplateObjects=*/ Arrays.asList( requestTemplateName, responseTemplateName), /*callSettingsVariantName=*/ methodVariantName, /*callSettingsTemplateObjects=*/ methodTemplateNames.stream() @@ -162,7 +196,7 @@ private static MethodDefinition createPagedCallableMethod(TypeStore typeStore) { .collect(Collectors.toList())); } - private static MethodDefinition createBatchingCallableMethod(TypeStore typeStore) { + protected MethodDefinition createBatchingCallableMethod(TypeStore typeStore) { String methodVariantName = "Batching"; String requestTemplateName = "RequestT"; String responseTemplateName = "ResponseT"; @@ -173,67 +207,7 @@ private static MethodDefinition createBatchingCallableMethod(TypeStore typeStore /*returnCallableKindName=*/ "Unary", /*returnCallableTemplateNames=*/ methodTemplateNames, /*methodVariantName=*/ methodVariantName, - /*grpcCallSettingsTemplateObjects=*/ methodTemplateNames.stream() - .map(n -> (Object) n) - .collect(Collectors.toList()), - /*callSettingsVariantName=*/ methodVariantName, - /*callSettingsTemplateObjects=*/ methodTemplateNames.stream() - .map(n -> (Object) n) - .collect(Collectors.toList())); - } - - private static MethodDefinition createOperationCallableMethod(TypeStore typeStore) { - String methodVariantName = "Operation"; - String requestTemplateName = "RequestT"; - String responseTemplateName = "ResponseT"; - List methodTemplateNames = - Arrays.asList(requestTemplateName, responseTemplateName, "MetadataT"); - return createGenericCallableMethod( - typeStore, - /*methodTemplateNames=*/ methodTemplateNames, - /*returnCallableKindName=*/ methodVariantName, - /*returnCallableTemplateNames=*/ methodTemplateNames, - /*methodVariantName=*/ methodVariantName, - /*grpcCallSettingsTemplateObjects=*/ Arrays.asList( - requestTemplateName, typeStore.get("Operation")), - /*callSettingsVariantName=*/ methodVariantName, - /*callSettingsTemplateObjects=*/ methodTemplateNames.stream() - .map(n -> (Object) n) - .collect(Collectors.toList())); - } - - private static MethodDefinition createBidiStreamingCallableMethod(TypeStore typeStore) { - String methodVariantName = "BidiStreaming"; - String requestTemplateName = "RequestT"; - String responseTemplateName = "ResponseT"; - List methodTemplateNames = Arrays.asList(requestTemplateName, responseTemplateName); - return createGenericCallableMethod( - typeStore, - /*methodTemplateNames=*/ methodTemplateNames, - /*returnCallableKindName=*/ methodVariantName, - /*returnCallableTemplateNames=*/ methodTemplateNames, - /*methodVariantName=*/ methodVariantName, - /*grpcCallSettingsTemplateObjects=*/ methodTemplateNames.stream() - .map(n -> (Object) n) - .collect(Collectors.toList()), - /*callSettingsVariantName=*/ "Streaming", - /*callSettingsTemplateObjects=*/ methodTemplateNames.stream() - .map(n -> (Object) n) - .collect(Collectors.toList())); - } - - private static MethodDefinition createServerStreamingCallableMethod(TypeStore typeStore) { - String methodVariantName = "ServerStreaming"; - String requestTemplateName = "RequestT"; - String responseTemplateName = "ResponseT"; - List methodTemplateNames = Arrays.asList(requestTemplateName, responseTemplateName); - return createGenericCallableMethod( - typeStore, - /*methodTemplateNames=*/ methodTemplateNames, - /*returnCallableKindName=*/ methodVariantName, - /*returnCallableTemplateNames=*/ methodTemplateNames, - /*methodVariantName=*/ methodVariantName, - /*grpcCallSettingsTemplateObjects=*/ methodTemplateNames.stream() + /*transportCallSettingsTemplateObjects=*/ methodTemplateNames.stream() .map(n -> (Object) n) .collect(Collectors.toList()), /*callSettingsVariantName=*/ methodVariantName, @@ -242,40 +216,22 @@ private static MethodDefinition createServerStreamingCallableMethod(TypeStore ty .collect(Collectors.toList())); } - private static MethodDefinition createClientStreamingCallableMethod(TypeStore typeStore) { - String methodVariantName = "ClientStreaming"; - String requestTemplateName = "RequestT"; - String responseTemplateName = "ResponseT"; - List methodTemplateNames = Arrays.asList(requestTemplateName, responseTemplateName); - return createGenericCallableMethod( - typeStore, - /*methodTemplateNames=*/ methodTemplateNames, - /*returnCallableKindName=*/ methodVariantName, - /*returnCallableTemplateNames=*/ methodTemplateNames, - /*methodVariantName=*/ methodVariantName, - /*grpcCallSettingsTemplateObjects=*/ methodTemplateNames.stream() - .map(n -> (Object) n) - .collect(Collectors.toList()), - /*callSettingsVariantName=*/ "Streaming", - /*callSettingsTemplateObjects=*/ methodTemplateNames.stream() - .map(n -> (Object) n) - .collect(Collectors.toList())); - } + protected abstract MethodDefinition createOperationCallableMethod(TypeStore typeStore); - private static MethodDefinition createGenericCallableMethod( + protected MethodDefinition createGenericCallableMethod( TypeStore typeStore, List methodTemplateNames, String returnCallableKindName, List returnCallableTemplateNames, String methodVariantName, - List grpcCallSettingsTemplateObjects, + List transportCallSettingsTemplateObjects, String callSettingsVariantName, List callSettingsTemplateObjects) { String methodName = String.format("create%sCallable", methodVariantName); String callSettingsTypeName = String.format("%sCallSettings", callSettingsVariantName); String returnTypeName = String.format("%sCallable", returnCallableKindName); - String grpcCallSettingsTypeName = "GrpcCallSettings"; + String transportCallSettingsTypeName = getTransportCallSettingsClass().getSimpleName(); boolean isOperationCallable = methodVariantName.equals("Operation"); List arguments = new ArrayList<>(); @@ -283,11 +239,11 @@ private static MethodDefinition createGenericCallableMethod( VariableExpr.builder() .setVariable( Variable.builder() - .setName("grpcCallSettings") - .setType(typeStore.get(grpcCallSettingsTypeName)) + .setName(getTransportCallSettingsName()) + .setType(typeStore.get(transportCallSettingsTypeName)) .build()) .setIsDecl(true) - .setTemplateObjects(grpcCallSettingsTemplateObjects) + .setTemplateObjects(transportCallSettingsTemplateObjects) .build()); arguments.add( VariableExpr.builder() @@ -314,22 +270,23 @@ private static MethodDefinition createGenericCallableMethod( .setVariable( Variable.builder() .setName("operationsStub") - .setType(typeStore.get("OperationsStub")) + .setType(typeStore.get(getOperationStubClass().getSimpleName())) .build()) .setIsDecl(true) .build()); } - String grpcCallableFactoryTypeName = "GrpcCallableFactory"; - TypeNode grpcCallableFactoryType = typeStore.get(grpcCallableFactoryTypeName); + String transportCallableFactoryTypeName = getTransportCallableFactoryClass().getSimpleName(); + TypeNode transportCallableFactoryType = typeStore.get(transportCallableFactoryTypeName); Preconditions.checkNotNull( - grpcCallableFactoryType, String.format("Type %s not found", grpcCallableFactoryTypeName)); + transportCallableFactoryType, + String.format("Type %s not found", transportCallableFactoryTypeName)); TypeNode returnType = typeStore.get(returnTypeName); MethodInvocationExpr returnExpr = MethodInvocationExpr.builder() .setMethodName(methodName) - .setStaticReferenceType(grpcCallableFactoryType) + .setStaticReferenceType(transportCallableFactoryType) .setArguments( arguments.stream() .map(v -> v.toBuilder().setIsDecl(false).build()) @@ -349,7 +306,7 @@ private static MethodDefinition createGenericCallableMethod( .build(); } - private static TypeStore createTypes(Service service) { + protected static TypeStore createCommonTypes() { List concreteClazzes = Arrays.asList( // Gax-java classes. @@ -366,15 +323,8 @@ private static TypeStore createTypes(Service service) { StreamingCallSettings.class, UnaryCallSettings.class, UnaryCallable.class, - // gax-java gRPC classes. - GrpcCallSettings.class, - GrpcCallableFactory.class, - GrpcStubCallableFactory.class, Generated.class, - Operation.class, UnsupportedOperationException.class); - TypeStore typeStore = new TypeStore(concreteClazzes); - typeStore.put("com.google.longrunning.stub", "OperationsStub"); - return typeStore; + return new TypeStore(concreteClazzes); } } diff --git a/src/main/java/com/google/api/generator/gapic/composer/ServiceClientTestClassComposer.java b/src/main/java/com/google/api/generator/gapic/composer/common/AbstractServiceClientTestClassComposer.java similarity index 69% rename from src/main/java/com/google/api/generator/gapic/composer/ServiceClientTestClassComposer.java rename to src/main/java/com/google/api/generator/gapic/composer/common/AbstractServiceClientTestClassComposer.java index 0283c9476c..f10664ea13 100644 --- a/src/main/java/com/google/api/generator/gapic/composer/ServiceClientTestClassComposer.java +++ b/src/main/java/com/google/api/generator/gapic/composer/common/AbstractServiceClientTestClassComposer.java @@ -12,13 +12,9 @@ // See the License for the specific language governing permissions and // limitations under the License. -package com.google.api.generator.gapic.composer; +package com.google.api.generator.gapic.composer.common; -import com.google.api.gax.core.GoogleCredentialsProvider; -import com.google.api.gax.core.InstantiatingExecutorProvider; import com.google.api.gax.core.NoCredentialsProvider; -import com.google.api.gax.grpc.GaxGrpcProperties; -import com.google.api.gax.grpc.InstantiatingGrpcChannelProvider; import com.google.api.gax.rpc.ApiClientHeaderProvider; import com.google.api.gax.rpc.ApiStreamObserver; import com.google.api.gax.rpc.BidiStreamingCallable; @@ -75,19 +71,15 @@ import com.google.longrunning.Operation; import com.google.protobuf.AbstractMessage; import com.google.protobuf.Any; -import io.grpc.StatusRuntimeException; import java.io.IOException; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; -import java.util.LinkedHashMap; import java.util.List; import java.util.Map; import java.util.Optional; import java.util.UUID; import java.util.concurrent.ExecutionException; -import java.util.function.BiFunction; -import java.util.function.Function; import java.util.stream.Collectors; import javax.annotation.Generated; import org.junit.After; @@ -97,41 +89,22 @@ import org.junit.BeforeClass; import org.junit.Test; -public class ServiceClientTestClassComposer implements ClassComposer { - private static final Statement EMPTY_LINE_STATEMENT = EmptyLineStatement.create(); +public abstract class AbstractServiceClientTestClassComposer implements ClassComposer { + protected static final Statement EMPTY_LINE_STATEMENT = EmptyLineStatement.create(); - private static final String CHANNEL_PROVIDER_VAR_NAME = "channelProvider"; - private static final String CLASS_NAME_PATTERN = "%sClientTest"; - private static final String CLIENT_VAR_NAME = "client"; - private static final String GRPC_TESTING_PACKAGE = "com.google.api.gax.grpc.testing"; + protected static final String CLIENT_VAR_NAME = "client"; private static final String MOCK_SERVICE_VAR_NAME_PATTERN = "mock%s"; private static final String PAGED_RESPONSE_TYPE_NAME_PATTERN = "%sPagedResponse"; - private static final String SERVICE_HELPER_VAR_NAME = "mockServiceHelper"; - private static final String STUB_SETTINGS_PATTERN = "%sSettings"; - - private static final ServiceClientTestClassComposer INSTANCE = - new ServiceClientTestClassComposer(); - - private static final TypeStore FIXED_TYPESTORE = createStaticTypes(); - private static final TypeNode LIST_TYPE = - TypeNode.withReference(ConcreteReference.withClazz(List.class)); - private static final TypeNode MAP_TYPE = - TypeNode.withReference(ConcreteReference.withClazz(Map.class)); - private static final TypeNode RESOURCE_NAME_TYPE = - TypeNode.withReference( - ConcreteReference.withClazz(com.google.api.resourcenames.ResourceName.class)); - - private static final AnnotationNode TEST_ANNOTATION = - AnnotationNode.withType(FIXED_TYPESTORE.get("Test")); - // Avoid conflicting types with com.google.rpc.Status. - private static final TypeNode GRPC_STATUS_TYPE = - TypeNode.withReference( - ConcreteReference.builder().setClazz(io.grpc.Status.class).setUseFullName(true).build()); - - private ServiceClientTestClassComposer() {} - - public static ServiceClientTestClassComposer instance() { - return INSTANCE; + + private final TypeStore fixedTypeStore; + private final ClassNames classNames; + private final AnnotationNode testAnnotation; + + protected AbstractServiceClientTestClassComposer( + TypeStore fixedTypeStore, ClassNames classNames) { + this.fixedTypeStore = fixedTypeStore; + this.classNames = classNames; + this.testAnnotation = AnnotationNode.withType(fixedTypeStore.get("Test")); } @Override @@ -160,35 +133,30 @@ public GapicClass generate(GapicContext context, Service service) { return GapicClass.create(kind, classDef); } - private static List createClassAnnotations() { + protected TypeStore getFixedTypeStore() { + return fixedTypeStore; + } + + protected ClassNames getClassNames() { + return classNames; + } + + protected AnnotationNode getTestAnnotation() { + return testAnnotation; + } + + private List createClassAnnotations() { return Arrays.asList( AnnotationNode.builder() - .setType(FIXED_TYPESTORE.get("Generated")) + .setType(getFixedTypeStore().get("Generated")) .setDescription("by gapic-generator-java") .build()); } - private static Map createClassMemberVarExprs( - Service service, GapicContext context, TypeStore typeStore) { - BiFunction varExprFn = - (name, type) -> - VariableExpr.withVariable(Variable.builder().setName(name).setType(type).build()); - Map fields = new LinkedHashMap<>(); - fields.put( - getMockServiceVarName(service), typeStore.get(ClassNames.getMockServiceClassName(service))); - for (Service mixinService : context.mixinServices()) { - fields.put( - getMockServiceVarName(mixinService), - typeStore.get(ClassNames.getMockServiceClassName(mixinService))); - } - fields.put(SERVICE_HELPER_VAR_NAME, FIXED_TYPESTORE.get("MockServiceHelper")); - fields.put(CLIENT_VAR_NAME, typeStore.get(ClassNames.getServiceClientClassName(service))); - fields.put(CHANNEL_PROVIDER_VAR_NAME, FIXED_TYPESTORE.get("LocalChannelProvider")); - return fields.entrySet().stream() - .collect(Collectors.toMap(e -> e.getKey(), e -> varExprFn.apply(e.getKey(), e.getValue()))); - } + protected abstract Map createClassMemberVarExprs( + Service service, GapicContext context, TypeStore typeStore); - private static List createClassMemberFieldDecls( + protected List createClassMemberFieldDecls( Map classMemberVarExprs) { return classMemberVarExprs.values().stream() .map( @@ -202,7 +170,7 @@ private static List createClassMemberFieldDecls( .collect(Collectors.toList()); } - private static List createClassMethods( + private List createClassMethods( Service service, GapicContext context, Map classMemberVarExprs, @@ -214,225 +182,36 @@ private static List createClassMethods( return javaMethods; } - private static List createTestAdminMethods( + private List createTestAdminMethods( Service service, GapicContext context, Map classMemberVarExprs, TypeStore typeStore) { List javaMethods = new ArrayList<>(); - javaMethods.add(createStartStaticServerMethod(service, context, classMemberVarExprs)); + javaMethods.add( + createStartStaticServerMethod(service, context, classMemberVarExprs, typeStore)); javaMethods.add(createStopServerMethod(service, classMemberVarExprs)); javaMethods.add(createSetUpMethod(service, classMemberVarExprs, typeStore)); javaMethods.add(createTearDownMethod(service, classMemberVarExprs)); return javaMethods; } - private static MethodDefinition createStartStaticServerMethod( - Service service, GapicContext context, Map classMemberVarExprs) { - VariableExpr serviceHelperVarExpr = classMemberVarExprs.get(SERVICE_HELPER_VAR_NAME); - Function serviceToVarExprFn = - s -> classMemberVarExprs.get(getMockServiceVarName(s)); - Function serviceToVarInitExprFn = - s -> { - VariableExpr mockServiceVarExpr = serviceToVarExprFn.apply(s); - return AssignmentExpr.builder() - .setVariableExpr(mockServiceVarExpr) - .setValueExpr(NewObjectExpr.builder().setType(mockServiceVarExpr.type()).build()) - .build(); - }; - List varInitExprs = new ArrayList<>(); - List mockServiceVarExprs = new ArrayList<>(); - varInitExprs.add(serviceToVarInitExprFn.apply(service)); - mockServiceVarExprs.add(serviceToVarExprFn.apply(service)); - for (Service mixinService : context.mixinServices()) { - varInitExprs.add(serviceToVarInitExprFn.apply(mixinService)); - mockServiceVarExprs.add(serviceToVarExprFn.apply(mixinService)); - } - - MethodInvocationExpr firstArg = - MethodInvocationExpr.builder() - .setStaticReferenceType(FIXED_TYPESTORE.get("UUID")) - .setMethodName("randomUUID") - .build(); - firstArg = - MethodInvocationExpr.builder() - .setExprReferenceExpr(firstArg) - .setMethodName("toString") - .build(); - - MethodInvocationExpr secondArg = - MethodInvocationExpr.builder() - .setStaticReferenceType(FIXED_TYPESTORE.get("Arrays")) - .setGenerics(Arrays.asList(FIXED_TYPESTORE.get("MockGrpcService").reference())) - .setMethodName("asList") - .setArguments(mockServiceVarExprs) - .build(); - - Expr initServiceHelperExpr = - AssignmentExpr.builder() - .setVariableExpr(serviceHelperVarExpr) - .setValueExpr( - NewObjectExpr.builder() - .setType(serviceHelperVarExpr.type()) - .setArguments(Arrays.asList(firstArg, secondArg)) - .build()) - .build(); - - Expr startServiceHelperExpr = - MethodInvocationExpr.builder() - .setExprReferenceExpr(serviceHelperVarExpr) - .setMethodName("start") - .build(); - varInitExprs.add(initServiceHelperExpr); - varInitExprs.add(startServiceHelperExpr); - - return MethodDefinition.builder() - .setAnnotations(Arrays.asList(AnnotationNode.withType(FIXED_TYPESTORE.get("BeforeClass")))) - .setScope(ScopeNode.PUBLIC) - .setIsStatic(true) - .setReturnType(TypeNode.VOID) - .setName("startStaticServer") - .setBody( - varInitExprs.stream().map(e -> ExprStatement.withExpr(e)).collect(Collectors.toList())) - .build(); - } - - private static MethodDefinition createStopServerMethod( - Service service, Map classMemberVarExprs) { - return MethodDefinition.builder() - .setAnnotations(Arrays.asList(AnnotationNode.withType(FIXED_TYPESTORE.get("AfterClass")))) - .setScope(ScopeNode.PUBLIC) - .setIsStatic(true) - .setReturnType(TypeNode.VOID) - .setName("stopServer") - .setBody( - Arrays.asList( - ExprStatement.withExpr( - MethodInvocationExpr.builder() - .setExprReferenceExpr(classMemberVarExprs.get(SERVICE_HELPER_VAR_NAME)) - .setMethodName("stop") - .build()))) - .build(); - } - - private static MethodDefinition createSetUpMethod( - Service service, Map classMemberVarExprs, TypeStore typeStore) { - VariableExpr clientVarExpr = classMemberVarExprs.get(CLIENT_VAR_NAME); - VariableExpr serviceHelperVarExpr = classMemberVarExprs.get(SERVICE_HELPER_VAR_NAME); - VariableExpr channelProviderVarExpr = classMemberVarExprs.get(CHANNEL_PROVIDER_VAR_NAME); - - Expr resetServiceHelperExpr = - MethodInvocationExpr.builder() - .setExprReferenceExpr(serviceHelperVarExpr) - .setMethodName("reset") - .build(); - Expr channelProviderInitExpr = - AssignmentExpr.builder() - .setVariableExpr(channelProviderVarExpr) - .setValueExpr( - MethodInvocationExpr.builder() - .setExprReferenceExpr(serviceHelperVarExpr) - .setMethodName("createChannelProvider") - .setReturnType(channelProviderVarExpr.type()) - .build()) - .build(); - - TypeNode settingsType = typeStore.get(ClassNames.getServiceSettingsClassName(service)); - VariableExpr localSettingsVarExpr = - VariableExpr.withVariable( - Variable.builder().setName("settings").setType(settingsType).build()); - - Expr settingsBuilderExpr = - MethodInvocationExpr.builder() - .setStaticReferenceType(settingsType) - .setMethodName("newBuilder") - .build(); - Function> methodBuilderFn = - methodExpr -> - (mName, argExpr) -> - MethodInvocationExpr.builder() - .setExprReferenceExpr(methodExpr) - .setMethodName(mName) - .setArguments(Arrays.asList(argExpr)) - .build(); - settingsBuilderExpr = - methodBuilderFn - .apply(settingsBuilderExpr) - .apply( - "setTransportChannelProvider", classMemberVarExprs.get(CHANNEL_PROVIDER_VAR_NAME)); - settingsBuilderExpr = - methodBuilderFn - .apply(settingsBuilderExpr) - .apply( - "setCredentialsProvider", - MethodInvocationExpr.builder() - .setStaticReferenceType(FIXED_TYPESTORE.get("NoCredentialsProvider")) - .setMethodName("create") - .build()); - settingsBuilderExpr = - MethodInvocationExpr.builder() - .setExprReferenceExpr(settingsBuilderExpr) - .setMethodName("build") - .setReturnType(localSettingsVarExpr.type()) - .build(); - - Expr initLocalSettingsExpr = - AssignmentExpr.builder() - .setVariableExpr(localSettingsVarExpr.toBuilder().setIsDecl(true).build()) - .setValueExpr(settingsBuilderExpr) - .build(); + protected abstract MethodDefinition createStartStaticServerMethod( + Service service, + GapicContext context, + Map classMemberVarExprs, + TypeStore typeStore); - Expr initClientExpr = - AssignmentExpr.builder() - .setVariableExpr(clientVarExpr) - .setValueExpr( - MethodInvocationExpr.builder() - .setStaticReferenceType( - typeStore.get(ClassNames.getServiceClientClassName(service))) - .setMethodName("create") - .setArguments(Arrays.asList(localSettingsVarExpr)) - .setReturnType(clientVarExpr.type()) - .build()) - .build(); + protected abstract MethodDefinition createStopServerMethod( + Service service, Map classMemberVarExprs); - return MethodDefinition.builder() - .setAnnotations(Arrays.asList(AnnotationNode.withType(FIXED_TYPESTORE.get("Before")))) - .setScope(ScopeNode.PUBLIC) - .setReturnType(TypeNode.VOID) - .setName("setUp") - .setThrowsExceptions(Arrays.asList(FIXED_TYPESTORE.get("IOException"))) - .setBody( - Arrays.asList( - resetServiceHelperExpr, - channelProviderInitExpr, - initLocalSettingsExpr, - initClientExpr) - .stream() - .map(e -> ExprStatement.withExpr(e)) - .collect(Collectors.toList())) - .build(); - } + protected abstract MethodDefinition createSetUpMethod( + Service service, Map classMemberVarExprs, TypeStore typeStore); - private static MethodDefinition createTearDownMethod( - Service service, Map classMemberVarExprs) { - return MethodDefinition.builder() - .setAnnotations(Arrays.asList(AnnotationNode.withType(FIXED_TYPESTORE.get("After")))) - .setScope(ScopeNode.PUBLIC) - .setReturnType(TypeNode.VOID) - .setName("tearDown") - .setThrowsExceptions( - Arrays.asList(TypeNode.withReference(ConcreteReference.withClazz(Exception.class)))) - .setBody( - Arrays.asList( - ExprStatement.withExpr( - MethodInvocationExpr.builder() - .setExprReferenceExpr(classMemberVarExprs.get(CLIENT_VAR_NAME)) - .setMethodName("close") - .build()))) - .build(); - } + protected abstract MethodDefinition createTearDownMethod( + Service service, Map classMemberVarExprs); - private static List createTestMethods( + private List createTestMethods( Service service, GapicContext context, Map classMemberVarExprs, @@ -524,7 +303,7 @@ private static List createTestMethods( * @param resourceNames the resource names available for use. * @param messageTypes the proto message types available for use. */ - private static MethodDefinition createRpcTestMethod( + private MethodDefinition createRpcTestMethod( Method method, Service apiService, Service rpcService, @@ -618,7 +397,7 @@ private static MethodDefinition createRpcTestMethod( VariableExpr resultOperationVarExpr = VariableExpr.withVariable( Variable.builder() - .setType(FIXED_TYPESTORE.get("Operation")) + .setType(getFixedTypeStore().get("Operation")) .setName("resultOperation") .build()); methodExprs.add( @@ -749,7 +528,7 @@ private static MethodDefinition createRpcTestMethod( .build(); Expr resourcesValExpr = MethodInvocationExpr.builder() - .setStaticReferenceType(FIXED_TYPESTORE.get("Lists")) + .setStaticReferenceType(getFixedTypeStore().get("Lists")) .setMethodName("newArrayList") .setArguments(iterateAllExpr) .setReturnType(resourcesVarExpr.type()) @@ -771,7 +550,7 @@ private static MethodDefinition createRpcTestMethod( // Assert the size is equivalent. methodExprs.add( MethodInvocationExpr.builder() - .setStaticReferenceType(FIXED_TYPESTORE.get("Assert")) + .setStaticReferenceType(getFixedTypeStore().get("Assert")) .setMethodName("assertEquals") .setArguments( ValueExpr.withValue( @@ -816,14 +595,14 @@ private static MethodDefinition createRpcTestMethod( methodExprs.add( MethodInvocationExpr.builder() - .setStaticReferenceType(FIXED_TYPESTORE.get("Assert")) + .setStaticReferenceType(getFixedTypeStore().get("Assert")) .setMethodName("assertEquals") .setArguments(expectedPagedResponseExpr, actualPagedResponseExpr) .build()); } else if (!returnsVoid) { methodExprs.add( MethodInvocationExpr.builder() - .setStaticReferenceType(FIXED_TYPESTORE.get("Assert")) + .setStaticReferenceType(getFixedTypeStore().get("Assert")) .setMethodName("assertEquals") .setArguments(expectedResponseVarExpr, actualResponseVarExpr) .build()); @@ -833,167 +612,19 @@ private static MethodDefinition createRpcTestMethod( methodExprs.clear(); methodStatements.add(EMPTY_LINE_STATEMENT); - // Construct the request checker logic. - VariableExpr actualRequestsVarExpr = - VariableExpr.withVariable( - Variable.builder() - .setType( - TypeNode.withReference( - ConcreteReference.builder() - .setClazz(List.class) - .setGenerics( - Arrays.asList(ConcreteReference.withClazz(AbstractMessage.class))) - .build())) - .setName("actualRequests") - .build()); - methodExprs.add( - AssignmentExpr.builder() - .setVariableExpr(actualRequestsVarExpr.toBuilder().setIsDecl(true).build()) - .setValueExpr( - MethodInvocationExpr.builder() - .setExprReferenceExpr(classMemberVarExprs.get(mockServiceVarName)) - .setMethodName("getRequests") - .setReturnType(actualRequestsVarExpr.type()) - .build()) - .build()); - - methodExprs.add( - MethodInvocationExpr.builder() - .setStaticReferenceType(FIXED_TYPESTORE.get("Assert")) - .setMethodName("assertEquals") - .setArguments( - ValueExpr.withValue( - PrimitiveValue.builder().setType(TypeNode.INT).setValue("1").build()), - MethodInvocationExpr.builder() - .setExprReferenceExpr(actualRequestsVarExpr) - .setMethodName("size") - .build()) - .build()); - - VariableExpr actualRequestVarExpr = - VariableExpr.withVariable( - Variable.builder().setType(method.inputType()).setName("actualRequest").build()); - Expr getFirstRequestExpr = - MethodInvocationExpr.builder() - .setExprReferenceExpr(actualRequestsVarExpr) - .setMethodName("get") - .setArguments( - ValueExpr.withValue( - PrimitiveValue.builder().setType(TypeNode.INT).setValue("0").build())) - .setReturnType(FIXED_TYPESTORE.get("AbstractMessage")) - .build(); - getFirstRequestExpr = - CastExpr.builder().setType(method.inputType()).setExpr(getFirstRequestExpr).build(); - methodExprs.add( - AssignmentExpr.builder() - .setVariableExpr(actualRequestVarExpr.toBuilder().setIsDecl(true).build()) - .setValueExpr(getFirstRequestExpr) - .build()); methodStatements.addAll( methodExprs.stream().map(e -> ExprStatement.withExpr(e)).collect(Collectors.toList())); methodExprs.clear(); - methodStatements.add(EMPTY_LINE_STATEMENT); - - // Assert field equality. - if (isRequestArg) { - // TODO(miraleung): Replace these with a simple request object equals? - Preconditions.checkNotNull(requestVarExpr); - Preconditions.checkNotNull(requestMessage); - for (Field field : requestMessage.fields()) { - String fieldGetterMethodNamePatternTemp = "get%s"; - if (field.isRepeated()) { - fieldGetterMethodNamePatternTemp = field.isMap() ? "get%sMap" : "get%sList"; - } - final String fieldGetterMethodNamePattern = fieldGetterMethodNamePatternTemp; - Function checkExprFn = - v -> - MethodInvocationExpr.builder() - .setExprReferenceExpr(v) - .setMethodName( - String.format( - fieldGetterMethodNamePattern, JavaStyle.toUpperCamelCase(field.name()))) - .build(); - Expr expectedFieldExpr = checkExprFn.apply(requestVarExpr); - Expr actualFieldExpr = checkExprFn.apply(actualRequestVarExpr); - List assertEqualsArguments = new ArrayList<>(); - assertEqualsArguments.add(expectedFieldExpr); - assertEqualsArguments.add(actualFieldExpr); - if (TypeNode.isFloatingPointType(field.type())) { - boolean isFloat = field.type().equals(TypeNode.FLOAT); - assertEqualsArguments.add( - ValueExpr.withValue( - PrimitiveValue.builder() - .setType(isFloat ? TypeNode.FLOAT : TypeNode.DOUBLE) - .setValue(String.format("0.0001%s", isFloat ? "f" : "")) - .build())); - } - methodExprs.add( - MethodInvocationExpr.builder() - .setStaticReferenceType(FIXED_TYPESTORE.get("Assert")) - .setMethodName("assertEquals") - .setArguments(assertEqualsArguments) - .build()); - } - } else { - for (VariableExpr argVarExpr : argExprs) { - Variable variable = argVarExpr.variable(); - String fieldGetterMethodNamePattern = "get%s"; - if (LIST_TYPE.isSupertypeOrEquals(variable.type())) { - fieldGetterMethodNamePattern = "get%sList"; - } else if (MAP_TYPE.isSupertypeOrEquals(variable.type())) { - fieldGetterMethodNamePattern = "get%sMap"; - } - Expr actualFieldExpr = - MethodInvocationExpr.builder() - .setExprReferenceExpr(actualRequestVarExpr) - .setMethodName( - String.format( - fieldGetterMethodNamePattern, - JavaStyle.toUpperCamelCase(variable.identifier().name()))) - .build(); - Expr expectedFieldExpr = argVarExpr; - if (RESOURCE_NAME_TYPE.isSupertypeOrEquals(argVarExpr.type())) { - expectedFieldExpr = - MethodInvocationExpr.builder() - .setExprReferenceExpr(argVarExpr) - .setMethodName("toString") - .build(); - } - methodExprs.add( - MethodInvocationExpr.builder() - .setStaticReferenceType(FIXED_TYPESTORE.get("Assert")) - .setMethodName("assertEquals") - .setArguments(expectedFieldExpr, actualFieldExpr) - .build()); - } - } - // Assert header equality. - Expr headerKeyExpr = - MethodInvocationExpr.builder() - .setStaticReferenceType(FIXED_TYPESTORE.get("ApiClientHeaderProvider")) - .setMethodName("getDefaultApiClientHeaderKey") - .build(); - Expr headerPatternExpr = - MethodInvocationExpr.builder() - .setStaticReferenceType(FIXED_TYPESTORE.get("GaxGrpcProperties")) - .setMethodName("getDefaultApiClientHeaderPattern") - .build(); - Expr headerSentExpr = - MethodInvocationExpr.builder() - .setExprReferenceExpr(classMemberVarExprs.get("channelProvider")) - .setMethodName("isHeaderSent") - .setArguments(headerKeyExpr, headerPatternExpr) - .build(); - methodExprs.add( - MethodInvocationExpr.builder() - .setStaticReferenceType(FIXED_TYPESTORE.get("Assert")) - .setMethodName("assertTrue") - .setArguments(headerSentExpr) - .build()); methodStatements.addAll( - methodExprs.stream().map(e -> ExprStatement.withExpr(e)).collect(Collectors.toList())); - methodExprs.clear(); + constructRpcTestCheckerLogic( + method, + rpcService, + isRequestArg, + classMemberVarExprs, + requestVarExpr, + requestMessage, + argExprs)); String testMethodName = String.format( @@ -1001,7 +632,7 @@ private static MethodDefinition createRpcTestMethod( JavaStyle.toLowerCamelCase(method.name()), variantIndex > 0 ? variantIndex + 1 : ""); return MethodDefinition.builder() - .setAnnotations(Arrays.asList(TEST_ANNOTATION)) + .setAnnotations(Arrays.asList(getTestAnnotation())) .setScope(ScopeNode.PUBLIC) .setReturnType(TypeNode.VOID) .setName(testMethodName) @@ -1010,7 +641,16 @@ private static MethodDefinition createRpcTestMethod( .build(); } - private static MethodDefinition createStreamingRpcTestMethod( + protected abstract List constructRpcTestCheckerLogic( + Method method, + Service service, + boolean isRequestArg, + Map classMemberVarExprs, + VariableExpr requestVarExpr, + Message requestMessage, + List argExprs); + + private MethodDefinition createStreamingRpcTestMethod( Service service, Method method, Map classMemberVarExprs, @@ -1050,7 +690,7 @@ private static MethodDefinition createStreamingRpcTestMethod( VariableExpr resultOperationVarExpr = VariableExpr.withVariable( Variable.builder() - .setType(FIXED_TYPESTORE.get("Operation")) + .setType(getFixedTypeStore().get("Operation")) .setName("resultOperation") .build()); methodExprs.add( @@ -1103,7 +743,7 @@ private static MethodDefinition createStreamingRpcTestMethod( Variable.builder() .setType( TypeNode.withReference( - FIXED_TYPESTORE + getFixedTypeStore() .get("MockStreamObserver") .reference() .copyAndSetGenerics(Arrays.asList(method.outputType().reference())))) @@ -1116,7 +756,7 @@ private static MethodDefinition createStreamingRpcTestMethod( .setVariableExpr(responseObserverVarExpr.toBuilder().setIsDecl(true).build()) .setValueExpr( NewObjectExpr.builder() - .setType(FIXED_TYPESTORE.get("MockStreamObserver")) + .setType(getFixedTypeStore().get("MockStreamObserver")) .setIsGeneric(true) .build()) .build())); @@ -1152,7 +792,7 @@ private static MethodDefinition createStreamingRpcTestMethod( Variable.builder() .setType( TypeNode.withReference( - FIXED_TYPESTORE + getFixedTypeStore() .get("ApiStreamObserver") .reference() .copyAndSetGenerics(Arrays.asList(method.inputType().reference())))) @@ -1231,7 +871,7 @@ private static MethodDefinition createStreamingRpcTestMethod( // Assert the size is equivalent. methodExprs.add( MethodInvocationExpr.builder() - .setStaticReferenceType(FIXED_TYPESTORE.get("Assert")) + .setStaticReferenceType(getFixedTypeStore().get("Assert")) .setMethodName("assertEquals") .setArguments( ValueExpr.withValue( @@ -1255,7 +895,7 @@ private static MethodDefinition createStreamingRpcTestMethod( methodExprs.add( MethodInvocationExpr.builder() - .setStaticReferenceType(FIXED_TYPESTORE.get("Assert")) + .setStaticReferenceType(getFixedTypeStore().get("Assert")) .setMethodName("assertEquals") .setArguments(expectedResponseVarExpr, actualResponseExpr) .build()); @@ -1267,7 +907,7 @@ private static MethodDefinition createStreamingRpcTestMethod( String testMethodName = String.format("%sTest", JavaStyle.toLowerCamelCase(method.name())); return MethodDefinition.builder() - .setAnnotations(Arrays.asList(TEST_ANNOTATION)) + .setAnnotations(Arrays.asList(getTestAnnotation())) .setScope(ScopeNode.PUBLIC) .setReturnType(TypeNode.VOID) .setName(testMethodName) @@ -1288,73 +928,16 @@ private static MethodDefinition createStreamingRpcTestMethod( * @param resourceNames the resource names available for use. * @param messageTypes the proto message types available for use. */ - private static MethodDefinition createRpcExceptionTestMethod( + protected abstract MethodDefinition createRpcExceptionTestMethod( Method method, Service service, List methodSignature, int variantIndex, Map classMemberVarExprs, Map resourceNames, - Map messageTypes) { - VariableExpr exceptionVarExpr = - VariableExpr.withVariable( - Variable.builder() - .setType(FIXED_TYPESTORE.get("StatusRuntimeException")) - .setName("exception") - .build()); - - // First two assignment lines. - Expr exceptionAssignExpr = - AssignmentExpr.builder() - .setVariableExpr(exceptionVarExpr.toBuilder().setIsDecl(true).build()) - .setValueExpr( - NewObjectExpr.builder() - .setType(FIXED_TYPESTORE.get("StatusRuntimeException")) - .setArguments( - EnumRefExpr.builder() - .setType(GRPC_STATUS_TYPE) - .setName("INVALID_ARGUMENT") - .build()) - .build()) - .build(); - Expr addExceptionExpr = - MethodInvocationExpr.builder() - .setExprReferenceExpr(classMemberVarExprs.get(getMockServiceVarName(service))) - .setMethodName("addException") - .setArguments(exceptionVarExpr) - .build(); - - // Try-catch block. Build the method call. - String exceptionTestMethodName = - String.format( - "%sExceptionTest%s", - JavaStyle.toLowerCamelCase(method.name()), variantIndex > 0 ? variantIndex + 1 : ""); - - boolean isStreaming = !method.stream().equals(Method.Stream.NONE); - List methodBody = new ArrayList<>(); - methodBody.add(ExprStatement.withExpr(exceptionAssignExpr)); - methodBody.add(ExprStatement.withExpr(addExceptionExpr)); - if (isStreaming) { - methodBody.addAll( - createStreamingRpcExceptionTestStatements( - method, classMemberVarExprs, resourceNames, messageTypes)); - } else { - methodBody.addAll( - createRpcExceptionTestStatements( - method, methodSignature, classMemberVarExprs, resourceNames, messageTypes)); - } - - return MethodDefinition.builder() - .setAnnotations(Arrays.asList(TEST_ANNOTATION)) - .setScope(ScopeNode.PUBLIC) - .setReturnType(TypeNode.VOID) - .setName(exceptionTestMethodName) - .setThrowsExceptions(Arrays.asList(TypeNode.withExceptionClazz(Exception.class))) - .setBody(methodBody) - .build(); - } + Map messageTypes); - private static List createStreamingRpcExceptionTestStatements( + protected List createStreamingRpcExceptionTestStatements( Method method, Map classMemberVarExprs, Map resourceNames, @@ -1384,7 +967,7 @@ private static List createStreamingRpcExceptionTestStatements( Variable.builder() .setType( TypeNode.withReference( - FIXED_TYPESTORE + getFixedTypeStore() .get("MockStreamObserver") .reference() .copyAndSetGenerics(Arrays.asList(method.outputType().reference())))) @@ -1397,7 +980,7 @@ private static List createStreamingRpcExceptionTestStatements( .setVariableExpr(responseObserverVarExpr.toBuilder().setIsDecl(true).build()) .setValueExpr( NewObjectExpr.builder() - .setType(FIXED_TYPESTORE.get("MockStreamObserver")) + .setType(getFixedTypeStore().get("MockStreamObserver")) .setIsGeneric(true) .build()) .build())); @@ -1435,7 +1018,7 @@ private static List createStreamingRpcExceptionTestStatements( Variable.builder() .setType( TypeNode.withReference( - FIXED_TYPESTORE + getFixedTypeStore() .get("ApiStreamObserver") .reference() .copyAndSetGenerics(Arrays.asList(method.inputType().reference())))) @@ -1510,7 +1093,7 @@ private static List createStreamingRpcExceptionTestStatements( // Assert a failure if no exception was raised. tryBodyExprs.add( MethodInvocationExpr.builder() - .setStaticReferenceType(FIXED_TYPESTORE.get("Assert")) + .setStaticReferenceType(getFixedTypeStore().get("Assert")) .setMethodName("fail") .setArguments(ValueExpr.withValue(StringObjectValue.withValue("No exception thrown"))) .build()); @@ -1538,7 +1121,7 @@ private static List createStreamingRpcExceptionTestStatements( return statements; } - private static List createRpcExceptionTestStatements( + protected List createRpcExceptionTestStatements( Method method, List methodSignature, Map classMemberVarExprs, @@ -1617,7 +1200,7 @@ private static List createRpcExceptionTestStatements( // Assert a failure if no exception was raised. tryBodyExprs.add( MethodInvocationExpr.builder() - .setStaticReferenceType(FIXED_TYPESTORE.get("Assert")) + .setStaticReferenceType(getFixedTypeStore().get("Assert")) .setMethodName("fail") .setArguments(ValueExpr.withValue(StringObjectValue.withValue("No exception raised"))) .build()); @@ -1635,14 +1218,14 @@ private static List createRpcExceptionTestStatements( return Arrays.asList(EMPTY_LINE_STATEMENT, tryCatchBlock); } - private static List createRpcLroExceptionTestCatchBody( + private List createRpcLroExceptionTestCatchBody( VariableExpr exceptionExpr, boolean isStreaming) { List catchBodyExprs = new ArrayList<>(); Expr testExpectedValueExpr = VariableExpr.builder() .setVariable(Variable.builder().setType(TypeNode.CLASS_OBJECT).setName("class").build()) - .setStaticReferenceType(FIXED_TYPESTORE.get("InvalidArgumentException")) + .setStaticReferenceType(getFixedTypeStore().get("InvalidArgumentException")) .build(); Expr getCauseExpr = MethodInvocationExpr.builder() @@ -1660,11 +1243,11 @@ private static List createRpcLroExceptionTestCatchBody( InstanceofExpr checkInstanceExpr = InstanceofExpr.builder() .setExpr(getCauseExpr) - .setCheckType(FIXED_TYPESTORE.get("InvalidArgumentException")) + .setCheckType(getFixedTypeStore().get("InvalidArgumentException")) .build(); catchBodyExprs.add( MethodInvocationExpr.builder() - .setStaticReferenceType(FIXED_TYPESTORE.get("Assert")) + .setStaticReferenceType(getFixedTypeStore().get("Assert")) .setMethodName("assertTrue") .setArguments(checkInstanceExpr) .build()); @@ -1672,7 +1255,7 @@ private static List createRpcLroExceptionTestCatchBody( // Constructs `Assert.assertEquals(InvalidArgumentException.class, e.getCaus().getClass());`. catchBodyExprs.add( MethodInvocationExpr.builder() - .setStaticReferenceType(FIXED_TYPESTORE.get("Assert")) + .setStaticReferenceType(getFixedTypeStore().get("Assert")) .setMethodName("assertEquals") .setArguments(testExpectedValueExpr, testActualValueExpr) .build()); @@ -1682,12 +1265,12 @@ private static List createRpcLroExceptionTestCatchBody( VariableExpr apiExceptionVarExpr = VariableExpr.withVariable( Variable.builder() - .setType(FIXED_TYPESTORE.get("InvalidArgumentException")) + .setType(getFixedTypeStore().get("InvalidArgumentException")) .setName("apiException") .build()); Expr castedCauseExpr = CastExpr.builder() - .setType(FIXED_TYPESTORE.get("InvalidArgumentException")) + .setType(getFixedTypeStore().get("InvalidArgumentException")) .setExpr(getCauseExpr) .build(); catchBodyExprs.add( @@ -1719,7 +1302,7 @@ private static List createRpcLroExceptionTestCatchBody( .build(); catchBodyExprs.add( MethodInvocationExpr.builder() - .setStaticReferenceType(FIXED_TYPESTORE.get("Assert")) + .setStaticReferenceType(getFixedTypeStore().get("Assert")) .setMethodName("assertEquals") .setArguments(testExpectedValueExpr, testActualValueExpr) .build()); @@ -1732,7 +1315,7 @@ private static List createRpcLroExceptionTestCatchBody( * ========================================= */ - private static TypeStore createStaticTypes() { + protected static TypeStore createCommonTypes() { List concreteClazzes = Arrays.asList( AbstractMessage.class, @@ -1748,7 +1331,6 @@ private static TypeStore createStaticTypes() { BidiStreamingCallable.class, ClientStreamingCallable.class, ExecutionException.class, - GaxGrpcProperties.class, Generated.class, IOException.class, InvalidArgumentException.class, @@ -1758,50 +1340,19 @@ private static TypeStore createStaticTypes() { Operation.class, ServerStreamingCallable.class, StatusCode.class, - StatusRuntimeException.class, Test.class, UUID.class); - TypeStore typeStore = new TypeStore(concreteClazzes); - typeStore.putAll( - GRPC_TESTING_PACKAGE, - Arrays.asList( - "LocalChannelProvider", "MockGrpcService", "MockServiceHelper", "MockStreamObserver")); - return typeStore; - } - - private static Map createDefaultMethodNamesToTypes() { - Function typeMakerFn = - c -> TypeNode.withReference(ConcreteReference.withClazz(c)); - Map javaMethodNameToReturnType = new LinkedHashMap<>(); - javaMethodNameToReturnType.put( - "defaultExecutorProviderBuilder", - typeMakerFn.apply(InstantiatingExecutorProvider.Builder.class)); - javaMethodNameToReturnType.put("getDefaultEndpoint", TypeNode.STRING); - javaMethodNameToReturnType.put( - "getDefaultServiceScopes", - TypeNode.withReference( - ConcreteReference.builder() - .setClazz(List.class) - .setGenerics(Arrays.asList(TypeNode.STRING.reference())) - .build())); - javaMethodNameToReturnType.put( - "defaultCredentialsProviderBuilder", - typeMakerFn.apply(GoogleCredentialsProvider.Builder.class)); - javaMethodNameToReturnType.put( - "defaultGrpcTransportProviderBuilder", - typeMakerFn.apply(InstantiatingGrpcChannelProvider.Builder.class)); - javaMethodNameToReturnType.put( - "defaultTransportChannelProvider", FIXED_TYPESTORE.get("TransportChannelProvider")); - return javaMethodNameToReturnType; + return new TypeStore(concreteClazzes); } - private static void addDynamicTypes(GapicContext context, Service service, TypeStore typeStore) { + private void addDynamicTypes(GapicContext context, Service service, TypeStore typeStore) { typeStore.putAll( service.pakkage(), Arrays.asList( ClassNames.getMockServiceClassName(service), ClassNames.getServiceClientClassName(service), - ClassNames.getServiceSettingsClassName(service))); + ClassNames.getServiceSettingsClassName(service), + getClassNames().getTransportServiceStubClassName(service))); // Pagination types. typeStore.putAll( service.pakkage(), @@ -1958,7 +1509,7 @@ private static String getCallableMethodName(Method protoMethod) { } } - private static String getMockServiceVarName(Service service) { + protected String getMockServiceVarName(Service service) { return String.format(MOCK_SERVICE_VAR_NAME_PATTERN, service.name()); } diff --git a/src/main/java/com/google/api/generator/gapic/composer/ServiceSettingsClassComposer.java b/src/main/java/com/google/api/generator/gapic/composer/common/AbstractServiceSettingsClassComposer.java similarity index 91% rename from src/main/java/com/google/api/generator/gapic/composer/ServiceSettingsClassComposer.java rename to src/main/java/com/google/api/generator/gapic/composer/common/AbstractServiceSettingsClassComposer.java index 28d4355cc4..4efe7bf819 100644 --- a/src/main/java/com/google/api/generator/gapic/composer/ServiceSettingsClassComposer.java +++ b/src/main/java/com/google/api/generator/gapic/composer/common/AbstractServiceSettingsClassComposer.java @@ -12,13 +12,12 @@ // See the License for the specific language governing permissions and // limitations under the License. -package com.google.api.generator.gapic.composer; +package com.google.api.generator.gapic.composer.common; import com.google.api.core.ApiFunction; import com.google.api.core.BetaApi; import com.google.api.gax.core.GoogleCredentialsProvider; import com.google.api.gax.core.InstantiatingExecutorProvider; -import com.google.api.gax.grpc.InstantiatingGrpcChannelProvider; import com.google.api.gax.rpc.ApiClientHeaderProvider; import com.google.api.gax.rpc.BatchingCallSettings; import com.google.api.gax.rpc.ClientContext; @@ -75,7 +74,7 @@ import java.util.stream.Collectors; import javax.annotation.Generated; -public class ServiceSettingsClassComposer implements ClassComposer { +public abstract class AbstractServiceSettingsClassComposer implements ClassComposer { private static final String BUILDER_CLASS_NAME = "Builder"; private static final String CALL_SETTINGS_TYPE_NAME_PATTERN = "%sCallSettings"; private static final String PAGED_RESPONSE_TYPE_NAME_PATTERN = "%sPagedResponse"; @@ -83,14 +82,17 @@ public class ServiceSettingsClassComposer implements ClassComposer { private static final String OPERATION_SETTINGS_LITERAL = "OperationSettings"; private static final String SETTINGS_LITERAL = "Settings"; - private static final ServiceSettingsClassComposer INSTANCE = new ServiceSettingsClassComposer(); - - private static final TypeStore FIXED_TYPESTORE = createStaticTypes(); - - private ServiceSettingsClassComposer() {} - - public static ServiceSettingsClassComposer instance() { - return INSTANCE; + private final TypeStore fixedTypeStore; + private final Class instantiatingChannelProviderClass; + private final String defaultTransportProviderBuilderName; + + protected AbstractServiceSettingsClassComposer( + TypeStore fixedTypeStore, + Class instantiatingChannelProviderClass, + String defaultTransportProviderBuilderName) { + this.fixedTypeStore = fixedTypeStore; + this.instantiatingChannelProviderClass = instantiatingChannelProviderClass; + this.defaultTransportProviderBuilderName = defaultTransportProviderBuilderName; } @Override @@ -110,7 +112,7 @@ public GapicClass generate(GapicContext ignored, Service service) { .setName(className) .setExtendsType( TypeNode.withReference( - FIXED_TYPESTORE + getFixedTypeStore() .get("ClientSettings") .reference() .copyAndSetGenerics( @@ -124,6 +126,18 @@ public GapicClass generate(GapicContext ignored, Service service) { return GapicClass.create(kind, classDef); } + protected Class getInstantiatingChannelProviderClass() { + return instantiatingChannelProviderClass; + } + + protected TypeStore getFixedTypeStore() { + return fixedTypeStore; + } + + protected String getDefaultTransportProviderBuilderName() { + return defaultTransportProviderBuilderName; + } + private static List createClassHeaderComments( Service service, TypeNode classType) { // Pick the first pure unary rpc method, if no such method exists, then pick the first in the @@ -150,10 +164,10 @@ private static List createClassHeaderComments( classType); } - private static List createClassAnnotations(Service service) { + private List createClassAnnotations(Service service) { List annotations = new ArrayList<>(); if (!PackageChecker.isGaApi(service.pakkage())) { - annotations.add(AnnotationNode.withType(FIXED_TYPESTORE.get("BetaApi"))); + annotations.add(AnnotationNode.withType(getFixedTypeStore().get("BetaApi"))); } if (service.isDeprecated()) { @@ -162,13 +176,13 @@ private static List createClassAnnotations(Service service) { annotations.add( AnnotationNode.builder() - .setType(FIXED_TYPESTORE.get("Generated")) + .setType(getFixedTypeStore().get("Generated")) .setDescription("by gapic-generator-java") .build()); return annotations; } - private static List createClassMethods(Service service, TypeStore typeStore) { + protected List createClassMethods(Service service, TypeStore typeStore) { List javaMethods = new ArrayList<>(); javaMethods.addAll(createSettingsGetterMethods(service, typeStore)); javaMethods.add(createCreatorMethod(service, typeStore)); @@ -178,7 +192,7 @@ private static List createClassMethods(Service service, TypeSt return javaMethods; } - private static MethodDefinition createConstructorMethod(Service service, TypeStore typeStore) { + private MethodDefinition createConstructorMethod(Service service, TypeStore typeStore) { VariableExpr settingsBuilderVarExpr = VariableExpr.withVariable( Variable.builder() @@ -190,20 +204,19 @@ private static MethodDefinition createConstructorMethod(Service service, TypeSto .setScope(ScopeNode.PROTECTED) .setReturnType(thisClassType) .setArguments(Arrays.asList(settingsBuilderVarExpr.toBuilder().setIsDecl(true).build())) - .setThrowsExceptions(Arrays.asList(FIXED_TYPESTORE.get("IOException"))) + .setThrowsExceptions(Arrays.asList(getFixedTypeStore().get("IOException"))) .setBody( Arrays.asList( ExprStatement.withExpr( ReferenceConstructorExpr.superBuilder() - .setType(FIXED_TYPESTORE.get("ClientSettings")) + .setType(getFixedTypeStore().get("ClientSettings")) .setArguments(settingsBuilderVarExpr) .build()))) .build(); } // TODO(miraleung): Consider merging this with createNestedBuilderSettingsGetterMethods. - private static List createSettingsGetterMethods( - Service service, TypeStore typeStore) { + private List createSettingsGetterMethods(Service service, TypeStore typeStore) { TypeNode stubSettingsType = typeStore.get(ClassNames.getServiceStubSettingsClassName(service)); BiFunction methodMakerFn = (retType, javaMethodName) -> @@ -219,7 +232,7 @@ private static List createSettingsGetterMethods( .setExpr( MethodInvocationExpr.builder() .setMethodName("getStubSettings") - .setReturnType(FIXED_TYPESTORE.get("StubSettings")) + .setReturnType(getFixedTypeStore().get("StubSettings")) .build()) .build()) .setMethodName(javaMethodName) @@ -262,7 +275,7 @@ private static List createSettingsGetterMethods( return javaMethods; } - private static MethodDefinition createCreatorMethod(Service service, TypeStore typeStore) { + private MethodDefinition createCreatorMethod(Service service, TypeStore typeStore) { TypeNode stubClassType = typeStore.get(ClassNames.getServiceStubSettingsClassName(service)); VariableExpr stubVarExpr = VariableExpr.withVariable( @@ -300,12 +313,12 @@ private static MethodDefinition createCreatorMethod(Service service, TypeStore t .setReturnType(thisClassType) .setName("create") .setArguments(Arrays.asList(stubVarExpr.toBuilder().setIsDecl(true).build())) - .setThrowsExceptions(Arrays.asList(FIXED_TYPESTORE.get("IOException"))) + .setThrowsExceptions(Arrays.asList(getFixedTypeStore().get("IOException"))) .setReturnExpr(returnMethodExpr) .build(); } - private static List createDefaultGetterMethods( + protected List createDefaultGetterMethods( Service service, TypeStore typeStore) { BiFunction methodStarterFn = (mName, retType) -> @@ -356,9 +369,9 @@ private static List createDefaultGetterMethods( javaMethods.add( methodMakerFn.apply( methodStarterFn.apply( - "defaultGrpcTransportProviderBuilder", - typeMakerFn.apply(InstantiatingGrpcChannelProvider.Builder.class)), - SettingsCommentComposer.DEFAULT_GRPC_TRANSPORT_PROVIDER_BUILDER_METHOD_COMMENT)); + getDefaultTransportProviderBuilderName(), + typeMakerFn.apply(getInstantiatingChannelProviderClass())), + SettingsCommentComposer.DEFAULT_TRANSPORT_PROVIDER_BUILDER_METHOD_COMMENT)); javaMethods.add( methodStarterFn @@ -376,7 +389,7 @@ private static List createDefaultGetterMethods( .setAnnotations( Arrays.asList( AnnotationNode.builder() - .setType(FIXED_TYPESTORE.get("BetaApi")) + .setType(getFixedTypeStore().get("BetaApi")) .setDescription( "The surface for customizing headers is not stable yet and may" + " change in the future.") @@ -385,8 +398,7 @@ private static List createDefaultGetterMethods( return javaMethods; } - private static List createBuilderHelperMethods( - Service service, TypeStore typeStore) { + private List createBuilderHelperMethods(Service service, TypeStore typeStore) { TypeNode builderType = typeStore.get(BUILDER_CLASS_NAME); MethodDefinition newBuilderMethodOne = MethodDefinition.builder() @@ -407,7 +419,7 @@ private static List createBuilderHelperMethods( VariableExpr.withVariable( Variable.builder() .setName("clientContext") - .setType(FIXED_TYPESTORE.get("ClientContext")) + .setType(getFixedTypeStore().get("ClientContext")) .build()); MethodDefinition newBuilderMethodTwo = @@ -444,7 +456,7 @@ private static List createBuilderHelperMethods( return Arrays.asList(newBuilderMethodOne, newBuilderMethodTwo, toBuilderMethod); } - private static ClassDefinition createNestedBuilderClass(Service service, TypeStore typeStore) { + private ClassDefinition createNestedBuilderClass(Service service, TypeStore typeStore) { return ClassDefinition.builder() .setHeaderCommentStatements( SettingsCommentComposer.createBuilderClassComment( @@ -468,7 +480,7 @@ private static ClassDefinition createNestedBuilderClass(Service service, TypeSto .build(); } - private static List createNestedBuilderClassMethods( + private List createNestedBuilderClassMethods( Service service, TypeStore typeStore) { List javaMethods = new ArrayList<>(); javaMethods.addAll(createNestedBuilderConstructorMethods(service, typeStore)); @@ -480,14 +492,14 @@ private static List createNestedBuilderClassMethods( return javaMethods; } - private static List createNestedBuilderConstructorMethods( + private List createNestedBuilderConstructorMethods( Service service, TypeStore typeStore) { TypeNode builderType = typeStore.get(BUILDER_CLASS_NAME); MethodDefinition noArgCtor = MethodDefinition.constructorBuilder() .setScope(ScopeNode.PROTECTED) .setReturnType(builderType) - .setThrowsExceptions(Arrays.asList(FIXED_TYPESTORE.get("IOException"))) + .setThrowsExceptions(Arrays.asList(getFixedTypeStore().get("IOException"))) .setBody( Arrays.asList( ExprStatement.withExpr( @@ -495,7 +507,7 @@ private static List createNestedBuilderConstructorMethods( .setType(builderType) .setArguments( CastExpr.builder() - .setType(FIXED_TYPESTORE.get("ClientContext")) + .setType(getFixedTypeStore().get("ClientContext")) .setExpr(ValueExpr.createNullExpr()) .build()) .build()))) @@ -511,7 +523,7 @@ private static List createNestedBuilderConstructorMethods( Arrays.asList( ExprStatement.withExpr( ReferenceConstructorExpr.superBuilder() - .setType(FIXED_TYPESTORE.get("ClientSettings")) + .setType(getFixedTypeStore().get("ClientSettings")) .setArguments(superArg) .build()))) .build(); @@ -520,7 +532,7 @@ private static List createNestedBuilderConstructorMethods( VariableExpr.withVariable( Variable.builder() .setName("clientContext") - .setType(FIXED_TYPESTORE.get("ClientContext")) + .setType(getFixedTypeStore().get("ClientContext")) .build()); MethodDefinition clientContextCtor = ctorMakerFn.apply( @@ -578,7 +590,7 @@ private static MethodDefinition createNestedBuilderCreatorMethod( .build(); } - private static MethodDefinition createNestedBuilderStubSettingsBuilderMethod( + private MethodDefinition createNestedBuilderStubSettingsBuilderMethod( Service service, TypeStore typeStore) { TypeNode retType = getStubSettingsBuilderType(service); return MethodDefinition.builder() @@ -591,13 +603,13 @@ private static MethodDefinition createNestedBuilderStubSettingsBuilderMethod( .setExpr( MethodInvocationExpr.builder() .setMethodName("getStubSettings") - .setReturnType(FIXED_TYPESTORE.get("StubSettings")) + .setReturnType(getFixedTypeStore().get("StubSettings")) .build()) .build()) .build(); } - private static MethodDefinition createNestedBuilderApplyToAllUnaryMethod( + private MethodDefinition createNestedBuilderApplyToAllUnaryMethod( Service service, TypeStore typeStore) { TypeNode builderType = typeStore.get(BUILDER_CLASS_NAME); String javaMethodName = "applyToAllUnaryMethods"; @@ -615,7 +627,7 @@ private static MethodDefinition createNestedBuilderApplyToAllUnaryMethod( .setName("settingsUpdater") .setType( TypeNode.withReference( - FIXED_TYPESTORE + getFixedTypeStore() .get("ApiFunction") .reference() .copyAndSetGenerics( @@ -711,7 +723,7 @@ private static List createNestedBuilderSettingsGetterMethods( return javaMethods; } - private static MethodDefinition createNestedBuilderClassBuildMethod( + private MethodDefinition createNestedBuilderClassBuildMethod( Service service, TypeStore typeStore) { TypeNode builderType = typeStore.get(BUILDER_CLASS_NAME); TypeNode returnType = typeStore.get(ClassNames.getServiceSettingsClassName(service)); @@ -720,7 +732,7 @@ private static MethodDefinition createNestedBuilderClassBuildMethod( .setScope(ScopeNode.PUBLIC) .setReturnType(returnType) .setName("build") - .setThrowsExceptions(Arrays.asList(FIXED_TYPESTORE.get("IOException"))) + .setThrowsExceptions(Arrays.asList(getFixedTypeStore().get("IOException"))) .setReturnExpr( NewObjectExpr.builder() .setType(returnType) @@ -729,7 +741,7 @@ private static MethodDefinition createNestedBuilderClassBuildMethod( .build(); } - private static TypeStore createStaticTypes() { + protected static TypeStore createCommonTypes() { List concreteClazzes = Arrays.asList( ApiClientHeaderProvider.class, @@ -740,7 +752,6 @@ private static TypeStore createStaticTypes() { Generated.class, GoogleCredentialsProvider.class, InstantiatingExecutorProvider.class, - InstantiatingGrpcChannelProvider.class, IOException.class, Operation.class, OperationCallSettings.class, diff --git a/src/main/java/com/google/api/generator/gapic/composer/GrpcServiceStubClassComposer.java b/src/main/java/com/google/api/generator/gapic/composer/common/AbstractServiceStubClassComposer.java similarity index 67% rename from src/main/java/com/google/api/generator/gapic/composer/GrpcServiceStubClassComposer.java rename to src/main/java/com/google/api/generator/gapic/composer/common/AbstractServiceStubClassComposer.java index 6c02c4c310..4146ae6343 100644 --- a/src/main/java/com/google/api/generator/gapic/composer/GrpcServiceStubClassComposer.java +++ b/src/main/java/com/google/api/generator/gapic/composer/common/AbstractServiceStubClassComposer.java @@ -12,13 +12,11 @@ // See the License for the specific language governing permissions and // limitations under the License. -package com.google.api.generator.gapic.composer; +package com.google.api.generator.gapic.composer.common; import com.google.api.core.BetaApi; import com.google.api.gax.core.BackgroundResource; import com.google.api.gax.core.BackgroundResourceAggregation; -import com.google.api.gax.grpc.GrpcCallSettings; -import com.google.api.gax.grpc.GrpcStubCallableFactory; import com.google.api.gax.rpc.BidiStreamingCallable; import com.google.api.gax.rpc.ClientContext; import com.google.api.gax.rpc.ClientStreamingCallable; @@ -27,7 +25,6 @@ import com.google.api.gax.rpc.ServerStreamingCallable; import com.google.api.gax.rpc.UnaryCallable; import com.google.api.generator.engine.ast.AnnotationNode; -import com.google.api.generator.engine.ast.AnonymousClassExpr; import com.google.api.generator.engine.ast.AssignmentExpr; import com.google.api.generator.engine.ast.ClassDefinition; import com.google.api.generator.engine.ast.CommentStatement; @@ -43,7 +40,6 @@ import com.google.api.generator.engine.ast.ReferenceConstructorExpr; import com.google.api.generator.engine.ast.ScopeNode; import com.google.api.generator.engine.ast.Statement; -import com.google.api.generator.engine.ast.StringObjectValue; import com.google.api.generator.engine.ast.ThisObjectValue; import com.google.api.generator.engine.ast.TypeNode; import com.google.api.generator.engine.ast.ValueExpr; @@ -62,32 +58,26 @@ import com.google.common.base.Preconditions; import com.google.common.collect.ImmutableMap; import com.google.longrunning.Operation; -import com.google.longrunning.stub.GrpcOperationsStub; import io.grpc.MethodDescriptor; import io.grpc.protobuf.ProtoUtils; import java.io.IOException; import java.util.ArrayList; import java.util.Arrays; -import java.util.HashSet; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; -import java.util.Set; import java.util.concurrent.TimeUnit; import java.util.function.BiFunction; import java.util.function.Function; import java.util.stream.Collectors; import javax.annotation.Generated; -public class GrpcServiceStubClassComposer implements ClassComposer { +public abstract class AbstractServiceStubClassComposer implements ClassComposer { private static final Statement EMPTY_LINE_STATEMENT = EmptyLineStatement.create(); - private static final String GRPC_SERVICE_CALLABLE_FACTORY_PATTERN = "Grpc%sCallableFactory"; private static final String METHOD_DESCRIPTOR_NAME_PATTERN = "%sMethodDescriptor"; private static final String PAGED_RESPONSE_TYPE_NAME_PATTERN = "%sPagedResponse"; private static final String PAGED_CALLABLE_CLASS_MEMBER_PATTERN = "%sPagedCallable"; - private static final String STUB_SETTINGS_PATTERN = "%sStubSettings"; - private static final String STUB_PATTERN = "%sStub"; private static final String BACKGROUND_RESOURCES_MEMBER_NAME = "backgroundResources"; private static final String CALLABLE_NAME = "Callable"; @@ -98,32 +88,64 @@ public class GrpcServiceStubClassComposer implements ClassComposer { private static final String OPERATIONS_STUB_MEMBER_NAME = "operationsStub"; private static final String PAGED_CALLABLE_NAME = "PagedCallable"; - private static final GrpcServiceStubClassComposer INSTANCE = new GrpcServiceStubClassComposer(); - - private static final TypeStore FIXED_TYPESTORE = createStaticTypes(); - - // Legacy support for the original reroute_to_grpc_interface option in gapic.yaml. These two APIs - // predate the modern way, which is to add the RPCs directly into the proto. - private static final Set REROUTE_TO_GRPC_INTERFACE_SERVICE_ALLOWLIST = - new HashSet<>(Arrays.asList("google.pubsub.v1")); - private static final Set REROUTE_TO_GRPC_INTERFACE_IAM_METHOD_ALLOWLIST = - new HashSet<>(Arrays.asList("SetIamPolicy", "GetIamPolicy", "TestIamPermissions")); - - private GrpcServiceStubClassComposer() {} + private final TypeStore fixedTypeStore; + private final StubCommentComposer commentComposer; + private final ClassNames classNames; + private final Class callSettingsClass; + private final Class stubCallableFactoryClass; + private final Class methodDescriptorClass; + private final Class operationsStubClass; + + protected AbstractServiceStubClassComposer( + TypeStore fixedTypeStore, + StubCommentComposer commentComposer, + ClassNames classNames, + Class callSettingsClass, + Class stubCallableFactoryClass, + Class methodDescriptorClass, + Class operationsStubClass) { + this.fixedTypeStore = fixedTypeStore; + this.commentComposer = commentComposer; + this.classNames = classNames; + this.callSettingsClass = callSettingsClass; + this.stubCallableFactoryClass = stubCallableFactoryClass; + this.methodDescriptorClass = methodDescriptorClass; + this.operationsStubClass = operationsStubClass; + } - public static GrpcServiceStubClassComposer instance() { - return INSTANCE; + protected static TypeStore createCommonStaticTypes() { + List concreteClazzes = + Arrays.asList( + BackgroundResource.class, + BackgroundResourceAggregation.class, + BetaApi.class, + BidiStreamingCallable.class, + ClientContext.class, + ClientStreamingCallable.class, + Generated.class, + ImmutableMap.class, + InterruptedException.class, + IOException.class, + MethodDescriptor.class, + Operation.class, + OperationCallable.class, + ProtoUtils.class, + RequestParamsExtractor.class, + ServerStreamingCallable.class, + TimeUnit.class, + UnaryCallable.class); + return new TypeStore(concreteClazzes); } @Override - public GapicClass generate(GapicContext ignored, Service service) { + public GapicClass generate(GapicContext context, Service service) { String pakkage = service.pakkage() + ".stub"; TypeStore typeStore = createDynamicTypes(service, pakkage); - String className = ClassNames.getGrpcServiceStubClassName(service); + String className = getClassNames().getTransportServiceStubClassName(service); GapicClass.Kind kind = Kind.STUB; Map protoMethodNameToDescriptorVarExprs = - createProtoMethodNameToDescriptorClassMembers(service); + createProtoMethodNameToDescriptorClassMembers(service, getMethodDescriptorClass()); Map callableClassMemberVarExprs = createCallableClassMembers(service, typeStore); @@ -134,21 +156,23 @@ public GapicClass generate(GapicContext ignored, Service service) { VariableExpr.withVariable( Variable.builder() .setName(BACKGROUND_RESOURCES_MEMBER_NAME) - .setType(FIXED_TYPESTORE.get("BackgroundResource")) - .build())); - classMemberVarExprs.put( - OPERATIONS_STUB_MEMBER_NAME, - VariableExpr.withVariable( - Variable.builder() - .setName(OPERATIONS_STUB_MEMBER_NAME) - .setType(FIXED_TYPESTORE.get("GrpcOperationsStub")) + .setType(getFixedTypeStore().get("BackgroundResource")) .build())); + if (getOperationsStubClass() != null) { + classMemberVarExprs.put( + OPERATIONS_STUB_MEMBER_NAME, + VariableExpr.withVariable( + Variable.builder() + .setName(OPERATIONS_STUB_MEMBER_NAME) + .setType(getFixedTypeStore().get(getOperationsStubClass().getSimpleName())) + .build())); + } classMemberVarExprs.put( CALLABLE_FACTORY_MEMBER_NAME, VariableExpr.withVariable( Variable.builder() .setName(CALLABLE_FACTORY_MEMBER_NAME) - .setType(FIXED_TYPESTORE.get("GrpcStubCallableFactory")) + .setType(getFixedTypeStore().get(getStubCallableFactoryClass().getSimpleName())) .build())); List classStatements = @@ -162,12 +186,12 @@ public GapicClass generate(GapicContext ignored, Service service) { ClassDefinition.builder() .setPackageString(pakkage) .setHeaderCommentStatements( - StubCommentComposer.createGrpcServiceStubClassHeaderComments( + getCommentComposer().createTransportServiceStubClassHeaderComments( service.name(), service.isDeprecated())) .setAnnotations(createClassAnnotations(service)) .setScope(ScopeNode.PUBLIC) .setName(className) - .setExtendsType(typeStore.get(ClassNames.getServiceStubClassName(service))) + .setExtendsType(typeStore.get(getClassNames().getServiceStubClassName(service))) .setStatements(classStatements) .setMethods( createClassMethods( @@ -180,7 +204,51 @@ public GapicClass generate(GapicContext ignored, Service service) { return GapicClass.create(kind, classDef); } - private static List createClassStatements( + protected abstract Statement createMethodDescriptorVariableDecl( + Service service, Method protoMethod, VariableExpr methodDescriptorVarExpr); + + protected abstract List createOperationsStubGetterMethod( + VariableExpr operationsStubVarExpr); + + protected abstract Expr createTransportSettingsInitExpr( + Method method, VariableExpr transportSettingsVarExpr, VariableExpr methodDescriptorVarExpr); + + protected List createGetMethodDescriptorsMethod( + Service service, + TypeStore typeStore, + Map protoMethodNameToDescriptorVarExprs) { + return Arrays.asList(); + } + + protected TypeStore getFixedTypeStore() { + return fixedTypeStore; + } + + protected StubCommentComposer getCommentComposer() { + return commentComposer; + } + + protected ClassNames getClassNames() { + return classNames; + } + + protected Class getCallSettingsClass() { + return callSettingsClass; + } + + protected Class getStubCallableFactoryClass() { + return stubCallableFactoryClass; + } + + protected Class getMethodDescriptorClass() { + return methodDescriptorClass; + } + + protected Class getOperationsStubClass() { + return operationsStubClass; + } + + protected List createClassStatements( Service service, Map protoMethodNameToDescriptorVarExprs, Map callableClassMemberVarExprs, @@ -199,7 +267,7 @@ private static List createClassStatements( return classStatements; } - private static List createMethodDescriptorVariableDecls( + protected List createMethodDescriptorVariableDecls( Service service, Map protoMethodNameToDescriptorVarExprs) { return service.methods().stream() .map( @@ -209,86 +277,6 @@ private static List createMethodDescriptorVariableDecls( .collect(Collectors.toList()); } - private static Statement createMethodDescriptorVariableDecl( - Service service, Method protoMethod, VariableExpr methodDescriptorVarExpr) { - MethodInvocationExpr methodDescriptorMaker = - MethodInvocationExpr.builder() - .setMethodName("newBuilder") - .setStaticReferenceType(FIXED_TYPESTORE.get("MethodDescriptor")) - .setGenerics(methodDescriptorVarExpr.variable().type().reference().generics()) - .build(); - - BiFunction> methodMakerFn = - (mName, argExpr) -> - m -> - MethodInvocationExpr.builder() - .setMethodName(mName) - .setArguments(Arrays.asList(argExpr)) - .setExprReferenceExpr(m) - .build(); - - methodDescriptorMaker = - methodMakerFn - .apply("setType", getMethodDescriptorMethodTypeExpr(protoMethod)) - .apply(methodDescriptorMaker); - - String codeMethodNameArg = getProtoRpcFullMethodName(service, protoMethod); - methodDescriptorMaker = - methodMakerFn - .apply( - "setFullMethodName", - ValueExpr.withValue(StringObjectValue.withValue(codeMethodNameArg))) - .apply(methodDescriptorMaker); - - Function protoUtilsMarshallerFn = - m -> - MethodInvocationExpr.builder() - .setStaticReferenceType(FIXED_TYPESTORE.get("ProtoUtils")) - .setMethodName("marshaller") - .setArguments(Arrays.asList(m)) - .build(); - MethodInvocationExpr methodInvocationArg = - MethodInvocationExpr.builder() - .setMethodName("getDefaultInstance") - .setStaticReferenceType(protoMethod.inputType()) - .build(); - - methodDescriptorMaker = - methodMakerFn - .apply("setRequestMarshaller", protoUtilsMarshallerFn.apply(methodInvocationArg)) - .apply(methodDescriptorMaker); - - methodInvocationArg = - MethodInvocationExpr.builder() - .setMethodName("getDefaultInstance") - .setStaticReferenceType(protoMethod.outputType()) - .build(); - methodDescriptorMaker = - methodMakerFn - .apply("setResponseMarshaller", protoUtilsMarshallerFn.apply(methodInvocationArg)) - .apply(methodDescriptorMaker); - - methodDescriptorMaker = - MethodInvocationExpr.builder() - .setMethodName("build") - .setExprReferenceExpr(methodDescriptorMaker) - .setReturnType(methodDescriptorVarExpr.type()) - .build(); - - return ExprStatement.withExpr( - AssignmentExpr.builder() - .setVariableExpr( - methodDescriptorVarExpr - .toBuilder() - .setIsDecl(true) - .setScope(ScopeNode.PRIVATE) - .setIsStatic(true) - .setIsFinal(true) - .build()) - .setValueExpr(methodDescriptorMaker) - .build()); - } - private static List createClassMemberFieldDeclarations( Map fieldNameToVarExprs) { return fieldNameToVarExprs.values().stream() @@ -303,12 +291,12 @@ private static List createClassMemberFieldDeclarations( .collect(Collectors.toList()); } - private static Map createProtoMethodNameToDescriptorClassMembers( - Service service) { + protected Map createProtoMethodNameToDescriptorClassMembers( + Service service, Class descriptorClass) { return service.methods().stream() .collect( Collectors.toMap( - m -> m.name(), + Method::name, m -> VariableExpr.withVariable( Variable.builder() @@ -319,7 +307,7 @@ private static Map createProtoMethodNameToDescriptorClassM .setType( TypeNode.withReference( ConcreteReference.builder() - .setClazz(MethodDescriptor.class) + .setClazz(descriptorClass) .setGenerics( Arrays.asList( m.inputType().reference(), @@ -328,7 +316,7 @@ private static Map createProtoMethodNameToDescriptorClassM .build()))); } - private static Map createCallableClassMembers( + private Map createCallableClassMembers( Service service, TypeStore typeStore) { Map callableClassMembers = new LinkedHashMap<>(); // Using a for-loop because the output cardinality is not a 1:1 mapping to the input set. @@ -388,10 +376,10 @@ private static Map createCallableClassMembers( return callableClassMembers; } - private static List createClassAnnotations(Service service) { + protected List createClassAnnotations(Service service) { List annotations = new ArrayList<>(); if (!PackageChecker.isGaApi(service.pakkage())) { - annotations.add(AnnotationNode.withType(FIXED_TYPESTORE.get("BetaApi"))); + annotations.add(AnnotationNode.withType(getFixedTypeStore().get("BetaApi"))); } if (service.isDeprecated()) { @@ -400,13 +388,13 @@ private static List createClassAnnotations(Service service) { annotations.add( AnnotationNode.builder() - .setType(FIXED_TYPESTORE.get("Generated")) + .setType(getFixedTypeStore().get("Generated")) .setDescription("by gapic-generator-java") .build()); return annotations; } - private static List createClassMethods( + protected List createClassMethods( Service service, TypeStore typeStore, Map classMemberVarExprs, @@ -421,7 +409,9 @@ private static List createClassMethods( classMemberVarExprs, callableClassMemberVarExprs, protoMethodNameToDescriptorVarExprs)); - javaMethods.add( + javaMethods.addAll( + createGetMethodDescriptorsMethod(service, typeStore, protoMethodNameToDescriptorVarExprs)); + javaMethods.addAll( createOperationsStubGetterMethod(classMemberVarExprs.get(OPERATIONS_STUB_MEMBER_NAME))); javaMethods.addAll(createCallableGetterMethods(callableClassMemberVarExprs)); javaMethods.addAll( @@ -429,10 +419,9 @@ private static List createClassMethods( return javaMethods; } - private static List createStaticCreatorMethods( - Service service, TypeStore typeStore) { + private List createStaticCreatorMethods(Service service, TypeStore typeStore) { TypeNode creatorMethodReturnType = - typeStore.get(ClassNames.getGrpcServiceStubClassName(service)); + typeStore.get(getClassNames().getTransportServiceStubClassName(service)); Function, MethodDefinition.Builder> creatorMethodStarterFn = argList -> MethodDefinition.builder() @@ -453,12 +442,13 @@ private static List createStaticCreatorMethods( argList -> NewObjectExpr.builder().setType(creatorMethodReturnType).setArguments(argList).build(); - TypeNode stubSettingsType = typeStore.get(ClassNames.getServiceStubSettingsClassName(service)); + TypeNode stubSettingsType = + typeStore.get(getClassNames().getServiceStubSettingsClassName(service)); VariableExpr settingsVarExpr = VariableExpr.withVariable( Variable.builder().setName("settings").setType(stubSettingsType).build()); - TypeNode clientContextType = FIXED_TYPESTORE.get("ClientContext"); + TypeNode clientContextType = getFixedTypeStore().get("ClientContext"); VariableExpr clientContextVarExpr = VariableExpr.withVariable( Variable.builder().setName("clientContext").setType(clientContextType).build()); @@ -467,7 +457,7 @@ private static List createStaticCreatorMethods( VariableExpr.withVariable( Variable.builder() .setName("callableFactory") - .setType(FIXED_TYPESTORE.get("GrpcStubCallableFactory")) + .setType(getFixedTypeStore().get(getStubCallableFactoryClass().getSimpleName())) .build()); MethodInvocationExpr clientContextCreateMethodExpr = @@ -509,18 +499,19 @@ private static List createStaticCreatorMethods( .build()); } - private static List createConstructorMethods( + protected List createConstructorMethods( Service service, TypeStore typeStore, Map classMemberVarExprs, Map callableClassMemberVarExprs, Map protoMethodNameToDescriptorVarExprs) { - TypeNode stubSettingsType = typeStore.get(ClassNames.getServiceStubSettingsClassName(service)); + TypeNode stubSettingsType = + typeStore.get(getClassNames().getServiceStubSettingsClassName(service)); VariableExpr settingsVarExpr = VariableExpr.withVariable( Variable.builder().setName("settings").setType(stubSettingsType).build()); - TypeNode clientContextType = FIXED_TYPESTORE.get("ClientContext"); + TypeNode clientContextType = getFixedTypeStore().get("ClientContext"); VariableExpr clientContextVarExpr = VariableExpr.withVariable( Variable.builder().setName("clientContext").setType(clientContextType).build()); @@ -529,10 +520,11 @@ private static List createConstructorMethods( VariableExpr.withVariable( Variable.builder() .setName("callableFactory") - .setType(FIXED_TYPESTORE.get("GrpcStubCallableFactory")) + .setType(getFixedTypeStore().get(getStubCallableFactoryClass().getSimpleName())) .build()); - TypeNode thisClassType = typeStore.get(ClassNames.getGrpcServiceStubClassName(service)); + TypeNode thisClassType = + typeStore.get(getClassNames().getTransportServiceStubClassName(service)); TypeNode ioExceptionType = TypeNode.withReference(ConcreteReference.withClazz(IOException.class)); @@ -564,14 +556,15 @@ private static List createConstructorMethods( NewObjectExpr.builder() .setType( typeStore.get( - ClassNames.getGrpcServiceCallableFactoryClassName(service))) + getClassNames() + .getTransportServiceCallableFactoryClassName(service))) .build()) .build()))); Expr thisExpr = ValueExpr.withValue( ThisObjectValue.withType( - typeStore.get(ClassNames.getGrpcServiceStubClassName(service)))); + typeStore.get(getClassNames().getTransportServiceStubClassName(service)))); // Body of the second constructor method. List secondCtorStatements = new ArrayList<>(); List secondCtorExprs = new ArrayList<>(); @@ -585,19 +578,22 @@ private static List createConstructorMethods( .build()) .setValueExpr(callableFactoryVarExpr) .build()); - VariableExpr operationsStubClassVarExpr = classMemberVarExprs.get("operationsStub"); - secondCtorExprs.add( - AssignmentExpr.builder() - .setVariableExpr( - operationsStubClassVarExpr.toBuilder().setExprReferenceExpr(thisExpr).build()) - .setValueExpr( - MethodInvocationExpr.builder() - .setStaticReferenceType(FIXED_TYPESTORE.get("GrpcOperationsStub")) - .setMethodName("create") - .setArguments(Arrays.asList(clientContextVarExpr, callableFactoryVarExpr)) - .setReturnType(operationsStubClassVarExpr.type()) - .build()) - .build()); + VariableExpr operationsStubClassVarExpr = classMemberVarExprs.get(OPERATIONS_STUB_MEMBER_NAME); + if (getOperationsStubClass() != null) { + secondCtorExprs.add( + AssignmentExpr.builder() + .setVariableExpr( + operationsStubClassVarExpr.toBuilder().setExprReferenceExpr(thisExpr).build()) + .setValueExpr( + MethodInvocationExpr.builder() + .setStaticReferenceType( + getFixedTypeStore().get(getOperationsStubClass().getSimpleName())) + .setMethodName("create") + .setArguments(Arrays.asList(clientContextVarExpr, callableFactoryVarExpr)) + .setReturnType(operationsStubClassVarExpr.type()) + .build()) + .build()); + } secondCtorStatements.addAll( secondCtorExprs.stream().map(e -> ExprStatement.withExpr(e)).collect(Collectors.toList())); secondCtorExprs.clear(); @@ -619,7 +615,7 @@ private static List createConstructorMethods( .setType( TypeNode.withReference( ConcreteReference.builder() - .setClazz(GrpcCallSettings.class) + .setClazz(getCallSettingsClass()) .setGenerics( Arrays.asList( m.inputType().reference(), @@ -675,7 +671,7 @@ private static List createConstructorMethods( backgroundResourcesVarExpr.toBuilder().setExprReferenceExpr(thisExpr).build()) .setValueExpr( NewObjectExpr.builder() - .setType(FIXED_TYPESTORE.get("BackgroundResourceAggregation")) + .setType(getFixedTypeStore().get("BackgroundResourceAggregation")) .setArguments(Arrays.asList(getBackgroundResourcesMethodExpr)) .build()) .build()); @@ -692,147 +688,6 @@ private static List createConstructorMethods( return Arrays.asList(firstCtor, secondCtor); } - private static Expr createTransportSettingsInitExpr( - Method method, VariableExpr transportSettingsVarExpr, VariableExpr methodDescriptorVarExpr) { - MethodInvocationExpr callSettingsBuilderExpr = - MethodInvocationExpr.builder() - .setStaticReferenceType(FIXED_TYPESTORE.get("GrpcCallSettings")) - .setGenerics(transportSettingsVarExpr.type().reference().generics()) - .setMethodName("newBuilder") - .build(); - callSettingsBuilderExpr = - MethodInvocationExpr.builder() - .setExprReferenceExpr(callSettingsBuilderExpr) - .setMethodName("setMethodDescriptor") - .setArguments(Arrays.asList(methodDescriptorVarExpr)) - .build(); - - if (method.hasHttpBindings()) { - callSettingsBuilderExpr = - MethodInvocationExpr.builder() - .setExprReferenceExpr(callSettingsBuilderExpr) - .setMethodName("setParamsExtractor") - .setArguments(createRequestParamsExtractorAnonClass(method)) - .build(); - } - - callSettingsBuilderExpr = - MethodInvocationExpr.builder() - .setExprReferenceExpr(callSettingsBuilderExpr) - .setMethodName("build") - .setReturnType(transportSettingsVarExpr.type()) - .build(); - return AssignmentExpr.builder() - .setVariableExpr(transportSettingsVarExpr.toBuilder().setIsDecl(true).build()) - .setValueExpr(callSettingsBuilderExpr) - .build(); - } - - private static AnonymousClassExpr createRequestParamsExtractorAnonClass(Method method) { - Preconditions.checkState( - method.hasHttpBindings(), String.format("Method %s has no HTTP binding", method.name())); - - TypeNode paramsVarType = - TypeNode.withReference( - ConcreteReference.builder() - .setClazz(ImmutableMap.Builder.class) - .setGenerics(TypeNode.STRING.reference(), TypeNode.STRING.reference()) - .build()); - VariableExpr paramsVarExpr = - VariableExpr.withVariable( - Variable.builder().setName("params").setType(paramsVarType).build()); - VariableExpr reqeustVarExpr = - VariableExpr.withVariable( - Variable.builder().setName("request").setType(method.inputType()).build()); - - Expr paramsAssignExpr = - AssignmentExpr.builder() - .setVariableExpr(paramsVarExpr.toBuilder().setIsDecl(true).build()) - .setValueExpr( - MethodInvocationExpr.builder() - .setStaticReferenceType(FIXED_TYPESTORE.get("ImmutableMap")) - .setMethodName("builder") - .setReturnType(paramsVarType) - .build()) - .build(); - List bodyExprs = new ArrayList<>(); - bodyExprs.add(paramsAssignExpr); - - VariableExpr requestVarExpr = - VariableExpr.withVariable( - Variable.builder().setType(method.inputType()).setName("request").build()); - - for (String httpBindingFieldName : method.httpBindings()) { - // Handle foo.bar cases by descending into the subfields. - MethodInvocationExpr.Builder requestFieldGetterExprBuilder = - MethodInvocationExpr.builder().setExprReferenceExpr(requestVarExpr); - String[] descendantFields = httpBindingFieldName.split("\\."); - for (int i = 0; i < descendantFields.length; i++) { - String currFieldName = descendantFields[i]; - String bindingFieldMethodName = - String.format("get%s", JavaStyle.toUpperCamelCase(currFieldName)); - requestFieldGetterExprBuilder = - requestFieldGetterExprBuilder.setMethodName(bindingFieldMethodName); - if (i < descendantFields.length - 1) { - requestFieldGetterExprBuilder = - MethodInvocationExpr.builder() - .setExprReferenceExpr(requestFieldGetterExprBuilder.build()); - } - } - - MethodInvocationExpr requestBuilderExpr = requestFieldGetterExprBuilder.build(); - Expr valueOfExpr = - MethodInvocationExpr.builder() - .setStaticReferenceType(TypeNode.STRING) - .setMethodName("valueOf") - .setArguments(requestBuilderExpr) - .build(); - - Expr paramsPutExpr = - MethodInvocationExpr.builder() - .setExprReferenceExpr(paramsVarExpr) - .setMethodName("put") - .setArguments( - ValueExpr.withValue(StringObjectValue.withValue(httpBindingFieldName)), - valueOfExpr) - .build(); - bodyExprs.add(paramsPutExpr); - } - - TypeNode returnType = - TypeNode.withReference( - ConcreteReference.builder() - .setClazz(Map.class) - .setGenerics(TypeNode.STRING.reference(), TypeNode.STRING.reference()) - .build()); - Expr returnExpr = - MethodInvocationExpr.builder() - .setExprReferenceExpr(paramsVarExpr) - .setMethodName("build") - .setReturnType(returnType) - .build(); - - MethodDefinition extractMethod = - MethodDefinition.builder() - .setIsOverride(true) - .setScope(ScopeNode.PUBLIC) - .setReturnType(returnType) - .setName("extract") - .setArguments(requestVarExpr.toBuilder().setIsDecl(true).build()) - .setBody( - bodyExprs.stream().map(e -> ExprStatement.withExpr(e)).collect(Collectors.toList())) - .setReturnExpr(returnExpr) - .build(); - - TypeNode anonClassType = - TypeNode.withReference( - ConcreteReference.builder() - .setClazz(RequestParamsExtractor.class) - .setGenerics(method.inputType().reference()) - .build()); - return AnonymousClassExpr.builder().setType(anonClassType).setMethods(extractMethod).build(); - } - private static Expr createCallableInitExpr( String callableVarName, VariableExpr callableVarExpr, @@ -924,16 +779,6 @@ private static String getCallableCreatorMethodName(TypeNode callableVarExprType) return String.format("create%sCallable", streamName); } - private static MethodDefinition createOperationsStubGetterMethod( - VariableExpr operationsStubVarExpr) { - return MethodDefinition.builder() - .setScope(ScopeNode.PUBLIC) - .setReturnType(operationsStubVarExpr.type()) - .setName("getOperationsStub") - .setReturnExpr(operationsStubVarExpr) - .build(); - } - private static List createCallableGetterMethods( Map callableClassMemberVarExprs) { return callableClassMemberVarExprs.entrySet().stream() @@ -949,7 +794,7 @@ private static List createCallableGetterMethods( .collect(Collectors.toList()); } - private static List createStubOverrideMethods( + private List createStubOverrideMethods( VariableExpr backgroundResourcesVarExpr) { Function methodMakerStarterFn = methodName -> @@ -1008,7 +853,7 @@ private static List createStubOverrideMethods( VariableExpr.withVariable( Variable.builder() .setName("unit") - .setType(FIXED_TYPESTORE.get("TimeUnit")) + .setType(getFixedTypeStore().get("TimeUnit")) .build())); javaMethods.add( methodMakerStarterFn @@ -1018,7 +863,7 @@ private static List createStubOverrideMethods( awaitTerminationArgs.stream() .map(v -> v.toBuilder().setIsDecl(true).build()) .collect(Collectors.toList())) - .setThrowsExceptions(Arrays.asList(FIXED_TYPESTORE.get("InterruptedException"))) + .setThrowsExceptions(Arrays.asList(getFixedTypeStore().get("InterruptedException"))) .setReturnExpr( MethodInvocationExpr.builder() .setExprReferenceExpr(backgroundResourcesVarExpr) @@ -1033,42 +878,15 @@ private static List createStubOverrideMethods( return javaMethods; } - private static TypeStore createStaticTypes() { - List concreteClazzes = - Arrays.asList( - BackgroundResource.class, - BackgroundResourceAggregation.class, - BetaApi.class, - BidiStreamingCallable.class, - ClientContext.class, - ClientStreamingCallable.class, - Generated.class, - GrpcCallSettings.class, - GrpcOperationsStub.class, - GrpcStubCallableFactory.class, - ImmutableMap.class, - InterruptedException.class, - IOException.class, - MethodDescriptor.class, - Operation.class, - OperationCallable.class, - ProtoUtils.class, - RequestParamsExtractor.class, - ServerStreamingCallable.class, - TimeUnit.class, - UnaryCallable.class); - return new TypeStore(concreteClazzes); - } - - private static TypeStore createDynamicTypes(Service service, String stubPakkage) { + private TypeStore createDynamicTypes(Service service, String stubPakkage) { TypeStore typeStore = new TypeStore(); typeStore.putAll( stubPakkage, Arrays.asList( - ClassNames.getGrpcServiceStubClassName(service), - ClassNames.getServiceStubSettingsClassName(service), - ClassNames.getServiceStubClassName(service), - ClassNames.getGrpcServiceCallableFactoryClassName(service))); + getClassNames().getTransportServiceStubClassName(service), + getClassNames().getServiceStubSettingsClassName(service), + getClassNames().getServiceStubClassName(service), + getClassNames().getTransportServiceCallableFactoryClassName(service))); // Pagination types. typeStore.putAll( service.pakkage(), @@ -1077,21 +895,21 @@ private static TypeStore createDynamicTypes(Service service, String stubPakkage) .map(m -> String.format(PAGED_RESPONSE_TYPE_NAME_PATTERN, m.name())) .collect(Collectors.toList()), true, - ClassNames.getServiceClientClassName(service)); + getClassNames().getServiceClientClassName(service)); return typeStore; } - private static TypeNode getCallableType(Method protoMethod) { - TypeNode callableType = FIXED_TYPESTORE.get("UnaryCallable"); + private TypeNode getCallableType(Method protoMethod) { + TypeNode callableType = getFixedTypeStore().get("UnaryCallable"); switch (protoMethod.stream()) { case CLIENT: - callableType = FIXED_TYPESTORE.get("ClientStreamingCallable"); + callableType = getFixedTypeStore().get("ClientStreamingCallable"); break; case SERVER: - callableType = FIXED_TYPESTORE.get("ServerStreamingCallable"); + callableType = getFixedTypeStore().get("ServerStreamingCallable"); break; case BIDI: - callableType = FIXED_TYPESTORE.get("BidiStreamingCallable"); + callableType = getFixedTypeStore().get("BidiStreamingCallable"); break; case NONE: // Fall through @@ -1107,7 +925,7 @@ private static TypeNode getCallableType(Method protoMethod) { protoMethod.inputType().reference(), protoMethod.outputType().reference()))); } - private static EnumRefExpr getMethodDescriptorMethodTypeExpr(Method protoMethod) { + protected EnumRefExpr getMethodDescriptorMethodTypeExpr(Method protoMethod) { String enumName = ""; switch (protoMethod.stream()) { case CLIENT: @@ -1132,28 +950,22 @@ private static EnumRefExpr getMethodDescriptorMethodTypeExpr(Method protoMethod) .build(); } - private static String getProtoRpcFullMethodName(Service protoService, Method protoMethod) { - if (protoMethod.isMixin()) { - return String.format("%s/%s", protoMethod.mixedInApiName(), protoMethod.name()); - } - - if (!REROUTE_TO_GRPC_INTERFACE_SERVICE_ALLOWLIST.contains(protoService.protoPakkage()) - || !REROUTE_TO_GRPC_INTERFACE_IAM_METHOD_ALLOWLIST.contains(protoMethod.name())) { - return String.format( - "%s.%s/%s", protoService.protoPakkage(), protoService.name(), protoMethod.name()); - } - // This is meant to be a temporary workaround until the allow-listed services come up with a - // long-term solution. - return String.format("google.iam.v1.IAMPolicy/%s", protoMethod.name()); - } - - private static CommentStatement createProtectedCtorComment(Service service) { + private CommentStatement createProtectedCtorComment(Service service) { return CommentStatement.withComment( JavaDocComment.withComment( String.format( "Constructs an instance of %s, using the given settings. This is protected so that" + " it is easy to make a subclass, but otherwise, the static factory methods" + " should be preferred.", - ClassNames.getGrpcServiceStubClassName(service)))); + getClassNames().getTransportServiceStubClassName(service)))); + } + + protected String getProtoRpcFullMethodName(Service protoService, Method protoMethod) { + if (protoMethod.isMixin()) { + return String.format("%s/%s", protoMethod.mixedInApiName(), protoMethod.name()); + } + + return String.format( + "%s.%s/%s", protoService.protoPakkage(), protoService.name(), protoMethod.name()); } } diff --git a/src/main/java/com/google/api/generator/gapic/composer/ServiceStubSettingsClassComposer.java b/src/main/java/com/google/api/generator/gapic/composer/common/AbstractServiceStubSettingsClassComposer.java similarity index 89% rename from src/main/java/com/google/api/generator/gapic/composer/ServiceStubSettingsClassComposer.java rename to src/main/java/com/google/api/generator/gapic/composer/common/AbstractServiceStubSettingsClassComposer.java index 2a6dc6b8c4..ba0327c0a9 100644 --- a/src/main/java/com/google/api/generator/gapic/composer/ServiceStubSettingsClassComposer.java +++ b/src/main/java/com/google/api/generator/gapic/composer/common/AbstractServiceStubSettingsClassComposer.java @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -package com.google.api.generator.gapic.composer; +package com.google.api.generator.gapic.composer.common; import com.google.api.MonitoredResourceDescriptor; import com.google.api.core.ApiFunction; @@ -26,10 +26,6 @@ import com.google.api.gax.core.GaxProperties; import com.google.api.gax.core.GoogleCredentialsProvider; import com.google.api.gax.core.InstantiatingExecutorProvider; -import com.google.api.gax.grpc.GaxGrpcProperties; -import com.google.api.gax.grpc.GrpcTransportChannel; -import com.google.api.gax.grpc.InstantiatingGrpcChannelProvider; -import com.google.api.gax.grpc.ProtoOperationTransformers; import com.google.api.gax.longrunning.OperationSnapshot; import com.google.api.gax.longrunning.OperationTimedPollAlgorithm; import com.google.api.gax.retrying.RetrySettings; @@ -121,7 +117,7 @@ import javax.annotation.Nullable; import org.threeten.bp.Duration; -public class ServiceStubSettingsClassComposer implements ClassComposer { +public abstract class AbstractServiceStubSettingsClassComposer implements ClassComposer { private static final Statement EMPTY_LINE_STATEMENT = EmptyLineStatement.create(); private static final String BATCHING_DESC_PATTERN = "%s_BATCHING_DESC"; @@ -139,27 +135,31 @@ public class ServiceStubSettingsClassComposer implements ClassComposer { private static final String SETTINGS_LITERAL = "Settings"; private static final String DOT = "."; - private static final String LEFT_BRACE = "{"; - private static final String RIGHT_BRACE = "}"; - private static final String SLASH = "/"; - private static final ServiceStubSettingsClassComposer INSTANCE = - new ServiceStubSettingsClassComposer(); - - private static final TypeStore FIXED_TYPESTORE = createStaticTypes(); private static final VariableExpr DEFAULT_SERVICE_SCOPES_VAR_EXPR = createDefaultServiceScopesVarExpr(); private static final VariableExpr NESTED_UNARY_METHOD_SETTINGS_BUILDERS_VAR_EXPR = createNestedUnaryMethodSettingsBuildersVarExpr(); private static final VariableExpr NESTED_RETRYABLE_CODE_DEFINITIONS_VAR_EXPR = createNestedRetryableCodeDefinitionsVarExpr(); - private static final VariableExpr NESTED_RETRY_PARAM_DEFINITIONS_VAR_EXPR = - createNestedRetryParamDefinitionsVarExpr(); - - private ServiceStubSettingsClassComposer() {} - public static ServiceStubSettingsClassComposer instance() { - return INSTANCE; + private final VariableExpr nestedRetryParamDefinitionsVarExpr; + + private final ClassNames classNames; + private final TypeStore fixedTypeStore; + private final Class transportChannelClass; + private final String transportGetterName; + + protected AbstractServiceStubSettingsClassComposer( + TypeStore fixedTypeStore, + ClassNames classNames, + Class transportChannelClass, + String transportGetterName) { + this.fixedTypeStore = fixedTypeStore; + this.classNames = classNames; + this.transportChannelClass = transportChannelClass; + this.nestedRetryParamDefinitionsVarExpr = createNestedRetryParamDefinitionsVarExpr(); + this.transportGetterName = transportGetterName; } @Override @@ -201,10 +201,33 @@ public GapicClass generate(GapicContext context, Service service) { return GapicClass.create(GapicClass.Kind.STUB, classDef); } - private static List createClassAnnotations(Service service) { + protected abstract MethodDefinition createDefaultTransportTransportProviderBuilderMethod(); + + protected abstract MethodDefinition createDefaultApiClientHeaderProviderBuilderMethod( + Service service, TypeStore typeStore); + + public abstract MethodDefinition createDefaultTransportChannelProviderMethod(); + + protected TypeStore getFixedTypeStore() { + return fixedTypeStore; + } + + protected ClassNames getClassNames() { + return classNames; + } + + protected Class getTransportChannelClass() { + return transportChannelClass; + } + + protected String getTransportGetterName() { + return transportGetterName; + } + + private List createClassAnnotations(Service service) { List annotations = new ArrayList<>(); if (!PackageChecker.isGaApi(service.pakkage())) { - annotations.add(AnnotationNode.withType(FIXED_TYPESTORE.get("BetaApi"))); + annotations.add(AnnotationNode.withType(getFixedTypeStore().get("BetaApi"))); } if (service.isDeprecated()) { @@ -213,7 +236,7 @@ private static List createClassAnnotations(Service service) { annotations.add( AnnotationNode.builder() - .setType(FIXED_TYPESTORE.get("Generated")) + .setType(getFixedTypeStore().get("Generated")) .setDescription("by gapic-generator-java") .build()); return annotations; @@ -246,10 +269,10 @@ private static List createClassHeaderComments( classType); } - private static TypeNode createExtendsType(Service service, TypeStore typeStore) { + private TypeNode createExtendsType(Service service, TypeStore typeStore) { TypeNode thisClassType = typeStore.get(ClassNames.getServiceStubSettingsClassName(service)); return TypeNode.withReference( - FIXED_TYPESTORE + getFixedTypeStore() .get("StubSettings") .reference() .copyAndSetGenerics(Arrays.asList(thisClassType.reference()))); @@ -291,7 +314,7 @@ private static Map createMethodSettingsClassMemberVarExprs return varExprs; } - private static List createClassStatements( + private List createClassStatements( Service service, GapicServiceConfig serviceConfig, Map methodSettingsMemberVarExprs, @@ -312,7 +335,7 @@ private static List createClassStatements( .build(); MethodInvocationExpr listBuilderExpr = MethodInvocationExpr.builder() - .setStaticReferenceType(FIXED_TYPESTORE.get("ImmutableList")) + .setStaticReferenceType(getFixedTypeStore().get("ImmutableList")) .setGenerics(Arrays.asList(ConcreteReference.withClazz(String.class))) .setMethodName("builder") .build(); @@ -376,7 +399,7 @@ private static List createClassStatements( return statements; } - private static List createPagingStaticAssignExprs( + private List createPagingStaticAssignExprs( Service service, GapicServiceConfig serviceConfig, Map messageTypes, @@ -625,7 +648,7 @@ private static Expr createPagedListDescriptorAssignExpr( .build(); } - private static Expr createPagedListResponseFactoryAssignExpr( + private Expr createPagedListResponseFactoryAssignExpr( VariableExpr pageStrDescVarExpr, Method method, TypeNode repeatedResponseType, @@ -662,7 +685,7 @@ private static Expr createPagedListResponseFactoryAssignExpr( VariableExpr contextVarExpr = VariableExpr.withVariable( Variable.builder() - .setType(FIXED_TYPESTORE.get("ApiCallContext")) + .setType(getFixedTypeStore().get("ApiCallContext")) .setName("context") .build()); VariableExpr futureResponseVarExpr = @@ -695,7 +718,7 @@ private static Expr createPagedListResponseFactoryAssignExpr( .setVariableExpr(pageContextVarExpr.toBuilder().setIsDecl(true).build()) .setValueExpr( MethodInvocationExpr.builder() - .setStaticReferenceType(FIXED_TYPESTORE.get("PageContext")) + .setStaticReferenceType(getFixedTypeStore().get("PageContext")) .setMethodName("create") .setArguments( callableVarExpr, pageStrDescVarExpr, requestVarExpr, contextVarExpr) @@ -765,7 +788,7 @@ private static Expr createPagedListResponseFactoryAssignExpr( .build(); } - private static List createClassMethods( + private List createClassMethods( Service service, Map methodSettingsMemberVarExprs, Set deprecatedSettingVarNames, @@ -805,12 +828,13 @@ private static List createMethodSettingsGetterMethods( .collect(Collectors.toList()); } - private static MethodDefinition createCreateStubMethod(Service service, TypeStore typeStore) { + private MethodDefinition createCreateStubMethod(Service service, TypeStore typeStore) { // Set up the if-statement. - Expr grpcTransportNameExpr = + Expr tRansportNameExpr = MethodInvocationExpr.builder() - .setStaticReferenceType(FIXED_TYPESTORE.get("GrpcTransportChannel")) - .setMethodName("getGrpcTransportName") + .setStaticReferenceType( + getFixedTypeStore().get(getTransportChannelClass().getSimpleName())) + .setMethodName(getTransportGetterName()) .build(); Expr getTransportNameExpr = @@ -825,13 +849,14 @@ private static MethodDefinition createCreateStubMethod(Service service, TypeStor MethodInvocationExpr.builder() .setExprReferenceExpr(getTransportNameExpr) .setMethodName("equals") - .setArguments(grpcTransportNameExpr) + .setArguments(tRansportNameExpr) .setReturnType(TypeNode.BOOLEAN) .build(); Expr createExpr = MethodInvocationExpr.builder() - .setStaticReferenceType(typeStore.get(ClassNames.getGrpcServiceStubClassName(service))) + .setStaticReferenceType( + typeStore.get(getClassNames().getTransportServiceStubClassName(service))) .setMethodName("create") .setArguments( ValueExpr.withValue( @@ -864,7 +889,7 @@ private static MethodDefinition createCreateStubMethod(Service service, TypeStor TypeNode returnType = typeStore.get(ClassNames.getServiceStubClassName(service)); AnnotationNode annotation = AnnotationNode.builder() - .setType(FIXED_TYPESTORE.get("BetaApi")) + .setType(getFixedTypeStore().get("BetaApi")) .setDescription( "A restructuring of stub classes is planned, so this may break in the future") .build(); @@ -879,7 +904,7 @@ private static MethodDefinition createCreateStubMethod(Service service, TypeStor .build(); } - private static List createDefaultHelperAndGetterMethods( + private List createDefaultHelperAndGetterMethods( Service service, TypeStore typeStore) { List javaMethods = new ArrayList<>(); @@ -897,7 +922,8 @@ private static List createDefaultHelperAndGetterMethods( .setName("defaultExecutorProviderBuilder") .setReturnExpr( MethodInvocationExpr.builder() - .setStaticReferenceType(FIXED_TYPESTORE.get("InstantiatingExecutorProvider")) + .setStaticReferenceType( + getFixedTypeStore().get("InstantiatingExecutorProvider")) .setMethodName("newBuilder") .setReturnType(returnType) .build()) @@ -940,7 +966,7 @@ private static List createDefaultHelperAndGetterMethods( ConcreteReference.withClazz(GoogleCredentialsProvider.Builder.class)); MethodInvocationExpr credsProviderBuilderExpr = MethodInvocationExpr.builder() - .setStaticReferenceType(FIXED_TYPESTORE.get("GoogleCredentialsProvider")) + .setStaticReferenceType(getFixedTypeStore().get("GoogleCredentialsProvider")) .setMethodName("newBuilder") .build(); credsProviderBuilderExpr = @@ -961,123 +987,14 @@ private static List createDefaultHelperAndGetterMethods( .setReturnExpr(credsProviderBuilderExpr) .build()); - // Create the defaultGrpcTransportProviderBuilder method. - returnType = - TypeNode.withReference( - ConcreteReference.withClazz(InstantiatingGrpcChannelProvider.Builder.class)); - MethodInvocationExpr grpcChannelProviderBuilderExpr = - MethodInvocationExpr.builder() - .setStaticReferenceType(FIXED_TYPESTORE.get("InstantiatingGrpcChannelProvider")) - .setMethodName("newBuilder") - .build(); - grpcChannelProviderBuilderExpr = - MethodInvocationExpr.builder() - .setExprReferenceExpr(grpcChannelProviderBuilderExpr) - .setMethodName("setMaxInboundMessageSize") - .setArguments( - VariableExpr.builder() - .setVariable( - Variable.builder().setType(TypeNode.INT).setName("MAX_VALUE").build()) - .setStaticReferenceType(TypeNode.INT_OBJECT) - .build()) - .setReturnType(returnType) - .build(); - javaMethods.add( - MethodDefinition.builder() - .setHeaderCommentStatements( - SettingsCommentComposer.DEFAULT_GRPC_TRANSPORT_PROVIDER_BUILDER_METHOD_COMMENT) - .setScope(ScopeNode.PUBLIC) - .setIsStatic(true) - .setReturnType(returnType) - .setName("defaultGrpcTransportProviderBuilder") - .setReturnExpr(grpcChannelProviderBuilderExpr) - .build()); - - // Create the defaultTransportChannelProvider method. - returnType = FIXED_TYPESTORE.get("TransportChannelProvider"); - MethodInvocationExpr transportProviderBuilderExpr = - MethodInvocationExpr.builder().setMethodName("defaultGrpcTransportProviderBuilder").build(); - transportProviderBuilderExpr = - MethodInvocationExpr.builder() - .setExprReferenceExpr(transportProviderBuilderExpr) - .setMethodName("build") - .setReturnType(returnType) - .build(); - javaMethods.add( - MethodDefinition.builder() - .setScope(ScopeNode.PUBLIC) - .setIsStatic(true) - .setReturnType(returnType) - .setName("defaultTransportChannelProvider") - .setReturnExpr(transportProviderBuilderExpr) - .build()); - - // Create the defaultApiClientHeaderProviderBuilder method. - returnType = - TypeNode.withReference(ConcreteReference.withClazz(ApiClientHeaderProvider.Builder.class)); - MethodInvocationExpr returnExpr = - MethodInvocationExpr.builder() - .setStaticReferenceType(FIXED_TYPESTORE.get("ApiClientHeaderProvider")) - .setMethodName("newBuilder") - .build(); - - MethodInvocationExpr versionArgExpr = - MethodInvocationExpr.builder() - .setStaticReferenceType(FIXED_TYPESTORE.get("GaxProperties")) - .setMethodName("getLibraryVersion") - .setArguments( - VariableExpr.builder() - .setVariable( - Variable.builder().setType(TypeNode.CLASS_OBJECT).setName("class").build()) - .setStaticReferenceType( - typeStore.get(ClassNames.getServiceStubSettingsClassName(service))) - .build()) - .build(); - - returnExpr = - MethodInvocationExpr.builder() - .setExprReferenceExpr(returnExpr) - .setMethodName("setGeneratedLibToken") - .setArguments(ValueExpr.withValue(StringObjectValue.withValue("gapic")), versionArgExpr) - .build(); - returnExpr = - MethodInvocationExpr.builder() - .setExprReferenceExpr(returnExpr) - .setMethodName("setTransportToken") - .setArguments( - MethodInvocationExpr.builder() - .setStaticReferenceType(FIXED_TYPESTORE.get("GaxGrpcProperties")) - .setMethodName("getGrpcTokenName") - .build(), - MethodInvocationExpr.builder() - .setStaticReferenceType(FIXED_TYPESTORE.get("GaxGrpcProperties")) - .setMethodName("getGrpcVersion") - .build()) - .setReturnType(returnType) - .build(); - - AnnotationNode annotation = - AnnotationNode.builder() - .setType(FIXED_TYPESTORE.get("BetaApi")) - .setDescription( - "The surface for customizing headers is not stable yet and may change in the" - + " future.") - .build(); - javaMethods.add( - MethodDefinition.builder() - .setAnnotations(Arrays.asList(annotation)) - .setScope(ScopeNode.PUBLIC) - .setIsStatic(true) - .setReturnType(returnType) - .setName("defaultApiClientHeaderProviderBuilder") - .setReturnExpr(returnExpr) - .build()); + javaMethods.add(createDefaultTransportTransportProviderBuilderMethod()); + javaMethods.add(createDefaultTransportChannelProviderMethod()); + javaMethods.add(createDefaultApiClientHeaderProviderBuilderMethod(service, typeStore)); return javaMethods; } - private static List createBuilderHelperMethods( - Service service, TypeStore typeStore) { + private List createBuilderHelperMethods(Service service, TypeStore typeStore) { List javaMethods = new ArrayList<>(); // Create the newBuilder() method. final TypeNode builderReturnType = typeStore.get(NESTED_BUILDER_CLASS_NAME); @@ -1102,7 +1019,7 @@ private static List createBuilderHelperMethods( VariableExpr clientContextVarExpr = VariableExpr.withVariable( Variable.builder() - .setType(FIXED_TYPESTORE.get("ClientContext")) + .setType(getFixedTypeStore().get("ClientContext")) .setName("clientContext") .build()); javaMethods.add( @@ -1133,7 +1050,7 @@ private static List createBuilderHelperMethods( return javaMethods; } - private static MethodDefinition createClassConstructor( + private MethodDefinition createClassConstructor( Service service, Map methodSettingsMemberVarExprs, TypeStore typeStore) { @@ -1147,7 +1064,7 @@ private static MethodDefinition createClassConstructor( Expr superCtorExpr = ReferenceConstructorExpr.superBuilder() - .setType(FIXED_TYPESTORE.get("StubSettings")) + .setType(getFixedTypeStore().get("StubSettings")) .setArguments(settingsBuilderVarExpr) .build(); @@ -1184,7 +1101,7 @@ private static MethodDefinition createClassConstructor( .build(); } - private static ClassDefinition createNestedBuilderClass( + private ClassDefinition createNestedBuilderClass( Service service, @Nullable GapicServiceConfig serviceConfig, TypeStore typeStore) { // TODO(miraleung): Robustify this against a null serviceConfig. String thisClassName = ClassNames.getServiceStubSettingsClassName(service); @@ -1234,7 +1151,7 @@ private static ClassDefinition createNestedBuilderClass( .build(); } - private static List createNestedClassStatements( + private List createNestedClassStatements( Service service, GapicServiceConfig serviceConfig, Map nestedMethodSettingsMemberVarExprs) { @@ -1275,16 +1192,16 @@ private static List createNestedClassStatements( // Declare the RETRY_PARAM_DEFINITIONS field. statements.add( - exprStatementFn.apply(varStaticDeclFn.apply(NESTED_RETRY_PARAM_DEFINITIONS_VAR_EXPR))); + exprStatementFn.apply(varStaticDeclFn.apply(nestedRetryParamDefinitionsVarExpr))); statements.add( RetrySettingsComposer.createRetryParamDefinitionsBlock( - service, serviceConfig, NESTED_RETRY_PARAM_DEFINITIONS_VAR_EXPR)); + service, serviceConfig, nestedRetryParamDefinitionsVarExpr)); return statements; } - private static List createNestedClassMethods( + private List createNestedClassMethods( Service service, GapicServiceConfig serviceConfig, TypeNode superType, @@ -1306,7 +1223,7 @@ private static List createNestedClassMethods( return nestedClassMethods; } - private static MethodDefinition createNestedClassInitDefaultsMethod( + private MethodDefinition createNestedClassInitDefaultsMethod( Service service, @Nullable GapicServiceConfig serviceConfig, TypeStore typeStore) { // TODO(miraleung): Robustify this against a null serviceConfig. TypeNode builderType = typeStore.get(NESTED_BUILDER_CLASS_NAME); @@ -1346,7 +1263,7 @@ private static MethodDefinition createNestedClassInitDefaultsMethod( method, builderVarExpr, NESTED_RETRYABLE_CODE_DEFINITIONS_VAR_EXPR, - NESTED_RETRY_PARAM_DEFINITIONS_VAR_EXPR))); + nestedRetryParamDefinitionsVarExpr))); bodyStatements.add(EMPTY_LINE_STATEMENT); } for (Method method : service.methods()) { @@ -1361,7 +1278,7 @@ private static MethodDefinition createNestedClassInitDefaultsMethod( method, builderVarExpr, NESTED_RETRYABLE_CODE_DEFINITIONS_VAR_EXPR, - NESTED_RETRY_PARAM_DEFINITIONS_VAR_EXPR))); + nestedRetryParamDefinitionsVarExpr))); bodyStatements.add(EMPTY_LINE_STATEMENT); } @@ -1376,7 +1293,7 @@ private static MethodDefinition createNestedClassInitDefaultsMethod( .build(); } - private static List createNestedClassConstructorMethods( + private List createNestedClassConstructorMethods( Service service, GapicServiceConfig serviceConfig, Map nestedMethodSettingsMemberVarExprs, @@ -1397,7 +1314,7 @@ private static List createNestedClassConstructorMethods( .setType(builderType) .setArguments( CastExpr.builder() - .setType(FIXED_TYPESTORE.get("ClientContext")) + .setType(getFixedTypeStore().get("ClientContext")) .setExpr(ValueExpr.createNullExpr()) .build()) .build()))) @@ -1407,7 +1324,7 @@ private static List createNestedClassConstructorMethods( VariableExpr clientContextVarExpr = VariableExpr.withVariable( Variable.builder() - .setType(FIXED_TYPESTORE.get("ClientContext")) + .setType(getFixedTypeStore().get("ClientContext")) .setName("clientContext") .build()); Reference pagedSettingsBuilderRef = @@ -1476,7 +1393,7 @@ private static List createNestedClassConstructorMethods( } Expr newBatchingSettingsExpr = MethodInvocationExpr.builder() - .setStaticReferenceType(FIXED_TYPESTORE.get("BatchingSettings")) + .setStaticReferenceType(getFixedTypeStore().get("BatchingSettings")) .setMethodName("newBuilder") .build(); newBatchingSettingsExpr = @@ -1495,7 +1412,7 @@ private static List createNestedClassConstructorMethods( .setArguments( VariableExpr.withVariable( Variable.builder() - .setType(FIXED_TYPESTORE.get("BatchingDescriptor")) + .setType(getFixedTypeStore().get("BatchingDescriptor")) .setName(batchingDescVarName) .build())) .build(); @@ -1520,7 +1437,7 @@ private static List createNestedClassConstructorMethods( VariableExpr argVar = VariableExpr.withVariable( Variable.builder() - .setType(FIXED_TYPESTORE.get("PagedListResponseFactory")) + .setType(getFixedTypeStore().get("PagedListResponseFactory")) .setName(memberVarName) .build()); Expr builderExpr = @@ -1544,7 +1461,7 @@ private static List createNestedClassConstructorMethods( .setVariableExpr(NESTED_UNARY_METHOD_SETTINGS_BUILDERS_VAR_EXPR) .setValueExpr( MethodInvocationExpr.builder() - .setStaticReferenceType(FIXED_TYPESTORE.get("ImmutableList")) + .setStaticReferenceType(getFixedTypeStore().get("ImmutableList")) .setGenerics( NESTED_UNARY_METHOD_SETTINGS_BUILDERS_VAR_EXPR .type() @@ -1631,7 +1548,7 @@ private static List createNestedClassConstructorMethods( return ctorMethods; } - private static MethodDefinition createNestedClassCreateDefaultMethod(TypeStore typeStore) { + private MethodDefinition createNestedClassCreateDefaultMethod(TypeStore typeStore) { List bodyStatements = new ArrayList<>(); // Initialize the builder: Builder builder = new Builder((ClientContext) null); @@ -1648,7 +1565,7 @@ private static MethodDefinition createNestedClassCreateDefaultMethod(TypeStore t .setType(builderType) .setArguments( CastExpr.builder() - .setType(FIXED_TYPESTORE.get("ClientContext")) + .setType(getFixedTypeStore().get("ClientContext")) .setExpr(ValueExpr.createNullExpr()) .build()) .build()) @@ -1772,7 +1689,7 @@ private static MethodDefinition createNestedClassUnaryMethodSettingsBuilderGette .build(); } - private static List createNestedClassSettingsBuilderGetterMethods( + private List createNestedClassSettingsBuilderGetterMethods( Map nestedMethodSettingsMemberVarExprs, Set nestedDeprecatedSettingVarNames) { Reference operationCallSettingsBuilderRef = @@ -1784,7 +1701,7 @@ private static List createNestedClassSettingsBuilderGetterMeth .equals(operationCallSettingsBuilderRef); AnnotationNode lroBetaAnnotation = AnnotationNode.builder() - .setType(FIXED_TYPESTORE.get("BetaApi")) + .setType(getFixedTypeStore().get("BetaApi")) .setDescription( "The surface for use by generated code is not stable yet and may change in the" + " future.") @@ -1843,7 +1760,7 @@ private static MethodDefinition createNestedClassBuildMethod( .build(); } - private static TypeStore createStaticTypes() { + protected static TypeStore createCommonStaticTypes() { List concreteClazzes = Arrays.asList( ApiCallContext.class, @@ -1859,17 +1776,14 @@ private static TypeStore createStaticTypes() { Duration.class, Empty.class, FlowControlSettings.class, - GaxGrpcProperties.class, GaxProperties.class, Generated.class, GoogleCredentialsProvider.class, - GrpcTransportChannel.class, IOException.class, ImmutableList.class, ImmutableMap.class, ImmutableSet.class, InstantiatingExecutorProvider.class, - InstantiatingGrpcChannelProvider.class, LimitExceededBehavior.class, List.class, Lists.class, @@ -1883,7 +1797,6 @@ private static TypeStore createStaticTypes() { PagedListDescriptor.class, PagedListResponseFactory.class, PartitionKey.class, - ProtoOperationTransformers.class, RequestBuilder.class, RetrySettings.class, ServerStreamingCallSettings.class, @@ -1896,7 +1809,7 @@ private static TypeStore createStaticTypes() { return new TypeStore(concreteClazzes); } - private static TypeStore createDynamicTypes(Service service, String pakkage) { + private TypeStore createDynamicTypes(Service service, String pakkage) { TypeStore typeStore = new TypeStore(); // This type. @@ -1905,7 +1818,7 @@ private static TypeStore createDynamicTypes(Service service, String pakkage) { pakkage, Arrays.asList( thisClassName, - ClassNames.getGrpcServiceStubClassName(service), + getClassNames().getTransportServiceStubClassName(service), ClassNames.getServiceStubSettingsClassName(service), ClassNames.getServiceStubClassName(service))); @@ -1978,13 +1891,14 @@ private static VariableExpr createNestedRetryableCodeDefinitionsVarExpr() { .build()); } - private static VariableExpr createNestedRetryParamDefinitionsVarExpr() { + private VariableExpr createNestedRetryParamDefinitionsVarExpr() { TypeNode varType = TypeNode.withReference( ConcreteReference.builder() .setClazz(ImmutableMap.class) .setGenerics( - Arrays.asList(TypeNode.STRING, FIXED_TYPESTORE.get("RetrySettings")).stream() + Arrays.asList(TypeNode.STRING, getFixedTypeStore().get("RetrySettings")) + .stream() .map(t -> t.reference()) .collect(Collectors.toList())) .build()); diff --git a/src/main/java/com/google/api/generator/gapic/composer/common/BUILD.bazel b/src/main/java/com/google/api/generator/gapic/composer/common/BUILD.bazel new file mode 100644 index 0000000000..be2ec575c3 --- /dev/null +++ b/src/main/java/com/google/api/generator/gapic/composer/common/BUILD.bazel @@ -0,0 +1,50 @@ +load("@rules_java//java:defs.bzl", "java_library") + +package(default_visibility = ["//visibility:public"]) + +filegroup( + name = "common_files", + srcs = glob(["*.java"]), +) + +java_library( + name = "common", + srcs = [ + ":common_files", + ], + deps = [ + "//:service_config_java_proto", + "//src/main/java/com/google/api/generator/engine/ast", + "//src/main/java/com/google/api/generator/engine/writer", + "//src/main/java/com/google/api/generator/gapic:status_java_proto", + "//src/main/java/com/google/api/generator/gapic/composer/comment", + "//src/main/java/com/google/api/generator/gapic/composer/defaultvalue", + "//src/main/java/com/google/api/generator/gapic/composer/resourcename", + "//src/main/java/com/google/api/generator/gapic/composer/samplecode", + "//src/main/java/com/google/api/generator/gapic/composer/store", + "//src/main/java/com/google/api/generator/gapic/composer/utils", + "//src/main/java/com/google/api/generator/gapic/model", + "//src/main/java/com/google/api/generator/gapic/utils", + "//src/main/java/com/google/api/generator/util", + "@com_google_api_api_common//jar", + "@com_google_api_gax_java//gax:gax", + "@com_google_api_gax_java//gax:gax_testlib", + "@com_google_api_gax_java//gax-grpc:gax_grpc", + "@com_google_api_gax_java//gax-grpc:gax_grpc_testlib", + "@com_google_code_findbugs_jsr305//jar", + "@com_google_googleapis//gapic/metadata:metadata_java_proto", + "@com_google_googleapis//google/api:api_java_proto", + "@com_google_googleapis//google/longrunning:longrunning_java_proto", + "@com_google_googleapis//google/rpc:rpc_java_proto", + "@com_google_guava_guava//jar", + "@com_google_protobuf//:protobuf_java", + "@com_google_protobuf//:protobuf_java_util", + "@com_google_protobuf//java/core", + "@io_grpc_grpc_java//api", + "@io_grpc_grpc_java//protobuf", + "@io_grpc_grpc_java//stub", + "@javax_annotation_javax_annotation_api//jar", + "@junit_junit//jar", + "@org_threeten_threetenbp//jar", + ], +) diff --git a/src/main/java/com/google/api/generator/gapic/composer/BatchingDescriptorComposer.java b/src/main/java/com/google/api/generator/gapic/composer/common/BatchingDescriptorComposer.java similarity index 99% rename from src/main/java/com/google/api/generator/gapic/composer/BatchingDescriptorComposer.java rename to src/main/java/com/google/api/generator/gapic/composer/common/BatchingDescriptorComposer.java index c2509b2e6c..f3a05ba904 100644 --- a/src/main/java/com/google/api/generator/gapic/composer/BatchingDescriptorComposer.java +++ b/src/main/java/com/google/api/generator/gapic/composer/common/BatchingDescriptorComposer.java @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -package com.google.api.generator.gapic.composer; +package com.google.api.generator.gapic.composer.common; import com.google.api.gax.batching.PartitionKey; import com.google.api.gax.batching.RequestBuilder; diff --git a/src/main/java/com/google/api/generator/gapic/composer/ClassComposer.java b/src/main/java/com/google/api/generator/gapic/composer/common/ClassComposer.java similarity index 93% rename from src/main/java/com/google/api/generator/gapic/composer/ClassComposer.java rename to src/main/java/com/google/api/generator/gapic/composer/common/ClassComposer.java index e7bcbc014f..d8d87eadc1 100644 --- a/src/main/java/com/google/api/generator/gapic/composer/ClassComposer.java +++ b/src/main/java/com/google/api/generator/gapic/composer/common/ClassComposer.java @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -package com.google.api.generator.gapic.composer; +package com.google.api.generator.gapic.composer.common; import com.google.api.generator.gapic.model.GapicClass; import com.google.api.generator.gapic.model.GapicContext; diff --git a/src/main/java/com/google/api/generator/gapic/composer/RetrySettingsComposer.java b/src/main/java/com/google/api/generator/gapic/composer/common/RetrySettingsComposer.java similarity index 99% rename from src/main/java/com/google/api/generator/gapic/composer/RetrySettingsComposer.java rename to src/main/java/com/google/api/generator/gapic/composer/common/RetrySettingsComposer.java index 77253189d2..4a20961399 100644 --- a/src/main/java/com/google/api/generator/gapic/composer/RetrySettingsComposer.java +++ b/src/main/java/com/google/api/generator/gapic/composer/common/RetrySettingsComposer.java @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -package com.google.api.generator.gapic.composer; +package com.google.api.generator.gapic.composer.common; import com.google.api.gax.batching.BatchingSettings; import com.google.api.gax.batching.FlowControlSettings; diff --git a/src/main/java/com/google/api/generator/gapic/composer/ServiceClientClassComposer.java b/src/main/java/com/google/api/generator/gapic/composer/common/ServiceClientClassComposer.java similarity index 99% rename from src/main/java/com/google/api/generator/gapic/composer/ServiceClientClassComposer.java rename to src/main/java/com/google/api/generator/gapic/composer/common/ServiceClientClassComposer.java index 2c67ddf632..02db92f992 100644 --- a/src/main/java/com/google/api/generator/gapic/composer/ServiceClientClassComposer.java +++ b/src/main/java/com/google/api/generator/gapic/composer/common/ServiceClientClassComposer.java @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -package com.google.api.generator.gapic.composer; +package com.google.api.generator.gapic.composer.common; import com.google.api.core.ApiFunction; import com.google.api.core.ApiFuture; diff --git a/src/main/java/com/google/api/generator/gapic/composer/ServiceStubClassComposer.java b/src/main/java/com/google/api/generator/gapic/composer/common/ServiceStubClassComposer.java similarity index 99% rename from src/main/java/com/google/api/generator/gapic/composer/ServiceStubClassComposer.java rename to src/main/java/com/google/api/generator/gapic/composer/common/ServiceStubClassComposer.java index ec737e770b..ca8405ba93 100644 --- a/src/main/java/com/google/api/generator/gapic/composer/ServiceStubClassComposer.java +++ b/src/main/java/com/google/api/generator/gapic/composer/common/ServiceStubClassComposer.java @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -package com.google.api.generator.gapic.composer; +package com.google.api.generator.gapic.composer.common; import com.google.api.core.BetaApi; import com.google.api.gax.core.BackgroundResource; diff --git a/src/main/java/com/google/api/generator/gapic/composer/grpc/BUILD.bazel b/src/main/java/com/google/api/generator/gapic/composer/grpc/BUILD.bazel new file mode 100644 index 0000000000..daabba93e6 --- /dev/null +++ b/src/main/java/com/google/api/generator/gapic/composer/grpc/BUILD.bazel @@ -0,0 +1,51 @@ +load("@rules_java//java:defs.bzl", "java_library") + +package(default_visibility = ["//visibility:public"]) + +filegroup( + name = "grpc_files", + srcs = glob(["*.java"]), +) + +java_library( + name = "grpc", + srcs = [ + ":grpc_files", + ], + deps = [ + "//:service_config_java_proto", + "//src/main/java/com/google/api/generator/engine/ast", + "//src/main/java/com/google/api/generator/engine/writer", + "//src/main/java/com/google/api/generator/gapic:status_java_proto", + "//src/main/java/com/google/api/generator/gapic/composer/comment", + "//src/main/java/com/google/api/generator/gapic/composer/common", + "//src/main/java/com/google/api/generator/gapic/composer/defaultvalue", + "//src/main/java/com/google/api/generator/gapic/composer/resourcename", + "//src/main/java/com/google/api/generator/gapic/composer/samplecode", + "//src/main/java/com/google/api/generator/gapic/composer/store", + "//src/main/java/com/google/api/generator/gapic/composer/utils", + "//src/main/java/com/google/api/generator/gapic/model", + "//src/main/java/com/google/api/generator/gapic/utils", + "//src/main/java/com/google/api/generator/util", + "@com_google_api_api_common//jar", + "@com_google_api_gax_java//gax", + "@com_google_api_gax_java//gax:gax_testlib", + "@com_google_api_gax_java//gax-grpc:gax_grpc", + "@com_google_api_gax_java//gax-grpc:gax_grpc_testlib", + "@com_google_code_findbugs_jsr305//jar", + "@com_google_googleapis//gapic/metadata:metadata_java_proto", + "@com_google_googleapis//google/api:api_java_proto", + "@com_google_googleapis//google/longrunning:longrunning_java_proto", + "@com_google_googleapis//google/rpc:rpc_java_proto", + "@com_google_guava_guava//jar", + "@com_google_protobuf//:protobuf_java", + "@com_google_protobuf//:protobuf_java_util", + "@com_google_protobuf//java/core", + "@io_grpc_grpc_java//api", + "@io_grpc_grpc_java//protobuf", + "@io_grpc_grpc_java//stub", + "@javax_annotation_javax_annotation_api//jar", + "@junit_junit//jar", + "@org_threeten_threetenbp//jar", + ], +) diff --git a/src/main/java/com/google/api/generator/gapic/composer/grpc/GrpcServiceCallableFactoryClassComposer.java b/src/main/java/com/google/api/generator/gapic/composer/grpc/GrpcServiceCallableFactoryClassComposer.java new file mode 100644 index 0000000000..edffe989e7 --- /dev/null +++ b/src/main/java/com/google/api/generator/gapic/composer/grpc/GrpcServiceCallableFactoryClassComposer.java @@ -0,0 +1,204 @@ +// Copyright 2021 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 +// +// http://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. + +package com.google.api.generator.gapic.composer.grpc; + +import com.google.api.gax.grpc.GrpcCallSettings; +import com.google.api.gax.grpc.GrpcCallableFactory; +import com.google.api.gax.grpc.GrpcStubCallableFactory; +import com.google.api.generator.engine.ast.MethodDefinition; +import com.google.api.generator.engine.ast.TypeNode; +import com.google.api.generator.gapic.composer.common.AbstractServiceCallableFactoryClassComposer; +import com.google.api.generator.gapic.composer.comment.StubCommentComposer; +import com.google.api.generator.gapic.composer.store.TypeStore; +import com.google.api.generator.gapic.composer.utils.ClassNames; +import com.google.longrunning.Operation; +import com.google.longrunning.stub.OperationsStub; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.stream.Collectors; + +public class GrpcServiceCallableFactoryClassComposer + extends AbstractServiceCallableFactoryClassComposer { + private static final GrpcServiceCallableFactoryClassComposer INSTANCE = + new GrpcServiceCallableFactoryClassComposer(); + + protected GrpcServiceCallableFactoryClassComposer() { + super( + createTypes(), + new StubCommentComposer("gRPC"), + new ClassNames("Grpc"), + GrpcCallSettings.class, + GrpcCallableFactory.class, + OperationsStub.class, + "grpcCallSettings"); + } + + public static GrpcServiceCallableFactoryClassComposer instance() { + return INSTANCE; + } + + @Override + protected List createClassImplements(TypeStore typeStore) { + return Arrays.asList(typeStore.get("GrpcStubCallableFactory")); + } + + protected List createClassMethods(TypeStore typeStore) { + List classMethods = new ArrayList<>(super.createClassMethods(typeStore)); + classMethods.addAll( + Arrays.asList( + createBidiStreamingCallableMethod(typeStore), + createServerStreamingCallableMethod(typeStore), + createClientStreamingCallableMethod(typeStore))); + return classMethods; + } + + protected MethodDefinition createUnaryCallableMethod(TypeStore typeStore) { + String methodVariantName = "Unary"; + String requestTemplateName = "RequestT"; + String responseTemplateName = "ResponseT"; + List methodTemplateNames = Arrays.asList(requestTemplateName, responseTemplateName); + return createGenericCallableMethod( + typeStore, + /*methodTemplateNames=*/ methodTemplateNames, + /*returnCallableKindName=*/ methodVariantName, + /*returnCallableTemplateNames=*/ methodTemplateNames, + /*methodVariantName=*/ methodVariantName, + /*grpcCallSettingsTemplateObjects=*/ methodTemplateNames.stream() + .map(n -> (Object) n) + .collect(Collectors.toList()), + /*callSettingsVariantName=*/ methodVariantName, + /*callSettingsTemplateObjects=*/ methodTemplateNames.stream() + .map(n -> (Object) n) + .collect(Collectors.toList())); + } + + protected MethodDefinition createPagedCallableMethod(TypeStore typeStore) { + String methodVariantName = "Paged"; + String requestTemplateName = "RequestT"; + String pagedResponseTemplateName = "PagedListResponseT"; + String responseTemplateName = "ResponseT"; + List methodTemplateNames = + Arrays.asList(requestTemplateName, responseTemplateName, pagedResponseTemplateName); + return createGenericCallableMethod( + typeStore, + /*methodTemplateNames=*/ methodTemplateNames, + /*returnCallableKindName=*/ "Unary", + /*returnCallableTemplateNames=*/ Arrays.asList( + requestTemplateName, pagedResponseTemplateName), + /*methodVariantName=*/ methodVariantName, + /*grpcCallSettingsTemplateObjects=*/ Arrays.asList( + requestTemplateName, responseTemplateName), + /*callSettingsVariantName=*/ methodVariantName, + /*callSettingsTemplateObjects=*/ methodTemplateNames.stream() + .map(n -> (Object) n) + .collect(Collectors.toList())); + } + + @Override + protected MethodDefinition createOperationCallableMethod(TypeStore typeStore) { + String methodVariantName = "Operation"; + String requestTemplateName = "RequestT"; + String responseTemplateName = "ResponseT"; + List methodTemplateNames = + Arrays.asList(requestTemplateName, responseTemplateName, "MetadataT"); + return createGenericCallableMethod( + typeStore, + /*methodTemplateNames=*/ methodTemplateNames, + /*returnCallableKindName=*/ methodVariantName, + /*returnCallableTemplateNames=*/ methodTemplateNames, + /*methodVariantName=*/ methodVariantName, + /*grpcCallSettingsTemplateObjects=*/ Arrays.asList( + requestTemplateName, typeStore.get("Operation")), + /*callSettingsVariantName=*/ methodVariantName, + /*callSettingsTemplateObjects=*/ methodTemplateNames.stream() + .map(n -> (Object) n) + .collect(Collectors.toList())); + } + + private MethodDefinition createBidiStreamingCallableMethod(TypeStore typeStore) { + String methodVariantName = "BidiStreaming"; + String requestTemplateName = "RequestT"; + String responseTemplateName = "ResponseT"; + List methodTemplateNames = Arrays.asList(requestTemplateName, responseTemplateName); + return createGenericCallableMethod( + typeStore, + /*methodTemplateNames=*/ methodTemplateNames, + /*returnCallableKindName=*/ methodVariantName, + /*returnCallableTemplateNames=*/ methodTemplateNames, + /*methodVariantName=*/ methodVariantName, + /*grpcCallSettingsTemplateObjects=*/ methodTemplateNames.stream() + .map(n -> (Object) n) + .collect(Collectors.toList()), + /*callSettingsVariantName=*/ "Streaming", + /*callSettingsTemplateObjects=*/ methodTemplateNames.stream() + .map(n -> (Object) n) + .collect(Collectors.toList())); + } + + private MethodDefinition createServerStreamingCallableMethod(TypeStore typeStore) { + String methodVariantName = "ServerStreaming"; + String requestTemplateName = "RequestT"; + String responseTemplateName = "ResponseT"; + List methodTemplateNames = Arrays.asList(requestTemplateName, responseTemplateName); + return createGenericCallableMethod( + typeStore, + /*methodTemplateNames=*/ methodTemplateNames, + /*returnCallableKindName=*/ methodVariantName, + /*returnCallableTemplateNames=*/ methodTemplateNames, + /*methodVariantName=*/ methodVariantName, + /*grpcCallSettingsTemplateObjects=*/ methodTemplateNames.stream() + .map(n -> (Object) n) + .collect(Collectors.toList()), + /*callSettingsVariantName=*/ methodVariantName, + /*callSettingsTemplateObjects=*/ methodTemplateNames.stream() + .map(n -> (Object) n) + .collect(Collectors.toList())); + } + + private MethodDefinition createClientStreamingCallableMethod(TypeStore typeStore) { + String methodVariantName = "ClientStreaming"; + String requestTemplateName = "RequestT"; + String responseTemplateName = "ResponseT"; + List methodTemplateNames = Arrays.asList(requestTemplateName, responseTemplateName); + return createGenericCallableMethod( + typeStore, + /*methodTemplateNames=*/ methodTemplateNames, + /*returnCallableKindName=*/ methodVariantName, + /*returnCallableTemplateNames=*/ methodTemplateNames, + /*methodVariantName=*/ methodVariantName, + /*grpcCallSettingsTemplateObjects=*/ methodTemplateNames.stream() + .map(n -> (Object) n) + .collect(Collectors.toList()), + /*callSettingsVariantName=*/ "Streaming", + /*callSettingsTemplateObjects=*/ methodTemplateNames.stream() + .map(n -> (Object) n) + .collect(Collectors.toList())); + } + + protected static TypeStore createTypes() { + TypeStore typeStore = createCommonTypes(); + typeStore.putAll( + Arrays.asList( + // gax-java gRPC classes. + GrpcCallSettings.class, + GrpcCallableFactory.class, + GrpcStubCallableFactory.class, + Operation.class)); + + typeStore.put("com.google.longrunning.stub", "OperationsStub"); + return typeStore; + } +} diff --git a/src/main/java/com/google/api/generator/gapic/composer/grpc/GrpcServiceStubClassComposer.java b/src/main/java/com/google/api/generator/gapic/composer/grpc/GrpcServiceStubClassComposer.java new file mode 100644 index 0000000000..e92c6d67f0 --- /dev/null +++ b/src/main/java/com/google/api/generator/gapic/composer/grpc/GrpcServiceStubClassComposer.java @@ -0,0 +1,338 @@ +// Copyright 2021 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 +// +// http://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. + +package com.google.api.generator.gapic.composer.grpc; + +import com.google.api.gax.grpc.GrpcCallSettings; +import com.google.api.gax.grpc.GrpcStubCallableFactory; +import com.google.api.gax.rpc.RequestParamsExtractor; +import com.google.api.generator.engine.ast.AnonymousClassExpr; +import com.google.api.generator.engine.ast.AssignmentExpr; +import com.google.api.generator.engine.ast.ConcreteReference; +import com.google.api.generator.engine.ast.Expr; +import com.google.api.generator.engine.ast.ExprStatement; +import com.google.api.generator.engine.ast.MethodDefinition; +import com.google.api.generator.engine.ast.MethodInvocationExpr; +import com.google.api.generator.engine.ast.ScopeNode; +import com.google.api.generator.engine.ast.Statement; +import com.google.api.generator.engine.ast.StringObjectValue; +import com.google.api.generator.engine.ast.TypeNode; +import com.google.api.generator.engine.ast.ValueExpr; +import com.google.api.generator.engine.ast.Variable; +import com.google.api.generator.engine.ast.VariableExpr; +import com.google.api.generator.gapic.composer.common.AbstractServiceStubClassComposer; +import com.google.api.generator.gapic.composer.comment.StubCommentComposer; +import com.google.api.generator.gapic.composer.store.TypeStore; +import com.google.api.generator.gapic.composer.utils.ClassNames; +import com.google.api.generator.gapic.model.Method; +import com.google.api.generator.gapic.model.Service; +import com.google.api.generator.gapic.utils.JavaStyle; +import com.google.common.base.Preconditions; +import com.google.common.collect.ImmutableMap; +import com.google.longrunning.stub.GrpcOperationsStub; +import io.grpc.MethodDescriptor; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.function.BiFunction; +import java.util.function.Function; +import java.util.stream.Collectors; + +public class GrpcServiceStubClassComposer extends AbstractServiceStubClassComposer { + private static final GrpcServiceStubClassComposer INSTANCE = new GrpcServiceStubClassComposer(); + + // Legacy support for the original reroute_to_grpc_interface option in gapic.yaml. These two APIs + // predate the modern way, which is to add the RPCs directly into the proto. + private static final Set REROUTE_TO_GRPC_INTERFACE_SERVICE_ALLOWLIST = + new HashSet<>(Arrays.asList("google.pubsub.v1")); + private static final Set REROUTE_TO_GRPC_INTERFACE_IAM_METHOD_ALLOWLIST = + new HashSet<>(Arrays.asList("SetIamPolicy", "GetIamPolicy", "TestIamPermissions")); + + protected GrpcServiceStubClassComposer() { + super( + createStaticTypes(), + new StubCommentComposer("gRPC"), + new ClassNames("Grpc"), + GrpcCallSettings.class, + GrpcStubCallableFactory.class, + MethodDescriptor.class, + GrpcOperationsStub.class); + } + + public static GrpcServiceStubClassComposer instance() { + return INSTANCE; + } + + private static TypeStore createStaticTypes() { + TypeStore typeStore = createCommonStaticTypes(); + typeStore.putAll( + Arrays.asList( + GrpcCallSettings.class, GrpcOperationsStub.class, GrpcStubCallableFactory.class)); + return typeStore; + } + + @Override + protected Statement createMethodDescriptorVariableDecl( + Service service, Method protoMethod, VariableExpr methodDescriptorVarExpr) { + MethodInvocationExpr methodDescriptorMaker = + MethodInvocationExpr.builder() + .setMethodName("newBuilder") + .setStaticReferenceType(getFixedTypeStore().get("MethodDescriptor")) + .setGenerics(methodDescriptorVarExpr.variable().type().reference().generics()) + .build(); + + BiFunction> methodMakerFn = + (mName, argExpr) -> + m -> + MethodInvocationExpr.builder() + .setMethodName(mName) + .setArguments(Arrays.asList(argExpr)) + .setExprReferenceExpr(m) + .build(); + + methodDescriptorMaker = + methodMakerFn + .apply("setType", getMethodDescriptorMethodTypeExpr(protoMethod)) + .apply(methodDescriptorMaker); + + String codeMethodNameArg = getProtoRpcFullMethodName(service, protoMethod); + methodDescriptorMaker = + methodMakerFn + .apply( + "setFullMethodName", + ValueExpr.withValue(StringObjectValue.withValue(codeMethodNameArg))) + .apply(methodDescriptorMaker); + + Function protoUtilsMarshallerFn = + m -> + MethodInvocationExpr.builder() + .setStaticReferenceType(getFixedTypeStore().get("ProtoUtils")) + .setMethodName("marshaller") + .setArguments(Arrays.asList(m)) + .build(); + MethodInvocationExpr methodInvocationArg = + MethodInvocationExpr.builder() + .setMethodName("getDefaultInstance") + .setStaticReferenceType(protoMethod.inputType()) + .build(); + + methodDescriptorMaker = + methodMakerFn + .apply("setRequestMarshaller", protoUtilsMarshallerFn.apply(methodInvocationArg)) + .apply(methodDescriptorMaker); + + methodInvocationArg = + MethodInvocationExpr.builder() + .setMethodName("getDefaultInstance") + .setStaticReferenceType(protoMethod.outputType()) + .build(); + methodDescriptorMaker = + methodMakerFn + .apply("setResponseMarshaller", protoUtilsMarshallerFn.apply(methodInvocationArg)) + .apply(methodDescriptorMaker); + + methodDescriptorMaker = + MethodInvocationExpr.builder() + .setMethodName("build") + .setExprReferenceExpr(methodDescriptorMaker) + .setReturnType(methodDescriptorVarExpr.type()) + .build(); + + return ExprStatement.withExpr( + AssignmentExpr.builder() + .setVariableExpr( + methodDescriptorVarExpr + .toBuilder() + .setIsDecl(true) + .setScope(ScopeNode.PRIVATE) + .setIsStatic(true) + .setIsFinal(true) + .build()) + .setValueExpr(methodDescriptorMaker) + .build()); + } + + @Override + protected List createOperationsStubGetterMethod( + VariableExpr operationsStubVarExpr) { + return Arrays.asList( + MethodDefinition.builder() + .setScope(ScopeNode.PUBLIC) + .setReturnType(operationsStubVarExpr.type()) + .setName("getOperationsStub") + .setReturnExpr(operationsStubVarExpr) + .build()); + } + + @Override + protected Expr createTransportSettingsInitExpr( + Method method, VariableExpr transportSettingsVarExpr, VariableExpr methodDescriptorVarExpr) { + MethodInvocationExpr callSettingsBuilderExpr = + MethodInvocationExpr.builder() + .setStaticReferenceType(getFixedTypeStore().get(getCallSettingsClass().getSimpleName())) + .setGenerics(transportSettingsVarExpr.type().reference().generics()) + .setMethodName("newBuilder") + .build(); + callSettingsBuilderExpr = + MethodInvocationExpr.builder() + .setExprReferenceExpr(callSettingsBuilderExpr) + .setMethodName("setMethodDescriptor") + .setArguments(Arrays.asList(methodDescriptorVarExpr)) + .build(); + + if (method.hasHttpBindings()) { + callSettingsBuilderExpr = + MethodInvocationExpr.builder() + .setExprReferenceExpr(callSettingsBuilderExpr) + .setMethodName("setParamsExtractor") + .setArguments(createRequestParamsExtractorAnonClass(method)) + .build(); + } + + callSettingsBuilderExpr = + MethodInvocationExpr.builder() + .setExprReferenceExpr(callSettingsBuilderExpr) + .setMethodName("build") + .setReturnType(transportSettingsVarExpr.type()) + .build(); + return AssignmentExpr.builder() + .setVariableExpr(transportSettingsVarExpr.toBuilder().setIsDecl(true).build()) + .setValueExpr(callSettingsBuilderExpr) + .build(); + } + + @Override + protected String getProtoRpcFullMethodName(Service protoService, Method protoMethod) { + if (protoMethod.isMixin()) { + return String.format("%s/%s", protoMethod.mixedInApiName(), protoMethod.name()); + } + + if (!REROUTE_TO_GRPC_INTERFACE_SERVICE_ALLOWLIST.contains(protoService.protoPakkage()) + || !REROUTE_TO_GRPC_INTERFACE_IAM_METHOD_ALLOWLIST.contains(protoMethod.name())) { + return String.format( + "%s.%s/%s", protoService.protoPakkage(), protoService.name(), protoMethod.name()); + } + // This is meant to be a temporary workaround until the allow-listed services come up with a + // long-term solution. + return String.format("google.iam.v1.IAMPolicy/%s", protoMethod.name()); + } + + private AnonymousClassExpr createRequestParamsExtractorAnonClass(Method method) { + Preconditions.checkState( + method.hasHttpBindings(), String.format("Method %s has no HTTP binding", method.name())); + + TypeNode paramsVarType = + TypeNode.withReference( + ConcreteReference.builder() + .setClazz(ImmutableMap.Builder.class) + .setGenerics(TypeNode.STRING.reference(), TypeNode.STRING.reference()) + .build()); + VariableExpr paramsVarExpr = + VariableExpr.withVariable( + Variable.builder().setName("params").setType(paramsVarType).build()); + VariableExpr reqeustVarExpr = + VariableExpr.withVariable( + Variable.builder().setName("request").setType(method.inputType()).build()); + + Expr paramsAssignExpr = + AssignmentExpr.builder() + .setVariableExpr(paramsVarExpr.toBuilder().setIsDecl(true).build()) + .setValueExpr( + MethodInvocationExpr.builder() + .setStaticReferenceType(getFixedTypeStore().get("ImmutableMap")) + .setMethodName("builder") + .setReturnType(paramsVarType) + .build()) + .build(); + List bodyExprs = new ArrayList<>(); + bodyExprs.add(paramsAssignExpr); + + VariableExpr requestVarExpr = + VariableExpr.withVariable( + Variable.builder().setType(method.inputType()).setName("request").build()); + + for (String httpBindingFieldName : method.httpBindings().pathParameters()) { + // Handle foo.bar cases by descending into the subfields. + MethodInvocationExpr.Builder requestFieldGetterExprBuilder = + MethodInvocationExpr.builder().setExprReferenceExpr(requestVarExpr); + String[] descendantFields = httpBindingFieldName.split("\\."); + for (int i = 0; i < descendantFields.length; i++) { + String currFieldName = descendantFields[i]; + String bindingFieldMethodName = + String.format("get%s", JavaStyle.toUpperCamelCase(currFieldName)); + requestFieldGetterExprBuilder = + requestFieldGetterExprBuilder.setMethodName(bindingFieldMethodName); + if (i < descendantFields.length - 1) { + requestFieldGetterExprBuilder = + MethodInvocationExpr.builder() + .setExprReferenceExpr(requestFieldGetterExprBuilder.build()); + } + } + + MethodInvocationExpr requestBuilderExpr = requestFieldGetterExprBuilder.build(); + Expr valueOfExpr = + MethodInvocationExpr.builder() + .setStaticReferenceType(TypeNode.STRING) + .setMethodName("valueOf") + .setArguments(requestBuilderExpr) + .build(); + + Expr paramsPutExpr = + MethodInvocationExpr.builder() + .setExprReferenceExpr(paramsVarExpr) + .setMethodName("put") + .setArguments( + ValueExpr.withValue(StringObjectValue.withValue(httpBindingFieldName)), + valueOfExpr) + .build(); + bodyExprs.add(paramsPutExpr); + } + + TypeNode returnType = + TypeNode.withReference( + ConcreteReference.builder() + .setClazz(Map.class) + .setGenerics(TypeNode.STRING.reference(), TypeNode.STRING.reference()) + .build()); + Expr returnExpr = + MethodInvocationExpr.builder() + .setExprReferenceExpr(paramsVarExpr) + .setMethodName("build") + .setReturnType(returnType) + .build(); + + MethodDefinition extractMethod = + MethodDefinition.builder() + .setIsOverride(true) + .setScope(ScopeNode.PUBLIC) + .setReturnType(returnType) + .setName("extract") + .setArguments(requestVarExpr.toBuilder().setIsDecl(true).build()) + .setBody( + bodyExprs.stream().map(e -> ExprStatement.withExpr(e)).collect(Collectors.toList())) + .setReturnExpr(returnExpr) + .build(); + + TypeNode anonClassType = + TypeNode.withReference( + ConcreteReference.builder() + .setClazz(RequestParamsExtractor.class) + .setGenerics(method.inputType().reference()) + .build()); + return AnonymousClassExpr.builder().setType(anonClassType).setMethods(extractMethod).build(); + } +} diff --git a/src/main/java/com/google/api/generator/gapic/composer/MockServiceClassComposer.java b/src/main/java/com/google/api/generator/gapic/composer/grpc/MockServiceClassComposer.java similarity index 98% rename from src/main/java/com/google/api/generator/gapic/composer/MockServiceClassComposer.java rename to src/main/java/com/google/api/generator/gapic/composer/grpc/MockServiceClassComposer.java index c542153cf7..f1ac25fd06 100644 --- a/src/main/java/com/google/api/generator/gapic/composer/MockServiceClassComposer.java +++ b/src/main/java/com/google/api/generator/gapic/composer/grpc/MockServiceClassComposer.java @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -package com.google.api.generator.gapic.composer; +package com.google.api.generator.gapic.composer.grpc; import com.google.api.core.BetaApi; import com.google.api.generator.engine.ast.AnnotationNode; @@ -29,6 +29,7 @@ import com.google.api.generator.engine.ast.TypeNode; import com.google.api.generator.engine.ast.Variable; import com.google.api.generator.engine.ast.VariableExpr; +import com.google.api.generator.gapic.composer.common.ClassComposer; import com.google.api.generator.gapic.composer.store.TypeStore; import com.google.api.generator.gapic.composer.utils.ClassNames; import com.google.api.generator.gapic.model.GapicClass; diff --git a/src/main/java/com/google/api/generator/gapic/composer/MockServiceImplClassComposer.java b/src/main/java/com/google/api/generator/gapic/composer/grpc/MockServiceImplClassComposer.java similarity index 99% rename from src/main/java/com/google/api/generator/gapic/composer/MockServiceImplClassComposer.java rename to src/main/java/com/google/api/generator/gapic/composer/grpc/MockServiceImplClassComposer.java index 20b1f3f71e..a58601197d 100644 --- a/src/main/java/com/google/api/generator/gapic/composer/MockServiceImplClassComposer.java +++ b/src/main/java/com/google/api/generator/gapic/composer/grpc/MockServiceImplClassComposer.java @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -package com.google.api.generator.gapic.composer; +package com.google.api.generator.gapic.composer.grpc; import com.google.api.core.BetaApi; import com.google.api.generator.engine.ast.AnnotationNode; @@ -39,6 +39,7 @@ import com.google.api.generator.engine.ast.VaporReference; import com.google.api.generator.engine.ast.Variable; import com.google.api.generator.engine.ast.VariableExpr; +import com.google.api.generator.gapic.composer.common.ClassComposer; import com.google.api.generator.gapic.composer.store.TypeStore; import com.google.api.generator.gapic.composer.utils.ClassNames; import com.google.api.generator.gapic.model.GapicClass; diff --git a/src/main/java/com/google/api/generator/gapic/composer/grpc/ServiceClientTestClassComposer.java b/src/main/java/com/google/api/generator/gapic/composer/grpc/ServiceClientTestClassComposer.java new file mode 100644 index 0000000000..45301abcfe --- /dev/null +++ b/src/main/java/com/google/api/generator/gapic/composer/grpc/ServiceClientTestClassComposer.java @@ -0,0 +1,582 @@ +// Copyright 2021 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 +// +// http://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. + +package com.google.api.generator.gapic.composer.grpc; + +import com.google.api.gax.grpc.GaxGrpcProperties; +import com.google.api.gax.grpc.testing.LocalChannelProvider; +import com.google.api.gax.grpc.testing.MockGrpcService; +import com.google.api.gax.grpc.testing.MockServiceHelper; +import com.google.api.gax.grpc.testing.MockStreamObserver; +import com.google.api.generator.engine.ast.AnnotationNode; +import com.google.api.generator.engine.ast.AssignmentExpr; +import com.google.api.generator.engine.ast.CastExpr; +import com.google.api.generator.engine.ast.ConcreteReference; +import com.google.api.generator.engine.ast.EnumRefExpr; +import com.google.api.generator.engine.ast.Expr; +import com.google.api.generator.engine.ast.ExprStatement; +import com.google.api.generator.engine.ast.MethodDefinition; +import com.google.api.generator.engine.ast.MethodInvocationExpr; +import com.google.api.generator.engine.ast.NewObjectExpr; +import com.google.api.generator.engine.ast.PrimitiveValue; +import com.google.api.generator.engine.ast.ScopeNode; +import com.google.api.generator.engine.ast.Statement; +import com.google.api.generator.engine.ast.TypeNode; +import com.google.api.generator.engine.ast.ValueExpr; +import com.google.api.generator.engine.ast.Variable; +import com.google.api.generator.engine.ast.VariableExpr; +import com.google.api.generator.gapic.composer.common.AbstractServiceClientTestClassComposer; +import com.google.api.generator.gapic.composer.store.TypeStore; +import com.google.api.generator.gapic.composer.utils.ClassNames; +import com.google.api.generator.gapic.model.Field; +import com.google.api.generator.gapic.model.GapicContext; +import com.google.api.generator.gapic.model.Message; +import com.google.api.generator.gapic.model.Method; +import com.google.api.generator.gapic.model.MethodArgument; +import com.google.api.generator.gapic.model.ResourceName; +import com.google.api.generator.gapic.model.Service; +import com.google.api.generator.gapic.utils.JavaStyle; +import com.google.common.base.Preconditions; +import com.google.protobuf.AbstractMessage; +import io.grpc.StatusRuntimeException; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; +import java.util.function.BiFunction; +import java.util.function.Function; +import java.util.stream.Collectors; + +public class ServiceClientTestClassComposer extends AbstractServiceClientTestClassComposer { + private static final String SERVICE_HELPER_VAR_NAME = "mockServiceHelper"; + private static final String CHANNEL_PROVIDER_VAR_NAME = "channelProvider"; + + private static final TypeNode LIST_TYPE = + TypeNode.withReference(ConcreteReference.withClazz(List.class)); + private static final TypeNode MAP_TYPE = + TypeNode.withReference(ConcreteReference.withClazz(Map.class)); + private static final TypeNode RESOURCE_NAME_TYPE = + TypeNode.withReference( + ConcreteReference.withClazz(com.google.api.resourcenames.ResourceName.class)); + + // Avoid conflicting types with com.google.rpc.Status. + private static final TypeNode GRPC_STATUS_TYPE = + TypeNode.withReference( + ConcreteReference.builder().setClazz(io.grpc.Status.class).setUseFullName(true).build()); + + protected ServiceClientTestClassComposer() { + super(createTypes(), new ClassNames("Grpc")); + } + + private static final ServiceClientTestClassComposer INSTANCE = + new ServiceClientTestClassComposer(); + + public static AbstractServiceClientTestClassComposer instance() { + return INSTANCE; + } + + protected static TypeStore createTypes() { + TypeStore typeStore = createCommonTypes(); + typeStore.putAll( + Arrays.asList( + GaxGrpcProperties.class, + LocalChannelProvider.class, + MockGrpcService.class, + MockServiceHelper.class, + MockStreamObserver.class, + StatusRuntimeException.class)); + + return typeStore; + } + + @Override + protected Map createClassMemberVarExprs( + Service service, GapicContext context, TypeStore typeStore) { + BiFunction varExprFn = + (name, type) -> + VariableExpr.withVariable(Variable.builder().setName(name).setType(type).build()); + Map fields = new LinkedHashMap<>(); + fields.put( + getMockServiceVarName(service), typeStore.get(ClassNames.getMockServiceClassName(service))); + for (Service mixinService : context.mixinServices()) { + fields.put( + getMockServiceVarName(mixinService), + typeStore.get(ClassNames.getMockServiceClassName(mixinService))); + } + fields.put(SERVICE_HELPER_VAR_NAME, getFixedTypeStore().get("MockServiceHelper")); + fields.put(CLIENT_VAR_NAME, typeStore.get(ClassNames.getServiceClientClassName(service))); + fields.put(CHANNEL_PROVIDER_VAR_NAME, getFixedTypeStore().get("LocalChannelProvider")); + return fields.entrySet().stream() + .collect(Collectors.toMap(e -> e.getKey(), e -> varExprFn.apply(e.getKey(), e.getValue()))); + } + + @Override + protected MethodDefinition createStartStaticServerMethod( + Service service, + GapicContext context, + Map classMemberVarExprs, + TypeStore typeStore) { + VariableExpr serviceHelperVarExpr = classMemberVarExprs.get(SERVICE_HELPER_VAR_NAME); + Function serviceToVarExprFn = + s -> classMemberVarExprs.get(getMockServiceVarName(s)); + Function serviceToVarInitExprFn = + s -> { + VariableExpr mockServiceVarExpr = serviceToVarExprFn.apply(s); + return AssignmentExpr.builder() + .setVariableExpr(mockServiceVarExpr) + .setValueExpr(NewObjectExpr.builder().setType(mockServiceVarExpr.type()).build()) + .build(); + }; + List varInitExprs = new ArrayList<>(); + List mockServiceVarExprs = new ArrayList<>(); + varInitExprs.add(serviceToVarInitExprFn.apply(service)); + mockServiceVarExprs.add(serviceToVarExprFn.apply(service)); + for (Service mixinService : context.mixinServices()) { + varInitExprs.add(serviceToVarInitExprFn.apply(mixinService)); + mockServiceVarExprs.add(serviceToVarExprFn.apply(mixinService)); + } + + MethodInvocationExpr firstArg = + MethodInvocationExpr.builder() + .setStaticReferenceType(getFixedTypeStore().get("UUID")) + .setMethodName("randomUUID") + .build(); + firstArg = + MethodInvocationExpr.builder() + .setExprReferenceExpr(firstArg) + .setMethodName("toString") + .build(); + + MethodInvocationExpr secondArg = + MethodInvocationExpr.builder() + .setStaticReferenceType(getFixedTypeStore().get("Arrays")) + .setGenerics(Arrays.asList(getFixedTypeStore().get("MockGrpcService").reference())) + .setMethodName("asList") + .setArguments(mockServiceVarExprs) + .build(); + + Expr initServiceHelperExpr = + AssignmentExpr.builder() + .setVariableExpr(serviceHelperVarExpr) + .setValueExpr( + NewObjectExpr.builder() + .setType(serviceHelperVarExpr.type()) + .setArguments(Arrays.asList(firstArg, secondArg)) + .build()) + .build(); + + Expr startServiceHelperExpr = + MethodInvocationExpr.builder() + .setExprReferenceExpr(serviceHelperVarExpr) + .setMethodName("start") + .build(); + varInitExprs.add(initServiceHelperExpr); + varInitExprs.add(startServiceHelperExpr); + + return MethodDefinition.builder() + .setAnnotations( + Arrays.asList(AnnotationNode.withType(getFixedTypeStore().get("BeforeClass")))) + .setScope(ScopeNode.PUBLIC) + .setIsStatic(true) + .setReturnType(TypeNode.VOID) + .setName("startStaticServer") + .setBody( + varInitExprs.stream().map(e -> ExprStatement.withExpr(e)).collect(Collectors.toList())) + .build(); + } + + @Override + protected MethodDefinition createStopServerMethod( + Service service, Map classMemberVarExprs) { + return MethodDefinition.builder() + .setAnnotations( + Arrays.asList(AnnotationNode.withType(getFixedTypeStore().get("AfterClass")))) + .setScope(ScopeNode.PUBLIC) + .setIsStatic(true) + .setReturnType(TypeNode.VOID) + .setName("stopServer") + .setBody( + Arrays.asList( + ExprStatement.withExpr( + MethodInvocationExpr.builder() + .setExprReferenceExpr(classMemberVarExprs.get(SERVICE_HELPER_VAR_NAME)) + .setMethodName("stop") + .build()))) + .build(); + } + + @Override + protected MethodDefinition createSetUpMethod( + Service service, Map classMemberVarExprs, TypeStore typeStore) { + VariableExpr clientVarExpr = classMemberVarExprs.get(CLIENT_VAR_NAME); + VariableExpr serviceHelperVarExpr = classMemberVarExprs.get(SERVICE_HELPER_VAR_NAME); + VariableExpr channelProviderVarExpr = classMemberVarExprs.get(CHANNEL_PROVIDER_VAR_NAME); + + Expr resetServiceHelperExpr = + MethodInvocationExpr.builder() + .setExprReferenceExpr(serviceHelperVarExpr) + .setMethodName("reset") + .build(); + Expr channelProviderInitExpr = + AssignmentExpr.builder() + .setVariableExpr(channelProviderVarExpr) + .setValueExpr( + MethodInvocationExpr.builder() + .setExprReferenceExpr(serviceHelperVarExpr) + .setMethodName("createChannelProvider") + .setReturnType(channelProviderVarExpr.type()) + .build()) + .build(); + + TypeNode settingsType = typeStore.get(ClassNames.getServiceSettingsClassName(service)); + VariableExpr localSettingsVarExpr = + VariableExpr.withVariable( + Variable.builder().setName("settings").setType(settingsType).build()); + + Expr settingsBuilderExpr = + MethodInvocationExpr.builder() + .setStaticReferenceType(settingsType) + .setMethodName("newBuilder") + .build(); + Function> methodBuilderFn = + methodExpr -> + (mName, argExpr) -> + MethodInvocationExpr.builder() + .setExprReferenceExpr(methodExpr) + .setMethodName(mName) + .setArguments(Arrays.asList(argExpr)) + .build(); + settingsBuilderExpr = + methodBuilderFn + .apply(settingsBuilderExpr) + .apply( + "setTransportChannelProvider", classMemberVarExprs.get(CHANNEL_PROVIDER_VAR_NAME)); + settingsBuilderExpr = + methodBuilderFn + .apply(settingsBuilderExpr) + .apply( + "setCredentialsProvider", + MethodInvocationExpr.builder() + .setStaticReferenceType(getFixedTypeStore().get("NoCredentialsProvider")) + .setMethodName("create") + .build()); + settingsBuilderExpr = + MethodInvocationExpr.builder() + .setExprReferenceExpr(settingsBuilderExpr) + .setMethodName("build") + .setReturnType(localSettingsVarExpr.type()) + .build(); + + Expr initLocalSettingsExpr = + AssignmentExpr.builder() + .setVariableExpr(localSettingsVarExpr.toBuilder().setIsDecl(true).build()) + .setValueExpr(settingsBuilderExpr) + .build(); + + Expr initClientExpr = + AssignmentExpr.builder() + .setVariableExpr(clientVarExpr) + .setValueExpr( + MethodInvocationExpr.builder() + .setStaticReferenceType( + typeStore.get(ClassNames.getServiceClientClassName(service))) + .setMethodName("create") + .setArguments(Arrays.asList(localSettingsVarExpr)) + .setReturnType(clientVarExpr.type()) + .build()) + .build(); + + return MethodDefinition.builder() + .setAnnotations(Arrays.asList(AnnotationNode.withType(getFixedTypeStore().get("Before")))) + .setScope(ScopeNode.PUBLIC) + .setReturnType(TypeNode.VOID) + .setName("setUp") + .setThrowsExceptions(Arrays.asList(getFixedTypeStore().get("IOException"))) + .setBody( + Arrays.asList( + resetServiceHelperExpr, + channelProviderInitExpr, + initLocalSettingsExpr, + initClientExpr) + .stream() + .map(e -> ExprStatement.withExpr(e)) + .collect(Collectors.toList())) + .build(); + } + + @Override + protected MethodDefinition createTearDownMethod( + Service service, Map classMemberVarExprs) { + return MethodDefinition.builder() + .setAnnotations(Arrays.asList(AnnotationNode.withType(getFixedTypeStore().get("After")))) + .setScope(ScopeNode.PUBLIC) + .setReturnType(TypeNode.VOID) + .setName("tearDown") + .setThrowsExceptions( + Arrays.asList(TypeNode.withReference(ConcreteReference.withClazz(Exception.class)))) + .setBody( + Arrays.asList( + ExprStatement.withExpr( + MethodInvocationExpr.builder() + .setExprReferenceExpr(classMemberVarExprs.get(CLIENT_VAR_NAME)) + .setMethodName("close") + .build()))) + .build(); + } + + @Override + protected List constructRpcTestCheckerLogic( + Method method, + Service service, + boolean isRequestArg, + Map classMemberVarExprs, + VariableExpr requestVarExpr, + Message requestMessage, + List argExprs) { + List methodExprs = new ArrayList<>(); + List methodStatements = new ArrayList<>(); + + // Construct the request checker logic. + VariableExpr actualRequestsVarExpr = + VariableExpr.withVariable( + Variable.builder() + .setType( + TypeNode.withReference( + ConcreteReference.builder() + .setClazz(List.class) + .setGenerics( + Arrays.asList(ConcreteReference.withClazz(AbstractMessage.class))) + .build())) + .setName("actualRequests") + .build()); + methodExprs.add( + AssignmentExpr.builder() + .setVariableExpr(actualRequestsVarExpr.toBuilder().setIsDecl(true).build()) + .setValueExpr( + MethodInvocationExpr.builder() + .setExprReferenceExpr(classMemberVarExprs.get(getMockServiceVarName(service))) + .setMethodName("getRequests") + .setReturnType(actualRequestsVarExpr.type()) + .build()) + .build()); + + methodExprs.add( + MethodInvocationExpr.builder() + .setStaticReferenceType(getFixedTypeStore().get("Assert")) + .setMethodName("assertEquals") + .setArguments( + ValueExpr.withValue( + PrimitiveValue.builder().setType(TypeNode.INT).setValue("1").build()), + MethodInvocationExpr.builder() + .setExprReferenceExpr(actualRequestsVarExpr) + .setMethodName("size") + .build()) + .build()); + + VariableExpr actualRequestVarExpr = + VariableExpr.withVariable( + Variable.builder().setType(method.inputType()).setName("actualRequest").build()); + Expr getFirstRequestExpr = + MethodInvocationExpr.builder() + .setExprReferenceExpr(actualRequestsVarExpr) + .setMethodName("get") + .setArguments( + ValueExpr.withValue( + PrimitiveValue.builder().setType(TypeNode.INT).setValue("0").build())) + .setReturnType(getFixedTypeStore().get("AbstractMessage")) + .build(); + getFirstRequestExpr = + CastExpr.builder().setType(method.inputType()).setExpr(getFirstRequestExpr).build(); + methodExprs.add( + AssignmentExpr.builder() + .setVariableExpr(actualRequestVarExpr.toBuilder().setIsDecl(true).build()) + .setValueExpr(getFirstRequestExpr) + .build()); + methodStatements.addAll( + methodExprs.stream().map(e -> ExprStatement.withExpr(e)).collect(Collectors.toList())); + methodExprs.clear(); + methodStatements.add(EMPTY_LINE_STATEMENT); + + // Assert field equality. + if (isRequestArg) { + // TODO(miraleung): Replace these with a simple request object equals? + Preconditions.checkNotNull(requestVarExpr); + Preconditions.checkNotNull(requestMessage); + for (Field field : requestMessage.fields()) { + String fieldGetterMethodNamePatternTemp = "get%s"; + if (field.isRepeated()) { + fieldGetterMethodNamePatternTemp = field.isMap() ? "get%sMap" : "get%sList"; + } + final String fieldGetterMethodNamePattern = fieldGetterMethodNamePatternTemp; + Function checkExprFn = + v -> + MethodInvocationExpr.builder() + .setExprReferenceExpr(v) + .setMethodName( + String.format( + fieldGetterMethodNamePattern, JavaStyle.toUpperCamelCase(field.name()))) + .build(); + Expr expectedFieldExpr = checkExprFn.apply(requestVarExpr); + Expr actualFieldExpr = checkExprFn.apply(actualRequestVarExpr); + List assertEqualsArguments = new ArrayList<>(); + assertEqualsArguments.add(expectedFieldExpr); + assertEqualsArguments.add(actualFieldExpr); + if (TypeNode.isFloatingPointType(field.type())) { + boolean isFloat = field.type().equals(TypeNode.FLOAT); + assertEqualsArguments.add( + ValueExpr.withValue( + PrimitiveValue.builder() + .setType(isFloat ? TypeNode.FLOAT : TypeNode.DOUBLE) + .setValue(String.format("0.0001%s", isFloat ? "f" : "")) + .build())); + } + methodExprs.add( + MethodInvocationExpr.builder() + .setStaticReferenceType(getFixedTypeStore().get("Assert")) + .setMethodName("assertEquals") + .setArguments(assertEqualsArguments) + .build()); + } + } else { + for (VariableExpr argVarExpr : argExprs) { + Variable variable = argVarExpr.variable(); + String fieldGetterMethodNamePattern = "get%s"; + if (LIST_TYPE.isSupertypeOrEquals(variable.type())) { + fieldGetterMethodNamePattern = "get%sList"; + } else if (MAP_TYPE.isSupertypeOrEquals(variable.type())) { + fieldGetterMethodNamePattern = "get%sMap"; + } + Expr actualFieldExpr = + MethodInvocationExpr.builder() + .setExprReferenceExpr(actualRequestVarExpr) + .setMethodName( + String.format( + fieldGetterMethodNamePattern, + JavaStyle.toUpperCamelCase(variable.identifier().name()))) + .build(); + Expr expectedFieldExpr = argVarExpr; + if (RESOURCE_NAME_TYPE.isSupertypeOrEquals(argVarExpr.type())) { + expectedFieldExpr = + MethodInvocationExpr.builder() + .setExprReferenceExpr(argVarExpr) + .setMethodName("toString") + .build(); + } + methodExprs.add( + MethodInvocationExpr.builder() + .setStaticReferenceType(getFixedTypeStore().get("Assert")) + .setMethodName("assertEquals") + .setArguments(expectedFieldExpr, actualFieldExpr) + .build()); + } + } + + // Assert header equality. + Expr headerKeyExpr = + MethodInvocationExpr.builder() + .setStaticReferenceType(getFixedTypeStore().get("ApiClientHeaderProvider")) + .setMethodName("getDefaultApiClientHeaderKey") + .build(); + Expr headerPatternExpr = + MethodInvocationExpr.builder() + .setStaticReferenceType(getFixedTypeStore().get("GaxGrpcProperties")) + .setMethodName("getDefaultApiClientHeaderPattern") + .build(); + Expr headerSentExpr = + MethodInvocationExpr.builder() + .setExprReferenceExpr(classMemberVarExprs.get("channelProvider")) + .setMethodName("isHeaderSent") + .setArguments(headerKeyExpr, headerPatternExpr) + .build(); + methodExprs.add( + MethodInvocationExpr.builder() + .setStaticReferenceType(getFixedTypeStore().get("Assert")) + .setMethodName("assertTrue") + .setArguments(headerSentExpr) + .build()); + methodStatements.addAll( + methodExprs.stream().map(e -> ExprStatement.withExpr(e)).collect(Collectors.toList())); + methodExprs.clear(); + + return methodStatements; + } + + @Override + protected MethodDefinition createRpcExceptionTestMethod( + Method method, + Service service, + List methodSignature, + int variantIndex, + Map classMemberVarExprs, + Map resourceNames, + Map messageTypes) { + VariableExpr exceptionVarExpr = + VariableExpr.withVariable( + Variable.builder() + .setType(getFixedTypeStore().get("StatusRuntimeException")) + .setName("exception") + .build()); + + // First two assignment lines. + Expr exceptionAssignExpr = + AssignmentExpr.builder() + .setVariableExpr(exceptionVarExpr.toBuilder().setIsDecl(true).build()) + .setValueExpr( + NewObjectExpr.builder() + .setType(getFixedTypeStore().get("StatusRuntimeException")) + .setArguments( + EnumRefExpr.builder() + .setType(GRPC_STATUS_TYPE) + .setName("INVALID_ARGUMENT") + .build()) + .build()) + .build(); + Expr addExceptionExpr = + MethodInvocationExpr.builder() + .setExprReferenceExpr(classMemberVarExprs.get(getMockServiceVarName(service))) + .setMethodName("addException") + .setArguments(exceptionVarExpr) + .build(); + + // Try-catch block. Build the method call. + String exceptionTestMethodName = + String.format( + "%sExceptionTest%s", + JavaStyle.toLowerCamelCase(method.name()), variantIndex > 0 ? variantIndex + 1 : ""); + + boolean isStreaming = !method.stream().equals(Method.Stream.NONE); + List methodBody = new ArrayList<>(); + methodBody.add(ExprStatement.withExpr(exceptionAssignExpr)); + methodBody.add(ExprStatement.withExpr(addExceptionExpr)); + if (isStreaming) { + methodBody.addAll( + createStreamingRpcExceptionTestStatements( + method, classMemberVarExprs, resourceNames, messageTypes)); + } else { + methodBody.addAll( + createRpcExceptionTestStatements( + method, methodSignature, classMemberVarExprs, resourceNames, messageTypes)); + } + + return MethodDefinition.builder() + .setAnnotations(Arrays.asList(getTestAnnotation())) + .setScope(ScopeNode.PUBLIC) + .setReturnType(TypeNode.VOID) + .setName(exceptionTestMethodName) + .setThrowsExceptions(Arrays.asList(TypeNode.withExceptionClazz(Exception.class))) + .setBody(methodBody) + .build(); + } +} diff --git a/src/main/java/com/google/api/generator/gapic/composer/grpc/ServiceSettingsClassComposer.java b/src/main/java/com/google/api/generator/gapic/composer/grpc/ServiceSettingsClassComposer.java new file mode 100644 index 0000000000..8b424fe87f --- /dev/null +++ b/src/main/java/com/google/api/generator/gapic/composer/grpc/ServiceSettingsClassComposer.java @@ -0,0 +1,42 @@ +// Copyright 2021 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 +// +// http://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. + +package com.google.api.generator.gapic.composer.grpc; + +import com.google.api.gax.grpc.InstantiatingGrpcChannelProvider; +import com.google.api.generator.gapic.composer.common.AbstractServiceSettingsClassComposer; +import com.google.api.generator.gapic.composer.store.TypeStore; +import java.util.Arrays; + +public class ServiceSettingsClassComposer extends AbstractServiceSettingsClassComposer { + private static final ServiceSettingsClassComposer INSTANCE = + new ServiceSettingsClassComposer(); + + protected ServiceSettingsClassComposer() { + super( + createTypes(), + InstantiatingGrpcChannelProvider.Builder.class, + "defaultGrpcTransportProviderBuilder"); + } + + public static ServiceSettingsClassComposer instance() { + return INSTANCE; + } + + private static TypeStore createTypes() { + TypeStore typeStore = createCommonTypes(); + typeStore.putAll(Arrays.asList(InstantiatingGrpcChannelProvider.class)); + return typeStore; + } +} diff --git a/src/main/java/com/google/api/generator/gapic/composer/grpc/ServiceStubSettingsClassComposer.java b/src/main/java/com/google/api/generator/gapic/composer/grpc/ServiceStubSettingsClassComposer.java new file mode 100644 index 0000000000..92801ea752 --- /dev/null +++ b/src/main/java/com/google/api/generator/gapic/composer/grpc/ServiceStubSettingsClassComposer.java @@ -0,0 +1,184 @@ +// Copyright 2021 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 +// +// http://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. + +package com.google.api.generator.gapic.composer.grpc; + +import com.google.api.gax.grpc.GaxGrpcProperties; +import com.google.api.gax.grpc.GrpcTransportChannel; +import com.google.api.gax.grpc.InstantiatingGrpcChannelProvider; +import com.google.api.gax.rpc.ApiClientHeaderProvider; +import com.google.api.generator.engine.ast.AnnotationNode; +import com.google.api.generator.engine.ast.ConcreteReference; +import com.google.api.generator.engine.ast.MethodDefinition; +import com.google.api.generator.engine.ast.MethodInvocationExpr; +import com.google.api.generator.engine.ast.ScopeNode; +import com.google.api.generator.engine.ast.StringObjectValue; +import com.google.api.generator.engine.ast.TypeNode; +import com.google.api.generator.engine.ast.ValueExpr; +import com.google.api.generator.engine.ast.Variable; +import com.google.api.generator.engine.ast.VariableExpr; +import com.google.api.generator.gapic.composer.common.AbstractServiceStubSettingsClassComposer; +import com.google.api.generator.gapic.composer.comment.SettingsCommentComposer; +import com.google.api.generator.gapic.composer.store.TypeStore; +import com.google.api.generator.gapic.composer.utils.ClassNames; +import com.google.api.generator.gapic.model.Service; +import java.util.Arrays; + +public class ServiceStubSettingsClassComposer extends AbstractServiceStubSettingsClassComposer { + private static final ServiceStubSettingsClassComposer INSTANCE = + new ServiceStubSettingsClassComposer(); + + public static ServiceStubSettingsClassComposer instance() { + return INSTANCE; + } + + protected ServiceStubSettingsClassComposer() { + super( + createStaticTypes(), + new ClassNames("Grpc"), + GrpcTransportChannel.class, + "getGrpcTransportName"); + } + + private static TypeStore createStaticTypes() { + TypeStore typeStore = createCommonStaticTypes(); + typeStore.putAll( + Arrays.asList( + GaxGrpcProperties.class, + GrpcTransportChannel.class, + InstantiatingGrpcChannelProvider.class)); + return typeStore; + } + + @Override + protected MethodDefinition createDefaultTransportTransportProviderBuilderMethod() { + // Create the defaultGrpcTransportProviderBuilder method. + TypeNode returnType = + TypeNode.withReference( + ConcreteReference.withClazz(InstantiatingGrpcChannelProvider.Builder.class)); + MethodInvocationExpr transportChannelProviderBuilderExpr = + MethodInvocationExpr.builder() + .setStaticReferenceType( + getFixedTypeStore().get(InstantiatingGrpcChannelProvider.class.getSimpleName())) + .setMethodName("newBuilder") + .build(); + transportChannelProviderBuilderExpr = + MethodInvocationExpr.builder() + .setExprReferenceExpr(transportChannelProviderBuilderExpr) + .setMethodName("setMaxInboundMessageSize") + .setArguments( + VariableExpr.builder() + .setVariable( + Variable.builder().setType(TypeNode.INT).setName("MAX_VALUE").build()) + .setStaticReferenceType(TypeNode.INT_OBJECT) + .build()) + .setReturnType(returnType) + .build(); + return MethodDefinition.builder() + .setHeaderCommentStatements( + SettingsCommentComposer.DEFAULT_TRANSPORT_PROVIDER_BUILDER_METHOD_COMMENT) + .setScope(ScopeNode.PUBLIC) + .setIsStatic(true) + .setReturnType(returnType) + .setName("defaultGrpcTransportProviderBuilder") + .setReturnExpr(transportChannelProviderBuilderExpr) + .build(); + } + + @Override + protected MethodDefinition createDefaultApiClientHeaderProviderBuilderMethod( + Service service, TypeStore typeStore) { + // Create the defaultApiClientHeaderProviderBuilder method. + TypeNode returnType = + TypeNode.withReference(ConcreteReference.withClazz(ApiClientHeaderProvider.Builder.class)); + MethodInvocationExpr returnExpr = + MethodInvocationExpr.builder() + .setStaticReferenceType(getFixedTypeStore().get("ApiClientHeaderProvider")) + .setMethodName("newBuilder") + .build(); + + MethodInvocationExpr versionArgExpr = + MethodInvocationExpr.builder() + .setStaticReferenceType(getFixedTypeStore().get("GaxProperties")) + .setMethodName("getLibraryVersion") + .setArguments( + VariableExpr.builder() + .setVariable( + Variable.builder().setType(TypeNode.CLASS_OBJECT).setName("class").build()) + .setStaticReferenceType( + typeStore.get(ClassNames.getServiceStubSettingsClassName(service))) + .build()) + .build(); + + returnExpr = + MethodInvocationExpr.builder() + .setExprReferenceExpr(returnExpr) + .setMethodName("setGeneratedLibToken") + .setArguments(ValueExpr.withValue(StringObjectValue.withValue("gapic")), versionArgExpr) + .build(); + returnExpr = + MethodInvocationExpr.builder() + .setExprReferenceExpr(returnExpr) + .setMethodName("setTransportToken") + .setArguments( + MethodInvocationExpr.builder() + .setStaticReferenceType( + getFixedTypeStore().get(GaxGrpcProperties.class.getSimpleName())) + .setMethodName("getGrpcTokenName") + .build(), + MethodInvocationExpr.builder() + .setStaticReferenceType( + getFixedTypeStore().get(GaxGrpcProperties.class.getSimpleName())) + .setMethodName("getGrpcVersion") + .build()) + .setReturnType(returnType) + .build(); + + AnnotationNode annotation = + AnnotationNode.builder() + .setType(getFixedTypeStore().get("BetaApi")) + .setDescription( + "The surface for customizing headers is not stable yet and may change in the" + + " future.") + .build(); + return MethodDefinition.builder() + .setAnnotations(Arrays.asList(annotation)) + .setScope(ScopeNode.PUBLIC) + .setIsStatic(true) + .setReturnType(returnType) + .setName("defaultApiClientHeaderProviderBuilder") + .setReturnExpr(returnExpr) + .build(); + } + + @Override + public MethodDefinition createDefaultTransportChannelProviderMethod() { + TypeNode returnType = getFixedTypeStore().get("TransportChannelProvider"); + MethodInvocationExpr transportProviderBuilderExpr = + MethodInvocationExpr.builder().setMethodName("defaultGrpcTransportProviderBuilder").build(); + transportProviderBuilderExpr = + MethodInvocationExpr.builder() + .setExprReferenceExpr(transportProviderBuilderExpr) + .setMethodName("build") + .setReturnType(returnType) + .build(); + return MethodDefinition.builder() + .setScope(ScopeNode.PUBLIC) + .setIsStatic(true) + .setReturnType(returnType) + .setName("defaultTransportChannelProvider") + .setReturnExpr(transportProviderBuilderExpr) + .build(); + } +} diff --git a/src/main/java/com/google/api/generator/gapic/composer/httpjson/BUILD.bazel b/src/main/java/com/google/api/generator/gapic/composer/httpjson/BUILD.bazel new file mode 100644 index 0000000000..44ed244337 --- /dev/null +++ b/src/main/java/com/google/api/generator/gapic/composer/httpjson/BUILD.bazel @@ -0,0 +1,52 @@ +load("@rules_java//java:defs.bzl", "java_library") + +package(default_visibility = ["//visibility:public"]) + +filegroup( + name = "httpjson_files", + srcs = glob(["*.java"]), +) + +java_library( + name = "httpjson", + srcs = [ + ":httpjson_files", + ], + deps = [ + "//:service_config_java_proto", + "//src/main/java/com/google/api/generator/engine/ast", + "//src/main/java/com/google/api/generator/engine/writer", + "//src/main/java/com/google/api/generator/gapic:status_java_proto", + "//src/main/java/com/google/api/generator/gapic/composer/common", + "//src/main/java/com/google/api/generator/gapic/composer/comment", + "//src/main/java/com/google/api/generator/gapic/composer/defaultvalue", + "//src/main/java/com/google/api/generator/gapic/composer/resourcename", + "//src/main/java/com/google/api/generator/gapic/composer/samplecode", + "//src/main/java/com/google/api/generator/gapic/composer/store", + "//src/main/java/com/google/api/generator/gapic/composer/utils", + "//src/main/java/com/google/api/generator/gapic/model", + "//src/main/java/com/google/api/generator/gapic/utils", + "//src/main/java/com/google/api/generator/util", + "@com_google_api_api_common//jar", + "@com_google_api_gax_java//gax:gax", + "@com_google_api_gax_java//gax:gax_testlib", + "@com_google_api_gax_java//gax-httpjson:gax_httpjson", + "@com_google_api_gax_java//gax-httpjson:gax_httpjson_testlib", + "@com_google_code_findbugs_jsr305//jar", + "@com_google_googleapis//gapic/metadata:metadata_java_proto", + "@com_google_googleapis//google/api:api_java_proto", + "@com_google_googleapis//google/longrunning:longrunning_java_proto", + "@com_google_googleapis//google/rpc:rpc_java_proto", + "@com_google_guava_guava//jar", + "@com_google_http_client_google_http_client//jar", + "@com_google_protobuf//:protobuf_java", + "@com_google_protobuf//:protobuf_java_util", + "@com_google_protobuf//java/core", + "@io_grpc_grpc_java//api", + "@io_grpc_grpc_java//protobuf", + "@io_grpc_grpc_java//stub", + "@javax_annotation_javax_annotation_api//jar", + "@junit_junit//jar", + "@org_threeten_threetenbp//jar", + ], +) diff --git a/src/main/java/com/google/api/generator/gapic/composer/httpjson/HttpJsonServiceCallableFactoryClassComposer.java b/src/main/java/com/google/api/generator/gapic/composer/httpjson/HttpJsonServiceCallableFactoryClassComposer.java new file mode 100644 index 0000000000..e5ac6a85f9 --- /dev/null +++ b/src/main/java/com/google/api/generator/gapic/composer/httpjson/HttpJsonServiceCallableFactoryClassComposer.java @@ -0,0 +1,100 @@ +// Copyright 2021 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 +// +// http://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. + +package com.google.api.generator.gapic.composer.httpjson; + +import com.google.api.gax.core.BackgroundResource; +import com.google.api.gax.httpjson.ApiMessage; +import com.google.api.gax.httpjson.HttpJsonCallSettings; +import com.google.api.gax.httpjson.HttpJsonCallableFactory; +import com.google.api.gax.httpjson.HttpJsonStubCallableFactory; +import com.google.api.generator.engine.ast.MethodDefinition; +import com.google.api.generator.engine.ast.TypeNode; +import com.google.api.generator.engine.ast.ValueExpr; +import com.google.api.generator.gapic.composer.common.AbstractServiceCallableFactoryClassComposer; +import com.google.api.generator.gapic.composer.comment.StubCommentComposer; +import com.google.api.generator.gapic.composer.store.TypeStore; +import com.google.api.generator.gapic.composer.utils.ClassNames; +import java.util.Arrays; +import java.util.List; +import java.util.stream.Collectors; + +public class HttpJsonServiceCallableFactoryClassComposer + extends AbstractServiceCallableFactoryClassComposer { + private static final HttpJsonServiceCallableFactoryClassComposer INSTANCE = + new HttpJsonServiceCallableFactoryClassComposer(); + + private HttpJsonServiceCallableFactoryClassComposer() { + super( + createTypes(), + new StubCommentComposer("REST"), + new ClassNames("HttpJson"), + HttpJsonCallSettings.class, + HttpJsonCallableFactory.class, + BackgroundResource.class, + "httpJsonCallSettings"); + } + + public static HttpJsonServiceCallableFactoryClassComposer instance() { + return INSTANCE; + } + + private static TypeStore createTypes() { + TypeStore typeStore = createCommonTypes(); + typeStore.putAll( + Arrays.asList( + ApiMessage.class, + BackgroundResource.class, + HttpJsonCallSettings.class, + HttpJsonCallableFactory.class, + HttpJsonStubCallableFactory.class)); + return typeStore; + } + + @Override + protected List createClassImplements(TypeStore typeStore) { + return Arrays.asList( + TypeNode.withReference( + typeStore + .get("HttpJsonStubCallableFactory") + .reference() + .copyAndSetGenerics( + Arrays.asList( + typeStore.get("ApiMessage").reference(), + typeStore.get("BackgroundResource").reference())))); + } + + @Override + protected MethodDefinition createOperationCallableMethod(TypeStore typeStore) { + String methodVariantName = "Operation"; + String requestTemplateName = "RequestT"; + String responseTemplateName = "ResponseT"; + List methodTemplateNames = + Arrays.asList(requestTemplateName, responseTemplateName, "MetadataT"); + MethodDefinition method = + createGenericCallableMethod( + typeStore, + /*methodTemplateNames=*/ methodTemplateNames, + /*returnCallableKindName=*/ methodVariantName, + /*returnCallableTemplateNames=*/ methodTemplateNames, + /*methodVariantName=*/ methodVariantName, + /*httpJsonCallSettingsTemplateObjects=*/ Arrays.asList( + requestTemplateName, typeStore.get("ApiMessage")), + /*callSettingsVariantName=*/ methodVariantName, + /*callSettingsTemplateObjects=*/ methodTemplateNames.stream() + .map(n -> (Object) n) + .collect(Collectors.toList())); + return method.toBuilder().setReturnExpr(ValueExpr.createNullExpr()).build(); + } +} diff --git a/src/main/java/com/google/api/generator/gapic/composer/httpjson/HttpJsonServiceStubClassComposer.java b/src/main/java/com/google/api/generator/gapic/composer/httpjson/HttpJsonServiceStubClassComposer.java new file mode 100644 index 0000000000..72a2a14a55 --- /dev/null +++ b/src/main/java/com/google/api/generator/gapic/composer/httpjson/HttpJsonServiceStubClassComposer.java @@ -0,0 +1,513 @@ +// Copyright 2021 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 +// +// http://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. + +package com.google.api.generator.gapic.composer.httpjson; + +import com.google.api.client.http.HttpMethods; +import com.google.api.core.InternalApi; +import com.google.api.gax.httpjson.ApiMethodDescriptor; +import com.google.api.gax.httpjson.FieldsExtractor; +import com.google.api.gax.httpjson.HttpJsonCallSettings; +import com.google.api.gax.httpjson.HttpJsonStubCallableFactory; +import com.google.api.gax.httpjson.ProtoMessageRequestFormatter; +import com.google.api.gax.httpjson.ProtoMessageResponseParser; +import com.google.api.gax.httpjson.ProtoRestSerializer; +import com.google.api.generator.engine.ast.AnnotationNode; +import com.google.api.generator.engine.ast.AnonymousClassExpr; +import com.google.api.generator.engine.ast.AssignmentExpr; +import com.google.api.generator.engine.ast.ConcreteReference; +import com.google.api.generator.engine.ast.EnumRefExpr; +import com.google.api.generator.engine.ast.Expr; +import com.google.api.generator.engine.ast.ExprStatement; +import com.google.api.generator.engine.ast.MethodDefinition; +import com.google.api.generator.engine.ast.MethodInvocationExpr; +import com.google.api.generator.engine.ast.NewObjectExpr; +import com.google.api.generator.engine.ast.ScopeNode; +import com.google.api.generator.engine.ast.Statement; +import com.google.api.generator.engine.ast.StringObjectValue; +import com.google.api.generator.engine.ast.TypeNode; +import com.google.api.generator.engine.ast.ValueExpr; +import com.google.api.generator.engine.ast.Variable; +import com.google.api.generator.engine.ast.VariableExpr; +import com.google.api.generator.gapic.composer.common.AbstractServiceStubClassComposer; +import com.google.api.generator.gapic.composer.comment.StubCommentComposer; +import com.google.api.generator.gapic.composer.store.TypeStore; +import com.google.api.generator.gapic.composer.utils.ClassNames; +import com.google.api.generator.gapic.model.Method; +import com.google.api.generator.gapic.model.Service; +import com.google.api.generator.gapic.utils.JavaStyle; +import com.google.common.base.Preconditions; +import com.google.common.collect.ImmutableList; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.function.BiFunction; +import java.util.function.Function; +import java.util.stream.Collectors; + +public class HttpJsonServiceStubClassComposer extends AbstractServiceStubClassComposer { + private static final HttpJsonServiceStubClassComposer INSTANCE = + new HttpJsonServiceStubClassComposer(); + + protected HttpJsonServiceStubClassComposer() { + super( + createStaticTypes(), + new StubCommentComposer("REST"), + new ClassNames("HttpJson"), + HttpJsonCallSettings.class, + HttpJsonStubCallableFactory.class, + ApiMethodDescriptor.class, + null); + } + + public static HttpJsonServiceStubClassComposer instance() { + return INSTANCE; + } + + private static TypeStore createStaticTypes() { + TypeStore typeStore = createCommonStaticTypes(); + typeStore.putAll( + Arrays.asList( + ApiMethodDescriptor.class, + ArrayList.class, + FieldsExtractor.class, + InternalApi.class, + HashMap.class, + HttpJsonCallSettings.class, + HttpJsonStubCallableFactory.class, + Map.class, + ProtoMessageRequestFormatter.class, + ProtoMessageResponseParser.class, + ProtoRestSerializer.class)); + + return typeStore; + } + + @Override + protected Statement createMethodDescriptorVariableDecl( + Service service, Method protoMethod, VariableExpr methodDescriptorVarExpr) { + MethodInvocationExpr expr = + MethodInvocationExpr.builder() + .setMethodName("newBuilder") + .setStaticReferenceType( + getFixedTypeStore().get(ApiMethodDescriptor.class.getSimpleName())) + .setGenerics(methodDescriptorVarExpr.variable().type().reference().generics()) + .build(); + + BiFunction, Function> maker = + getMethodMaker(); + + String codeMethodNameArg = getProtoRpcFullMethodName(service, protoMethod); + expr = + maker + .apply( + "setFullMethodName", + Arrays.asList(ValueExpr.withValue(StringObjectValue.withValue(codeMethodNameArg)))) + .apply(expr); + + expr = maker.apply("setHttpMethod", getHttpMethodTypeExpr(protoMethod)).apply(expr); + expr = maker.apply("setRequestFormatter", getRequestFormatterExpr(protoMethod)).apply(expr); + + expr = maker.apply("setResponseParser", setResponseParserExpr(protoMethod)).apply(expr); + + expr = + MethodInvocationExpr.builder() + .setMethodName("build") + .setExprReferenceExpr(expr) + .setReturnType(methodDescriptorVarExpr.type()) + .build(); + + return ExprStatement.withExpr( + AssignmentExpr.builder() + .setVariableExpr( + methodDescriptorVarExpr + .toBuilder() + .setIsDecl(true) + .setScope(ScopeNode.PUBLIC) + .setIsStatic(true) + .setIsFinal(true) + .build()) + .setValueExpr(expr) + .build()); + } + + @Override + protected List createOperationsStubGetterMethod( + VariableExpr operationsStubVarExpr) { + return Collections.emptyList(); + } + + @Override + protected Expr createTransportSettingsInitExpr( + Method method, VariableExpr transportSettingsVarExpr, VariableExpr methodDescriptorVarExpr) { + MethodInvocationExpr callSettingsBuilderExpr = + MethodInvocationExpr.builder() + .setStaticReferenceType( + getFixedTypeStore().get(HttpJsonCallSettings.class.getSimpleName())) + .setGenerics(transportSettingsVarExpr.type().reference().generics()) + .setMethodName("newBuilder") + .build(); + callSettingsBuilderExpr = + MethodInvocationExpr.builder() + .setExprReferenceExpr(callSettingsBuilderExpr) + .setMethodName("setMethodDescriptor") + .setArguments(Arrays.asList(methodDescriptorVarExpr)) + .build(); + + callSettingsBuilderExpr = + MethodInvocationExpr.builder() + .setExprReferenceExpr(callSettingsBuilderExpr) + .setMethodName("build") + .setReturnType(transportSettingsVarExpr.type()) + .build(); + return AssignmentExpr.builder() + .setVariableExpr(transportSettingsVarExpr.toBuilder().setIsDecl(true).build()) + .setValueExpr(callSettingsBuilderExpr) + .build(); + } + + @Override + protected List createClassAnnotations(Service service) { + List annotations = super.createClassAnnotations(service); + + annotations.add( + AnnotationNode.builder() + .setType(getFixedTypeStore().get("BetaApi")) + .setDescription( + "A restructuring of stub classes is planned, so this may break in the future") + .build()); + return annotations; + } + + @Override + protected List createGetMethodDescriptorsMethod( + Service service, + TypeStore typeStore, + Map protoMethodNameToDescriptorVarExprs) { + + List bodyExprs = new ArrayList<>(); + + VariableExpr methodDescriptorsVarExpr = + VariableExpr.withVariable( + Variable.builder() + .setType( + TypeNode.withReference( + ConcreteReference.builder() + .setClazz(List.class) + .setGenerics( + Arrays.asList( + getFixedTypeStore().get("ApiMethodDescriptor").reference())) + .build())) + .setName("methodDescriptors") + .build()); + + bodyExprs.add( + AssignmentExpr.builder() + .setVariableExpr(methodDescriptorsVarExpr.toBuilder().setIsDecl(true).build()) + .setValueExpr( + NewObjectExpr.builder() + .setType(getFixedTypeStore().get("ArrayList")) + .setIsGeneric(true) + .build()) + .build()); + + for (VariableExpr methodDescriptorVarExpr : protoMethodNameToDescriptorVarExprs.values()) { + bodyExprs.add( + MethodInvocationExpr.builder() + .setExprReferenceExpr(methodDescriptorsVarExpr) + .setMethodName("add") + .setArguments(methodDescriptorVarExpr) + .build()); + } + + return Arrays.asList( + MethodDefinition.builder() + .setScope(ScopeNode.PUBLIC) + .setIsStatic(true) + .setReturnType(methodDescriptorsVarExpr.type()) + .setReturnExpr(methodDescriptorsVarExpr) + .setAnnotations( + Arrays.asList(AnnotationNode.withType(getFixedTypeStore().get("InternalApi")))) + .setName("getMethodDescriptors") + .setBody(bodyExprs.stream().map(ExprStatement::withExpr).collect(Collectors.toList())) + .build()); + } + + private BiFunction, Function> + getMethodMaker() { + return (mName, argExpr) -> + (m) -> + MethodInvocationExpr.builder() + .setMethodName(mName) + .setArguments(argExpr) + .setExprReferenceExpr(m) + .build(); + } + + private List getRequestFormatterExpr(Method protoMethod) { + BiFunction, Function> + methodMaker = getMethodMaker(); + + MethodInvocationExpr expr = + MethodInvocationExpr.builder() + .setStaticReferenceType( + getFixedTypeStore().get(ProtoMessageRequestFormatter.class.getSimpleName())) + .setMethodName("newBuilder") + .setGenerics(Collections.singletonList(protoMethod.inputType().reference())) + // .setArguments(Arrays.asList(m)) + .build(); + + TypeNode extractorVarType = + TypeNode.withReference( + ConcreteReference.builder() + .setClazz(Map.class) + .setGenerics(TypeNode.STRING.reference(), TypeNode.STRING.reference()) + .build()); + + expr = + methodMaker + .apply( + "setPath", + Arrays.asList( + ValueExpr.withValue( + StringObjectValue.withValue(protoMethod.httpBindings().pattern())), + createFieldsExtractorAnonClass( + protoMethod, + extractorVarType, + protoMethod.httpBindings().pathParameters(), + "putPathParam"))) + .apply(expr); + + TypeNode fieldsVarGenericType = + TypeNode.withReference( + ConcreteReference.builder() + .setClazz(List.class) + .setGenerics(TypeNode.STRING.reference()) + .build()); + + extractorVarType = + TypeNode.withReference( + ConcreteReference.builder() + .setClazz(Map.class) + .setGenerics(TypeNode.STRING.reference(), fieldsVarGenericType.reference()) + .build()); + + expr = + methodMaker + .apply( + "setQueryParamsExtractor", + Arrays.asList( + createFieldsExtractorAnonClass( + protoMethod, + extractorVarType, + protoMethod.httpBindings().queryParameters(), + "putQueryParam"))) + .apply(expr); + + extractorVarType = TypeNode.STRING; + expr = + methodMaker + .apply( + "setRequestBodyExtractor", + Arrays.asList( + createFieldsExtractorAnonClass( + protoMethod, + extractorVarType, + protoMethod.httpBindings().bodyParameters(), + "toBody"))) + .apply(expr); + expr = methodMaker.apply("build", Collections.emptyList()).apply(expr); + + return Collections.singletonList(expr); + } + + private List setResponseParserExpr(Method protoMethod) { + BiFunction, Function> + methodMaker = getMethodMaker(); + + MethodInvocationExpr expr = + MethodInvocationExpr.builder() + .setStaticReferenceType( + getFixedTypeStore().get(ProtoMessageResponseParser.class.getSimpleName())) + .setMethodName("newBuilder") + .setGenerics(Collections.singletonList(protoMethod.outputType().reference())) + // .setArguments(Arrays.asList(m)) + .build(); + + expr = + methodMaker + .apply( + "setDefaultInstance", + Arrays.asList( + MethodInvocationExpr.builder() + .setStaticReferenceType(protoMethod.outputType()) + .setMethodName("getDefaultInstance") + .setReturnType(protoMethod.outputType()) + .build())) + .apply(expr); + expr = methodMaker.apply("build", Collections.emptyList()).apply(expr); + + return Collections.singletonList(expr); + } + + private Expr createFieldsExtractorAnonClass( + Method method, + TypeNode extractorReturnType, + Set httpBindingFieldNames, + String serializerMethodName) { + Preconditions.checkState( + method.hasHttpBindings(), String.format("Method %s has no HTTP binding", method.name())); + + List bodyExprs = new ArrayList<>(); + + Expr returnExpr = null; + VariableExpr fieldsVarExpr = null; + if (!extractorReturnType.isProtoPrimitiveType()) { + fieldsVarExpr = + VariableExpr.withVariable( + Variable.builder().setName("fields").setType(extractorReturnType).build()); + Expr fieldsAssignExpr = + AssignmentExpr.builder() + .setVariableExpr(fieldsVarExpr.toBuilder().setIsDecl(true).build()) + .setValueExpr( + NewObjectExpr.builder() + .setType(getFixedTypeStore().get(HashMap.class.getSimpleName())) + .setIsGeneric(true) + .build()) + .build(); + + bodyExprs.add(fieldsAssignExpr); + returnExpr = fieldsVarExpr; + } + + TypeNode serializerVarType = + TypeNode.withReference( + ConcreteReference.builder() + .setClazz(ProtoRestSerializer.class) + .setGenerics(method.inputType().reference()) + .build()); + + VariableExpr serializerVarExpr = + VariableExpr.withVariable( + Variable.builder().setName("serializer").setType(serializerVarType).build()); + + Expr serializerAssignExpr = + AssignmentExpr.builder() + .setVariableExpr(serializerVarExpr.toBuilder().setIsDecl(true).build()) + .setValueExpr( + MethodInvocationExpr.builder() + .setStaticReferenceType( + getFixedTypeStore().get(ProtoRestSerializer.class.getSimpleName())) + .setMethodName("create") + .setReturnType(serializerVarType) + .build()) + .build(); + + bodyExprs.add(serializerAssignExpr); + + VariableExpr requestVarExpr = + VariableExpr.withVariable( + Variable.builder().setType(method.inputType()).setName("request").build()); + + for (String httpBindingFieldName : httpBindingFieldNames) { + // Handle foo.bar cases by descending into the subfields. + MethodInvocationExpr.Builder requestFieldGetterExprBuilder = + MethodInvocationExpr.builder().setExprReferenceExpr(requestVarExpr); + String[] descendantFields = httpBindingFieldName.split("\\."); + for (int i = 0; i < descendantFields.length; i++) { + String currFieldName = descendantFields[i]; + String bindingFieldMethodName = + String.format("get%s", JavaStyle.toUpperCamelCase(currFieldName)); + requestFieldGetterExprBuilder = + requestFieldGetterExprBuilder.setMethodName(bindingFieldMethodName); + if (i < descendantFields.length - 1) { + requestFieldGetterExprBuilder = + MethodInvocationExpr.builder() + .setExprReferenceExpr(requestFieldGetterExprBuilder.build()); + } + } + + MethodInvocationExpr requestBuilderExpr = requestFieldGetterExprBuilder.build(); + + ImmutableList.Builder paramsPutArgs = ImmutableList.builder(); + if (fieldsVarExpr != null) { + paramsPutArgs.add(fieldsVarExpr); + } + paramsPutArgs.add( + ValueExpr.withValue( + StringObjectValue.withValue(JavaStyle.toLowerCamelCase(httpBindingFieldName)))); + paramsPutArgs.add(requestBuilderExpr); + + if (fieldsVarExpr == null) { + Expr paramsPutExpr = + MethodInvocationExpr.builder() + .setExprReferenceExpr(serializerVarExpr) + .setMethodName(serializerMethodName) + .setArguments(paramsPutArgs.build()) + .setReturnType(extractorReturnType) + .build(); + + returnExpr = paramsPutExpr; + } else { + Expr paramsPutExpr = + MethodInvocationExpr.builder() + .setExprReferenceExpr(serializerVarExpr) + .setMethodName(serializerMethodName) + .setArguments(paramsPutArgs.build()) + .build(); + bodyExprs.add(paramsPutExpr); + } + } + + if (httpBindingFieldNames.isEmpty()) { + bodyExprs = Collections.emptyList(); + returnExpr = ValueExpr.createNullExpr(); + } + + MethodDefinition extractMethod = + MethodDefinition.builder() + .setIsOverride(true) + .setScope(ScopeNode.PUBLIC) + .setReturnType(extractorReturnType) + .setName("extract") + .setArguments(requestVarExpr.toBuilder().setIsDecl(true).build()) + .setBody(bodyExprs.stream().map(ExprStatement::withExpr).collect(Collectors.toList())) + .setReturnExpr(returnExpr) + .build(); + + TypeNode anonClassType = + TypeNode.withReference( + ConcreteReference.builder() + .setClazz(FieldsExtractor.class) + .setGenerics(method.inputType().reference(), extractorReturnType.reference()) + .build()); + + return AnonymousClassExpr.builder().setType(anonClassType).setMethods(extractMethod).build(); + } + + private List getHttpMethodTypeExpr(Method protoMethod) { + EnumRefExpr expr = + EnumRefExpr.builder() + .setName(protoMethod.httpBindings().httpVerb()) + .setType( + TypeNode.withReference( + ConcreteReference.builder().setClazz(HttpMethods.class).build())) + .build(); + return Collections.singletonList(expr); + } +} diff --git a/src/main/java/com/google/api/generator/gapic/composer/httpjson/ServiceClientTestClassComposer.java b/src/main/java/com/google/api/generator/gapic/composer/httpjson/ServiceClientTestClassComposer.java new file mode 100644 index 0000000000..a3b9696351 --- /dev/null +++ b/src/main/java/com/google/api/generator/gapic/composer/httpjson/ServiceClientTestClassComposer.java @@ -0,0 +1,508 @@ +// Copyright 2021 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 +// +// http://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. + +package com.google.api.generator.gapic.composer.httpjson; + +import com.google.api.gax.httpjson.ApiMethodDescriptor; +import com.google.api.gax.httpjson.GaxHttpJsonProperties; +import com.google.api.gax.httpjson.testing.MockHttpService; +import com.google.api.gax.rpc.ApiClientHeaderProvider; +import com.google.api.gax.rpc.ApiException; +import com.google.api.gax.rpc.ApiExceptionFactory; +import com.google.api.gax.rpc.StatusCode.Code; +import com.google.api.gax.rpc.testing.FakeStatusCode; +import com.google.api.generator.engine.ast.AnnotationNode; +import com.google.api.generator.engine.ast.AssignmentExpr; +import com.google.api.generator.engine.ast.ConcreteReference; +import com.google.api.generator.engine.ast.EnumRefExpr; +import com.google.api.generator.engine.ast.Expr; +import com.google.api.generator.engine.ast.ExprStatement; +import com.google.api.generator.engine.ast.MethodDefinition; +import com.google.api.generator.engine.ast.MethodInvocationExpr; +import com.google.api.generator.engine.ast.NewObjectExpr; +import com.google.api.generator.engine.ast.PrimitiveValue; +import com.google.api.generator.engine.ast.ScopeNode; +import com.google.api.generator.engine.ast.Statement; +import com.google.api.generator.engine.ast.TypeNode; +import com.google.api.generator.engine.ast.ValueExpr; +import com.google.api.generator.engine.ast.Variable; +import com.google.api.generator.engine.ast.VariableExpr; +import com.google.api.generator.gapic.composer.common.AbstractServiceClientTestClassComposer; +import com.google.api.generator.gapic.composer.store.TypeStore; +import com.google.api.generator.gapic.composer.utils.ClassNames; +import com.google.api.generator.gapic.model.GapicContext; +import com.google.api.generator.gapic.model.Message; +import com.google.api.generator.gapic.model.Method; +import com.google.api.generator.gapic.model.MethodArgument; +import com.google.api.generator.gapic.model.ResourceName; +import com.google.api.generator.gapic.model.Service; +import com.google.api.generator.gapic.utils.JavaStyle; +import com.google.common.collect.ImmutableList; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; +import java.util.function.BiFunction; +import java.util.function.Function; +import java.util.stream.Collectors; + +public class ServiceClientTestClassComposer extends AbstractServiceClientTestClassComposer { + private static final String MOCK_SERVICE_VAR_NAME = "mockService"; + private static final String METHOD_DESCRIPTOR_NAME_PATTERN = "%sMethodDescriptor"; + + private static final ServiceClientTestClassComposer INSTANCE = + new ServiceClientTestClassComposer(); + + protected ServiceClientTestClassComposer() { + super(createTypes(), new ClassNames("HttpJson")); + } + + public static ServiceClientTestClassComposer instance() { + return INSTANCE; + } + + private static TypeStore createTypes() { + TypeStore typeStore = createCommonTypes(); + typeStore.putAll( + Arrays.asList( + ApiClientHeaderProvider.class, + ApiException.class, + ApiExceptionFactory.class, + ApiMethodDescriptor.class, + Code.class, + Exception.class, + FakeStatusCode.class, + GaxHttpJsonProperties.class, + ImmutableList.class, + MockHttpService.class, + String.class)); + return typeStore; + } + + @Override + protected Map createClassMemberVarExprs( + Service service, GapicContext context, TypeStore typeStore) { + BiFunction varExprFn = + (name, type) -> + VariableExpr.withVariable(Variable.builder().setName(name).setType(type).build()); + Map fields = new LinkedHashMap<>(); + fields.put( + MOCK_SERVICE_VAR_NAME, getFixedTypeStore().get(MockHttpService.class.getSimpleName())); + fields.put(CLIENT_VAR_NAME, typeStore.get(ClassNames.getServiceClientClassName(service))); + return fields.entrySet().stream() + .collect(Collectors.toMap(e -> e.getKey(), e -> varExprFn.apply(e.getKey(), e.getValue()))); + } + + @Override + protected List createClassMemberFieldDecls( + Map classMemberVarExprs) { + return classMemberVarExprs.values().stream() + .map( + v -> + ExprStatement.withExpr( + v.toBuilder() + .setIsDecl(true) + .setScope(ScopeNode.PRIVATE) + .setIsStatic(true) + .build())) + .collect(Collectors.toList()); + } + + @Override + protected MethodDefinition createStartStaticServerMethod( + Service service, + GapicContext context, + Map classMemberVarExprs, + TypeStore typeStore) { + + VariableExpr mockServiceVarExpr = classMemberVarExprs.get(MOCK_SERVICE_VAR_NAME); + VariableExpr clientVarExpr = classMemberVarExprs.get(CLIENT_VAR_NAME); + TypeNode settingsType = typeStore.get(ClassNames.getServiceSettingsClassName(service)); + TypeNode transportStubType = + typeStore.get(getClassNames().getTransportServiceStubClassName(service)); + + Function> methodBuilderFn = + methodExpr -> + (mName, argExpr) -> + MethodInvocationExpr.builder() + .setExprReferenceExpr(methodExpr) + .setMethodName(mName) + .setArguments(Arrays.asList(argExpr)) + .build(); + + Expr initMockServiceExpr = + AssignmentExpr.builder() + .setVariableExpr(mockServiceVarExpr) + .setValueExpr( + NewObjectExpr.builder() + .setType(mockServiceVarExpr.type()) + .setArguments( + MethodInvocationExpr.builder() + .setStaticReferenceType(transportStubType) + .setMethodName("getMethodDescriptors") + .build(), + MethodInvocationExpr.builder() + .setStaticReferenceType(settingsType) + .setMethodName("getDefaultEndpoint") + .build()) + .build()) + .build(); + + VariableExpr localSettingsVarExpr = + VariableExpr.withVariable( + Variable.builder().setName("settings").setType(settingsType).build()); + + Expr settingsBuilderExpr = + MethodInvocationExpr.builder() + .setStaticReferenceType(settingsType) + .setMethodName("newBuilder") + .build(); + + Expr transportChannelProviderExpr = + MethodInvocationExpr.builder() + .setStaticReferenceType(settingsType) + .setMethodName("defaultHttpJsonTransportProviderBuilder") + .build(); + + transportChannelProviderExpr = + methodBuilderFn + .apply(transportChannelProviderExpr) + .apply("setHttpTransport", mockServiceVarExpr); + + transportChannelProviderExpr = + MethodInvocationExpr.builder() + .setExprReferenceExpr(transportChannelProviderExpr) + .setMethodName("build") + .setReturnType(localSettingsVarExpr.type()) + .build(); + + settingsBuilderExpr = + methodBuilderFn + .apply(settingsBuilderExpr) + .apply("setTransportChannelProvider", transportChannelProviderExpr); + + settingsBuilderExpr = + methodBuilderFn + .apply(settingsBuilderExpr) + .apply( + "setCredentialsProvider", + MethodInvocationExpr.builder() + .setStaticReferenceType(getFixedTypeStore().get("NoCredentialsProvider")) + .setMethodName("create") + .build()); + settingsBuilderExpr = + MethodInvocationExpr.builder() + .setExprReferenceExpr(settingsBuilderExpr) + .setMethodName("build") + .setReturnType(localSettingsVarExpr.type()) + .build(); + + Expr initLocalSettingsExpr = + AssignmentExpr.builder() + .setVariableExpr(localSettingsVarExpr.toBuilder().setIsDecl(true).build()) + .setValueExpr(settingsBuilderExpr) + .build(); + + Expr initClientExpr = + AssignmentExpr.builder() + .setVariableExpr(clientVarExpr) + .setValueExpr( + MethodInvocationExpr.builder() + .setStaticReferenceType( + typeStore.get(ClassNames.getServiceClientClassName(service))) + .setMethodName("create") + .setArguments(Arrays.asList(localSettingsVarExpr)) + .setReturnType(clientVarExpr.type()) + .build()) + .build(); + + return MethodDefinition.builder() + .setAnnotations( + Arrays.asList(AnnotationNode.withType(getFixedTypeStore().get("BeforeClass")))) + .setScope(ScopeNode.PUBLIC) + .setReturnType(TypeNode.VOID) + .setName("startStaticServer") + .setThrowsExceptions(Arrays.asList(getFixedTypeStore().get("IOException"))) + .setIsStatic(true) + .setBody( + Arrays.asList(initMockServiceExpr, initLocalSettingsExpr, initClientExpr).stream() + .map(e -> ExprStatement.withExpr(e)) + .collect(Collectors.toList())) + .build(); + } + + @Override + protected MethodDefinition createStopServerMethod( + Service service, Map classMemberVarExprs) { + return MethodDefinition.builder() + .setAnnotations( + Arrays.asList(AnnotationNode.withType(getFixedTypeStore().get("AfterClass")))) + .setScope(ScopeNode.PUBLIC) + .setIsStatic(true) + .setReturnType(TypeNode.VOID) + .setName("stopServer") + .setBody( + Arrays.asList( + ExprStatement.withExpr( + MethodInvocationExpr.builder() + .setExprReferenceExpr(classMemberVarExprs.get(CLIENT_VAR_NAME)) + .setMethodName("close") + .build()))) + .build(); + } + + @Override + protected MethodDefinition createSetUpMethod( + Service service, Map classMemberVarExprs, TypeStore typeStore) { + + return MethodDefinition.builder() + .setAnnotations(Arrays.asList(AnnotationNode.withType(getFixedTypeStore().get("Before")))) + .setScope(ScopeNode.PUBLIC) + .setReturnType(TypeNode.VOID) + .setName("setUp") + .setBody(Arrays.asList()) + .build(); + } + + @Override + protected MethodDefinition createTearDownMethod( + Service service, Map classMemberVarExprs) { + return MethodDefinition.builder() + .setAnnotations(Arrays.asList(AnnotationNode.withType(getFixedTypeStore().get("After")))) + .setScope(ScopeNode.PUBLIC) + .setReturnType(TypeNode.VOID) + .setName("tearDown") + .setThrowsExceptions( + Arrays.asList(TypeNode.withReference(ConcreteReference.withClazz(Exception.class)))) + .setBody( + Arrays.asList( + ExprStatement.withExpr( + MethodInvocationExpr.builder() + .setExprReferenceExpr(classMemberVarExprs.get(MOCK_SERVICE_VAR_NAME)) + .setMethodName("reset") + .build()))) + .build(); + } + + @Override + protected List constructRpcTestCheckerLogic( + Method method, + Service service, + boolean isRequestArg, + Map classMemberVarExprs, + VariableExpr requestVarExpr, + Message requestMessage, + List argExprs) { + + List methodExprs = new ArrayList<>(); + List methodStatements = new ArrayList<>(); + + VariableExpr actualRequestsVarExpr = + VariableExpr.withVariable( + Variable.builder() + .setType( + TypeNode.withReference( + ConcreteReference.builder() + .setClazz(List.class) + .setGenerics( + Arrays.asList(getFixedTypeStore().get("String").reference())) + .build())) + .setName("actualRequests") + .build()); + methodExprs.add( + AssignmentExpr.builder() + .setVariableExpr(actualRequestsVarExpr.toBuilder().setIsDecl(true).build()) + .setValueExpr( + MethodInvocationExpr.builder() + .setExprReferenceExpr(classMemberVarExprs.get(getMockServiceVarName(service))) + .setMethodName("getRequestPaths") + .setReturnType(actualRequestsVarExpr.type()) + .build()) + .build()); + + methodExprs.add( + MethodInvocationExpr.builder() + .setStaticReferenceType(getFixedTypeStore().get("Assert")) + .setMethodName("assertEquals") + .setArguments( + ValueExpr.withValue( + PrimitiveValue.builder().setType(TypeNode.INT).setValue("1").build()), + MethodInvocationExpr.builder() + .setExprReferenceExpr(actualRequestsVarExpr) + .setMethodName("size") + .build()) + .build()); + + methodStatements.addAll( + methodExprs.stream().map(ExprStatement::withExpr).collect(Collectors.toList())); + + methodExprs.clear(); + methodStatements.add(EMPTY_LINE_STATEMENT); + + VariableExpr apiClientHeaderKeyVarExpr = + VariableExpr.withVariable( + Variable.builder() + .setType(getFixedTypeStore().get("String")) + .setName("apiClientHeaderKey") + .build()); + + AssignmentExpr apiClientHeaderKeyAssignExpr = + AssignmentExpr.builder() + .setVariableExpr(apiClientHeaderKeyVarExpr.toBuilder().setIsDecl(true).build()) + .setValueExpr( + MethodInvocationExpr.builder() + .setMethodName("next") + .setReturnType(apiClientHeaderKeyVarExpr.type()) + .setExprReferenceExpr( + MethodInvocationExpr.builder() + .setMethodName("iterator") + .setExprReferenceExpr( + MethodInvocationExpr.builder() + .setMethodName("get") + .setArguments( + MethodInvocationExpr.builder() + .setMethodName("getDefaultApiClientHeaderKey") + .setStaticReferenceType( + getFixedTypeStore().get("ApiClientHeaderProvider")) + .build()) + .setExprReferenceExpr( + MethodInvocationExpr.builder() + .setMethodName("getRequestHeaders") + .setExprReferenceExpr( + classMemberVarExprs.get( + getMockServiceVarName(service))) + .build()) + .build()) + .build()) + .build()) + .build(); + + methodExprs.add(apiClientHeaderKeyAssignExpr); + + methodExprs.add( + MethodInvocationExpr.builder() + .setMethodName("assertTrue") + .setStaticReferenceType(getFixedTypeStore().get("Assert")) + .setArguments( + MethodInvocationExpr.builder() + .setMethodName("matches") + .setExprReferenceExpr( + MethodInvocationExpr.builder() + .setMethodName("matcher") + .setArguments(apiClientHeaderKeyVarExpr) + .setExprReferenceExpr( + MethodInvocationExpr.builder() + .setMethodName("getDefaultApiClientHeaderPattern") + .setStaticReferenceType( + getFixedTypeStore().get("GaxHttpJsonProperties")) + .build()) + .build()) + .build()) + .build()); + + methodStatements.addAll( + methodExprs.stream().map(ExprStatement::withExpr).collect(Collectors.toList())); + methodExprs.clear(); + + return methodStatements; + } + + @Override + protected MethodDefinition createRpcExceptionTestMethod( + Method method, + Service service, + List methodSignature, + int variantIndex, + Map classMemberVarExprs, + Map resourceNames, + Map messageTypes) { + VariableExpr exceptionVarExpr = + VariableExpr.withVariable( + Variable.builder() + .setType(getFixedTypeStore().get("ApiException")) + .setName("exception") + .build()); + + // First two assignment lines. + + Expr exceptionAssignExpr = + AssignmentExpr.builder() + .setVariableExpr(exceptionVarExpr.toBuilder().setIsDecl(true).build()) + .setValueExpr( + MethodInvocationExpr.builder() + .setMethodName("createException") + .setStaticReferenceType(getFixedTypeStore().get("ApiExceptionFactory")) + .setArguments( + NewObjectExpr.withType(getFixedTypeStore().get("Exception")), + MethodInvocationExpr.builder() + .setMethodName("of") + .setStaticReferenceType(getFixedTypeStore().get("FakeStatusCode")) + .setArguments( + EnumRefExpr.builder() + .setName("INVALID_ARGUMENT") + .setType(getFixedTypeStore().get("Code")) + .build()) + .build(), + ValueExpr.withValue( + PrimitiveValue.builder() + .setType(TypeNode.BOOLEAN) + .setValue("false") + .build())) + .setReturnType(exceptionVarExpr.type()) + .build()) + .build(); + + Expr addExceptionExpr = + MethodInvocationExpr.builder() + .setExprReferenceExpr(classMemberVarExprs.get(getMockServiceVarName(service))) + .setMethodName("addException") + .setArguments(exceptionVarExpr) + .build(); + + // Try-catch block. Build the method call. + String exceptionTestMethodName = + String.format( + "%sExceptionTest%s", + JavaStyle.toLowerCamelCase(method.name()), variantIndex > 0 ? variantIndex + 1 : ""); + + boolean isStreaming = !method.stream().equals(Method.Stream.NONE); + List methodBody = new ArrayList<>(); + methodBody.add(ExprStatement.withExpr(exceptionAssignExpr)); + methodBody.add(ExprStatement.withExpr(addExceptionExpr)); + if (isStreaming) { + methodBody.addAll( + createStreamingRpcExceptionTestStatements( + method, classMemberVarExprs, resourceNames, messageTypes)); + } else { + methodBody.addAll( + createRpcExceptionTestStatements( + method, methodSignature, classMemberVarExprs, resourceNames, messageTypes)); + } + + return MethodDefinition.builder() + .setAnnotations(Arrays.asList(getTestAnnotation())) + .setScope(ScopeNode.PUBLIC) + .setReturnType(TypeNode.VOID) + .setName(exceptionTestMethodName) + .setThrowsExceptions(Arrays.asList(TypeNode.withExceptionClazz(Exception.class))) + .setBody(methodBody) + .build(); + } + + @Override + protected String getMockServiceVarName(Service service) { + return String.format(MOCK_SERVICE_VAR_NAME); + } +} diff --git a/src/main/java/com/google/api/generator/gapic/composer/httpjson/ServiceSettingsClassComposer.java b/src/main/java/com/google/api/generator/gapic/composer/httpjson/ServiceSettingsClassComposer.java new file mode 100644 index 0000000000..bd9d0d97bb --- /dev/null +++ b/src/main/java/com/google/api/generator/gapic/composer/httpjson/ServiceSettingsClassComposer.java @@ -0,0 +1,42 @@ +// Copyright 2021 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 +// +// http://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. + +package com.google.api.generator.gapic.composer.httpjson; + +import com.google.api.gax.httpjson.InstantiatingHttpJsonChannelProvider; +import com.google.api.generator.gapic.composer.common.AbstractServiceSettingsClassComposer; +import com.google.api.generator.gapic.composer.store.TypeStore; +import java.util.Arrays; + +public class ServiceSettingsClassComposer extends AbstractServiceSettingsClassComposer { + private static final ServiceSettingsClassComposer INSTANCE = + new ServiceSettingsClassComposer(); + + protected ServiceSettingsClassComposer() { + super( + createTypes(), + InstantiatingHttpJsonChannelProvider.Builder.class, + "defaultHttpJsonTransportProviderBuilder"); + } + + public static ServiceSettingsClassComposer instance() { + return INSTANCE; + } + + private static TypeStore createTypes() { + TypeStore typeStore = createCommonTypes(); + typeStore.putAll(Arrays.asList(InstantiatingHttpJsonChannelProvider.class)); + return typeStore; + } +} diff --git a/src/main/java/com/google/api/generator/gapic/composer/httpjson/ServiceStubSettingsClassComposer.java b/src/main/java/com/google/api/generator/gapic/composer/httpjson/ServiceStubSettingsClassComposer.java new file mode 100644 index 0000000000..9a2f14c8fb --- /dev/null +++ b/src/main/java/com/google/api/generator/gapic/composer/httpjson/ServiceStubSettingsClassComposer.java @@ -0,0 +1,176 @@ +// Copyright 2021 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 +// +// http://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. + +package com.google.api.generator.gapic.composer.httpjson; + +import com.google.api.gax.httpjson.GaxHttpJsonProperties; +import com.google.api.gax.httpjson.HttpJsonTransportChannel; +import com.google.api.gax.httpjson.InstantiatingHttpJsonChannelProvider; +import com.google.api.gax.rpc.ApiClientHeaderProvider; +import com.google.api.generator.engine.ast.AnnotationNode; +import com.google.api.generator.engine.ast.ConcreteReference; +import com.google.api.generator.engine.ast.MethodDefinition; +import com.google.api.generator.engine.ast.MethodInvocationExpr; +import com.google.api.generator.engine.ast.ScopeNode; +import com.google.api.generator.engine.ast.StringObjectValue; +import com.google.api.generator.engine.ast.TypeNode; +import com.google.api.generator.engine.ast.ValueExpr; +import com.google.api.generator.engine.ast.Variable; +import com.google.api.generator.engine.ast.VariableExpr; +import com.google.api.generator.gapic.composer.common.AbstractServiceStubSettingsClassComposer; +import com.google.api.generator.gapic.composer.comment.SettingsCommentComposer; +import com.google.api.generator.gapic.composer.store.TypeStore; +import com.google.api.generator.gapic.composer.utils.ClassNames; +import com.google.api.generator.gapic.model.Service; +import java.util.Arrays; + +public class ServiceStubSettingsClassComposer extends + AbstractServiceStubSettingsClassComposer { + private static final ServiceStubSettingsClassComposer INSTANCE = + new ServiceStubSettingsClassComposer(); + + public static ServiceStubSettingsClassComposer instance() { + return INSTANCE; + } + + protected ServiceStubSettingsClassComposer() { + super( + createStaticTypes(), + new ClassNames("HttpJson"), + HttpJsonTransportChannel.class, + "getHttpJsonTransportName"); + } + + private static TypeStore createStaticTypes() { + TypeStore typeStore = createCommonStaticTypes(); + typeStore.putAll( + Arrays.asList( + GaxHttpJsonProperties.class, + HttpJsonTransportChannel.class, + InstantiatingHttpJsonChannelProvider.class)); + return typeStore; + } + + @Override + protected MethodDefinition createDefaultTransportTransportProviderBuilderMethod() { + // Create the defaultHttpJsonTransportProviderBuilder method. + TypeNode returnType = + TypeNode.withReference( + ConcreteReference.withClazz(InstantiatingHttpJsonChannelProvider.Builder.class)); + MethodInvocationExpr transportChannelProviderBuilderExpr = + MethodInvocationExpr.builder() + .setStaticReferenceType( + getFixedTypeStore().get(InstantiatingHttpJsonChannelProvider.class.getSimpleName())) + .setMethodName("newBuilder") + .setReturnType(returnType) + .build(); + return MethodDefinition.builder() + .setHeaderCommentStatements( + SettingsCommentComposer.DEFAULT_TRANSPORT_PROVIDER_BUILDER_METHOD_COMMENT) + .setScope(ScopeNode.PUBLIC) + .setIsStatic(true) + .setReturnType(returnType) + .setName("defaultHttpJsonTransportProviderBuilder") + .setReturnExpr(transportChannelProviderBuilderExpr) + .build(); + } + + @Override + protected MethodDefinition createDefaultApiClientHeaderProviderBuilderMethod( + Service service, TypeStore typeStore) { + // Create the defaultApiClientHeaderProviderBuilder method. + TypeNode returnType = + TypeNode.withReference(ConcreteReference.withClazz(ApiClientHeaderProvider.Builder.class)); + MethodInvocationExpr returnExpr = + MethodInvocationExpr.builder() + .setStaticReferenceType(getFixedTypeStore().get("ApiClientHeaderProvider")) + .setMethodName("newBuilder") + .build(); + + MethodInvocationExpr versionArgExpr = + MethodInvocationExpr.builder() + .setStaticReferenceType(getFixedTypeStore().get("GaxProperties")) + .setMethodName("getLibraryVersion") + .setArguments( + VariableExpr.builder() + .setVariable( + Variable.builder().setType(TypeNode.CLASS_OBJECT).setName("class").build()) + .setStaticReferenceType( + typeStore.get(ClassNames.getServiceStubSettingsClassName(service))) + .build()) + .build(); + + returnExpr = + MethodInvocationExpr.builder() + .setExprReferenceExpr(returnExpr) + .setMethodName("setGeneratedLibToken") + .setArguments(ValueExpr.withValue(StringObjectValue.withValue("gapic")), versionArgExpr) + .build(); + returnExpr = + MethodInvocationExpr.builder() + .setExprReferenceExpr(returnExpr) + .setMethodName("setTransportToken") + .setArguments( + MethodInvocationExpr.builder() + .setStaticReferenceType( + getFixedTypeStore().get(GaxHttpJsonProperties.class.getSimpleName())) + .setMethodName("getHttpJsonTokenName") + .build(), + MethodInvocationExpr.builder() + .setStaticReferenceType( + getFixedTypeStore().get(GaxHttpJsonProperties.class.getSimpleName())) + .setMethodName("getHttpJsonVersion") + .build()) + .setReturnType(returnType) + .build(); + + AnnotationNode annotation = + AnnotationNode.builder() + .setType(getFixedTypeStore().get("BetaApi")) + .setDescription( + "The surface for customizing headers is not stable yet and may change in the" + + " future.") + .build(); + return MethodDefinition.builder() + .setAnnotations(Arrays.asList(annotation)) + .setScope(ScopeNode.PUBLIC) + .setIsStatic(true) + .setReturnType(returnType) + .setName("defaultApiClientHeaderProviderBuilder") + .setReturnExpr(returnExpr) + .build(); + } + + @Override + public MethodDefinition createDefaultTransportChannelProviderMethod() { + TypeNode returnType = getFixedTypeStore().get("TransportChannelProvider"); + MethodInvocationExpr transportProviderBuilderExpr = + MethodInvocationExpr.builder() + .setMethodName("defaultHttpJsonTransportProviderBuilder") + .build(); + transportProviderBuilderExpr = + MethodInvocationExpr.builder() + .setExprReferenceExpr(transportProviderBuilderExpr) + .setMethodName("build") + .setReturnType(returnType) + .build(); + return MethodDefinition.builder() + .setScope(ScopeNode.PUBLIC) + .setIsStatic(true) + .setReturnType(returnType) + .setName("defaultTransportChannelProvider") + .setReturnExpr(transportProviderBuilderExpr) + .build(); + } +} diff --git a/src/main/java/com/google/api/generator/gapic/composer/store/TypeStore.java b/src/main/java/com/google/api/generator/gapic/composer/store/TypeStore.java index aa7ff06647..1a6c2e1c13 100644 --- a/src/main/java/com/google/api/generator/gapic/composer/store/TypeStore.java +++ b/src/main/java/com/google/api/generator/gapic/composer/store/TypeStore.java @@ -24,16 +24,20 @@ import java.util.stream.Collectors; public class TypeStore { - private Map store = new HashMap<>(); + private final Map store = new HashMap<>(); public TypeStore() {} public TypeStore(List concreteClasses) { + putConcreteClassses(concreteClasses); + } + + private void putConcreteClassses(List concreteClasses) { store.putAll( concreteClasses.stream() .collect( Collectors.toMap( - c -> c.getSimpleName(), + Class::getSimpleName, c -> TypeNode.withReference(ConcreteReference.withClazz(c))))); } @@ -67,6 +71,10 @@ public void put( .build())); } + public void putAll(List concreteClasses) { + putConcreteClassses(concreteClasses); + } + public void putAll( String pakkage, List typeNames, diff --git a/src/main/java/com/google/api/generator/gapic/composer/utils/ClassNames.java b/src/main/java/com/google/api/generator/gapic/composer/utils/ClassNames.java index fb54e3f4d4..f1abb45a4c 100644 --- a/src/main/java/com/google/api/generator/gapic/composer/utils/ClassNames.java +++ b/src/main/java/com/google/api/generator/gapic/composer/utils/ClassNames.java @@ -26,9 +26,15 @@ public class ClassNames { private static final String SERVICE_SETTINGS_CLASS_NAME_PATTERN = "%sSettings"; private static final String SERVICE_STUB_SETTINGS_CLASS_NAME_PATTERN = "%sStubSettings"; private static final String SERVICE_STUB_CLASS_NAME_PATTERN = "%sStub"; - private static final String GRPC_SERVICE_STUB_CLASS_NAME_PATTERN = "Grpc%sStub"; - private static final String GRPC_SERVICE_CALLABLE_FACTORY_CLASS_NAME_PATTERN = - "Grpc%sCallableFactory"; + private static final String TRANSPORT_SERVICE_STUB_CLASS_NAME_PATTERN = "%s%sStub"; + private static final String TRANSPORT_SERVICE_CALLABLE_FACTORY_CLASS_NAME_PATTERN = + "%s%sCallableFactory"; + + private final String transportPrefix; + + public ClassNames(String transportPrefix) { + this.transportPrefix = transportPrefix; + } public static String getServiceClientClassName(Service service) { return String.format( @@ -52,15 +58,18 @@ public static String getServiceStubClassName(Service service) { SERVICE_STUB_CLASS_NAME_PATTERN, monolithBackwardsCompatibleName(service.name())); } - public static String getGrpcServiceCallableFactoryClassName(Service service) { + public String getTransportServiceCallableFactoryClassName(Service service) { return String.format( - GRPC_SERVICE_CALLABLE_FACTORY_CLASS_NAME_PATTERN, + TRANSPORT_SERVICE_CALLABLE_FACTORY_CLASS_NAME_PATTERN, + transportPrefix, monolithBackwardsCompatibleName(service.name())); } - public static String getGrpcServiceStubClassName(Service service) { + public String getTransportServiceStubClassName(Service service) { return String.format( - GRPC_SERVICE_STUB_CLASS_NAME_PATTERN, monolithBackwardsCompatibleName(service.name())); + TRANSPORT_SERVICE_STUB_CLASS_NAME_PATTERN, + transportPrefix, + monolithBackwardsCompatibleName(service.name())); } public static String getServiceClientTestClassName(Service service) { diff --git a/src/main/java/com/google/api/generator/gapic/model/GapicContext.java b/src/main/java/com/google/api/generator/gapic/model/GapicContext.java index bc4561a0ad..f209f55aa3 100644 --- a/src/main/java/com/google/api/generator/gapic/model/GapicContext.java +++ b/src/main/java/com/google/api/generator/gapic/model/GapicContext.java @@ -56,6 +56,9 @@ public GapicMetadata gapicMetadata() { @Nullable public abstract com.google.api.Service serviceYamlProto(); + @Nullable + public abstract Transport transport(); + public boolean hasServiceYamlProto() { return serviceYamlProto() != null; } @@ -104,6 +107,8 @@ public Builder setHelperResourceNames(Set helperResourceNames) { public abstract Builder setServiceYamlProto(com.google.api.Service serviceYamlProto); + public abstract Builder setTransport(Transport transport); + public abstract Builder setGapicMetadataEnabled(boolean gapicMetadataEnabled); public abstract GapicContext build(); diff --git a/src/main/java/com/google/api/generator/gapic/model/HttpRuleBindings.java b/src/main/java/com/google/api/generator/gapic/model/HttpRuleBindings.java new file mode 100644 index 0000000000..073069be06 --- /dev/null +++ b/src/main/java/com/google/api/generator/gapic/model/HttpRuleBindings.java @@ -0,0 +1,58 @@ +// Copyright 2021 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 +// +// http://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. + +package com.google.api.generator.gapic.model; + +import com.google.auto.value.AutoValue; +import com.google.common.collect.ImmutableSet; +import java.util.Set; + +@AutoValue +public abstract class HttpRuleBindings { + public abstract String httpVerb(); + + public abstract String pattern(); + + public abstract Set pathParameters(); + + public abstract Set queryParameters(); + + public abstract Set bodyParameters(); + + // Private. + public static HttpRuleBindings.Builder builder() { + return new AutoValue_HttpRuleBindings.Builder() + .setHttpVerb("") + .setPattern("") + .setPathParameters(ImmutableSet.of()) + .setQueryParameters(ImmutableSet.of()) + .setBodyParameters(ImmutableSet.of()); + } + + // Private. + @AutoValue.Builder + public abstract static class Builder { + public abstract HttpRuleBindings.Builder setHttpVerb(String httpVerb); + + public abstract HttpRuleBindings.Builder setPattern(String pattern); + + public abstract HttpRuleBindings.Builder setPathParameters(Set pathParameters); + + public abstract HttpRuleBindings.Builder setQueryParameters(Set queryParameters); + + public abstract HttpRuleBindings.Builder setBodyParameters(Set bodyParameters); + + public abstract HttpRuleBindings build(); + } +} diff --git a/src/main/java/com/google/api/generator/gapic/model/Method.java b/src/main/java/com/google/api/generator/gapic/model/Method.java index df5a9aa668..82d5e46760 100644 --- a/src/main/java/com/google/api/generator/gapic/model/Method.java +++ b/src/main/java/com/google/api/generator/gapic/model/Method.java @@ -53,9 +53,8 @@ public enum Stream { @Nullable public abstract String mixedInApiName(); - // TODO(miraleung): May need to change this to MethodArgument, Field, or some new struct // HttpBinding pending dotted reference support. - public abstract List httpBindings(); + public abstract HttpRuleBindings httpBindings(); // Example from Expand in echo.proto: Thet TypeNodes that map to // [["content", "error"], ["content", "error", "info"]]. @@ -70,7 +69,7 @@ public boolean hasDescription() { } public boolean hasHttpBindings() { - return !httpBindings().isEmpty(); + return !httpBindings().pathParameters().isEmpty(); } public boolean isMixin() { @@ -83,7 +82,7 @@ public static Builder builder() { return new AutoValue_Method.Builder() .setStream(Stream.NONE) .setMethodSignatures(ImmutableList.of()) - .setHttpBindings(ImmutableList.of()) + .setHttpBindings(HttpRuleBindings.builder().build()) .setIsBatching(false) .setIsPaged(false) .setIsDeprecated(false); @@ -118,7 +117,7 @@ public abstract static class Builder { public abstract Builder setMixedInApiName(String mixedInApiName); - public abstract Builder setHttpBindings(List httpBindings); + public abstract Builder setHttpBindings(HttpRuleBindings httpBindings); public abstract Builder setMethodSignatures(List> methodSignature); diff --git a/src/test/java/com/google/api/generator/gapic/composer/constants/ComposerConstants.java b/src/main/java/com/google/api/generator/gapic/model/Transport.java similarity index 60% rename from src/test/java/com/google/api/generator/gapic/composer/constants/ComposerConstants.java rename to src/main/java/com/google/api/generator/gapic/model/Transport.java index c8247b10eb..f07efc4dac 100644 --- a/src/test/java/com/google/api/generator/gapic/composer/constants/ComposerConstants.java +++ b/src/main/java/com/google/api/generator/gapic/model/Transport.java @@ -1,4 +1,4 @@ -// Copyright 2020 Google LLC +// Copyright 2021 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -12,11 +12,14 @@ // See the License for the specific language governing permissions and // limitations under the License. -package com.google.api.generator.gapic.composer.constants; +package com.google.api.generator.gapic.model; -public class ComposerConstants { - public static final String GOLDENFILES_DIRECTORY = - "src/test/java/com/google/api/generator/gapic/composer/goldens/"; - public static final String TESTFILES_DIRECTORY = - "src/test/java/com/google/api/generator/gapic/testdata/"; +public enum Transport { + REST, + GRPC, + GRPC_REST; + + public static Transport parse(String name) { + return valueOf(name.replace('+', '_').toUpperCase()); + } } diff --git a/src/main/java/com/google/api/generator/gapic/protoparser/HttpRuleParser.java b/src/main/java/com/google/api/generator/gapic/protoparser/HttpRuleParser.java index 488bc52cea..e2d5b6896e 100644 --- a/src/main/java/com/google/api/generator/gapic/protoparser/HttpRuleParser.java +++ b/src/main/java/com/google/api/generator/gapic/protoparser/HttpRuleParser.java @@ -18,29 +18,29 @@ import com.google.api.HttpRule; import com.google.api.HttpRule.PatternCase; import com.google.api.generator.gapic.model.Field; +import com.google.api.generator.gapic.model.HttpRuleBindings; import com.google.api.generator.gapic.model.Message; import com.google.api.pathtemplate.PathTemplate; import com.google.common.base.Preconditions; import com.google.common.base.Strings; +import com.google.common.collect.ImmutableSet; +import com.google.common.collect.ImmutableSortedSet; +import com.google.common.collect.Sets; import com.google.protobuf.DescriptorProtos.MethodOptions; import com.google.protobuf.Descriptors.MethodDescriptor; -import java.util.ArrayList; -import java.util.Collections; -import java.util.HashSet; -import java.util.List; import java.util.Map; -import java.util.Optional; import java.util.Set; import java.util.stream.Collectors; public class HttpRuleParser { private static final String ASTERISK = "*"; - public static Optional> parseHttpBindings( + public static HttpRuleBindings parse( MethodDescriptor protoMethod, Message inputMessage, Map messageTypes) { MethodOptions methodOptions = protoMethod.getOptions(); + HttpRuleBindings.Builder httpBindings = HttpRuleBindings.builder(); if (!methodOptions.hasExtension(AnnotationsProto.http)) { - return Optional.empty(); + return httpBindings.build(); } HttpRule httpRule = methodOptions.getExtension(AnnotationsProto.http); @@ -51,19 +51,16 @@ public static Optional> parseHttpBindings( } // Get pattern. - Set uniqueBindings = getPatternBindings(httpRule); - if (uniqueBindings.isEmpty()) { - return Optional.empty(); - } - + String pattern = getPattern(httpRule); + ImmutableSet.Builder bindingsBuilder = getPatternBindings(pattern); if (httpRule.getAdditionalBindingsCount() > 0) { for (HttpRule additionalRule : httpRule.getAdditionalBindingsList()) { - uniqueBindings.addAll(getPatternBindings(additionalRule)); + // TODO: save additional bindings path in HttpRuleBindings + bindingsBuilder.addAll(getPatternBindings(getPattern(additionalRule)).build()); } } - List bindings = new ArrayList<>(uniqueBindings); - Collections.sort(bindings); + Set bindings = bindingsBuilder.build(); // Binding validation. for (String binding : bindings) { @@ -86,40 +83,60 @@ public static Optional> parseHttpBindings( } } - return Optional.of(bindings); + String body = httpRule.getBody(); + Set bodyParameters; + Set queryParameters; + if (Strings.isNullOrEmpty(body)) { + bodyParameters = ImmutableSet.of(); + queryParameters = Sets.difference(inputMessage.fieldMap().keySet(), bindings); + } else if (body.equals(ASTERISK)) { + bodyParameters = Sets.difference(inputMessage.fieldMap().keySet(), bindings); + queryParameters = ImmutableSet.of(); + } else { + bodyParameters = ImmutableSet.of(body); + Set bodyBinidngsUnion = Sets.union(bodyParameters, bindings); + queryParameters = Sets.difference(inputMessage.fieldMap().keySet(), bodyBinidngsUnion); + } + + httpBindings.setHttpVerb(httpRule.getPatternCase().toString()); + httpBindings.setPattern(pattern); + httpBindings.setPathParameters(ImmutableSortedSet.copyOf(bindings)); + httpBindings.setQueryParameters(ImmutableSortedSet.copyOf(queryParameters)); + httpBindings.setBodyParameters(ImmutableSortedSet.copyOf(bodyParameters)); + + return httpBindings.build(); } - private static Set getPatternBindings(HttpRule httpRule) { - String pattern = null; - // Assign a temp variable to prevent the formatter from removing the import. + private static String getPattern(HttpRule httpRule) { PatternCase patternCase = httpRule.getPatternCase(); switch (patternCase) { case GET: - pattern = httpRule.getGet(); - break; + return httpRule.getGet(); case PUT: - pattern = httpRule.getPut(); - break; + return httpRule.getPut(); case POST: - pattern = httpRule.getPost(); - break; + return httpRule.getPost(); case DELETE: - pattern = httpRule.getDelete(); - break; + return httpRule.getDelete(); case PATCH: - pattern = httpRule.getPatch(); - break; + return httpRule.getPatch(); case CUSTOM: // Invalid pattern. // Fall through. default: - return Collections.emptySet(); + return ""; + } + } + + private static ImmutableSortedSet.Builder getPatternBindings(String pattern) { + ImmutableSortedSet.Builder bindings = ImmutableSortedSet.naturalOrder(); + if (pattern.isEmpty()) { + return bindings; } PathTemplate template = PathTemplate.create(pattern); - Set bindings = - new HashSet( - // Filter out any unbound variable like "$0, $1, etc. - template.vars().stream().filter(s -> !s.contains("$")).collect(Collectors.toList())); + // Filter out any unbound variable like "$0, $1, etc. + bindings.addAll( + template.vars().stream().filter(s -> !s.contains("$")).collect(Collectors.toSet())); return bindings; } diff --git a/src/main/java/com/google/api/generator/gapic/protoparser/Parser.java b/src/main/java/com/google/api/generator/gapic/protoparser/Parser.java index fee1587c49..19a92ef6d9 100644 --- a/src/main/java/com/google/api/generator/gapic/protoparser/Parser.java +++ b/src/main/java/com/google/api/generator/gapic/protoparser/Parser.java @@ -24,6 +24,7 @@ import com.google.api.generator.gapic.model.GapicLanguageSettings; import com.google.api.generator.gapic.model.GapicLroRetrySettings; import com.google.api.generator.gapic.model.GapicServiceConfig; +import com.google.api.generator.gapic.model.HttpRuleBindings; import com.google.api.generator.gapic.model.LongrunningOperation; import com.google.api.generator.gapic.model.Message; import com.google.api.generator.gapic.model.Method; @@ -31,6 +32,7 @@ import com.google.api.generator.gapic.model.ResourceReference; import com.google.api.generator.gapic.model.Service; import com.google.api.generator.gapic.model.SourceCodeInfoLocation; +import com.google.api.generator.gapic.model.Transport; import com.google.api.generator.gapic.utils.ResourceNameConstants; import com.google.common.annotations.VisibleForTesting; import com.google.common.base.Preconditions; @@ -103,6 +105,7 @@ public static GapicContext parse(CodeGeneratorRequest request) { GapicLroRetrySettingsParser.parse(gapicYamlConfigPathOpt); Optional languageSettingsOpt = GapicLanguageSettingsParser.parse(gapicYamlConfigPathOpt); + Optional transportOpt = PluginArgumentParser.parseTransport(request); boolean willGenerateMetadata = PluginArgumentParser.hasMetadataFlag(request); @@ -183,6 +186,7 @@ public static GapicContext parse(CodeGeneratorRequest request) { .setServiceConfig(serviceConfigOpt.isPresent() ? serviceConfigOpt.get() : null) .setGapicMetadataEnabled(willGenerateMetadata) .setServiceYamlProto(serviceYamlProtoOpt.isPresent() ? serviceYamlProtoOpt.get() : null) + .setTransport(Transport.parse(transportOpt.orElse(Transport.GRPC.toString()))) .build(); } @@ -484,7 +488,7 @@ private static boolean isMapType(Descriptor messageDescriptor) { * Populates ResourceName objects in Message POJOs. * * @param messageTypes A map of the message type name (as in the protobuf) to Message POJOs. - * @param resourceNames A list of ResourceName POJOs. + * @param resources A list of ResourceName POJOs. * @return The updated messageTypes map. */ public static Map updateResourceNamesInMessages( @@ -557,10 +561,7 @@ static List parseMethods( Preconditions.checkNotNull( inputMessage, String.format("No message found for %s", inputType.reference().simpleName())); - Optional> httpBindingsOpt = - HttpRuleParser.parseHttpBindings(protoMethod, inputMessage, messageTypes); - List httpBindings = - httpBindingsOpt.isPresent() ? httpBindingsOpt.get() : Collections.emptyList(); + HttpRuleBindings httpBindings = HttpRuleParser.parse(protoMethod, inputMessage, messageTypes); boolean isBatching = !serviceConfigOpt.isPresent() ? false diff --git a/src/main/java/com/google/api/generator/gapic/protoparser/PluginArgumentParser.java b/src/main/java/com/google/api/generator/gapic/protoparser/PluginArgumentParser.java index 53cd0f32f3..d5a7de1f79 100644 --- a/src/main/java/com/google/api/generator/gapic/protoparser/PluginArgumentParser.java +++ b/src/main/java/com/google/api/generator/gapic/protoparser/PluginArgumentParser.java @@ -30,6 +30,7 @@ public class PluginArgumentParser { @VisibleForTesting static final String KEY_GAPIC_CONFIG = "gapic-config"; @VisibleForTesting static final String KEY_METADATA = "metadata"; @VisibleForTesting static final String KEY_SERVICE_YAML_CONFIG = "api-service-config"; + @VisibleForTesting static final String KEY_TRANSPORT = "transport"; private static final String JSON_FILE_ENDING = "grpc_service_config.json"; private static final String GAPIC_YAML_FILE_ENDING = "gapic.yaml"; @@ -47,6 +48,10 @@ static Optional parseServiceYamlConfigPath(CodeGeneratorRequest request) return parseServiceYamlConfigPath(request.getParameter()); } + static Optional parseTransport(CodeGeneratorRequest request) { + return parseConfigArgument(request.getParameter(), KEY_TRANSPORT); + } + static boolean hasMetadataFlag(CodeGeneratorRequest request) { return hasMetadataFlag(request.getParameter()); } @@ -54,17 +59,33 @@ static boolean hasMetadataFlag(CodeGeneratorRequest request) { /** Expects a comma-separated list of file paths. */ @VisibleForTesting static Optional parseJsonConfigPath(String pluginProtocArgument) { - return parseArgument(pluginProtocArgument, KEY_GRPC_SERVICE_CONFIG, JSON_FILE_ENDING); + return parseFileArgument(pluginProtocArgument, KEY_GRPC_SERVICE_CONFIG, JSON_FILE_ENDING); } @VisibleForTesting static Optional parseGapicYamlConfigPath(String pluginProtocArgument) { - return parseArgument(pluginProtocArgument, KEY_GAPIC_CONFIG, GAPIC_YAML_FILE_ENDING); + return parseFileArgument(pluginProtocArgument, KEY_GAPIC_CONFIG, GAPIC_YAML_FILE_ENDING); } @VisibleForTesting static Optional parseServiceYamlConfigPath(String pluginProtocArgument) { - return parseArgument(pluginProtocArgument, KEY_SERVICE_YAML_CONFIG, SERVICE_YAML_FILE_ENDING); + return parseFileArgument( + pluginProtocArgument, KEY_SERVICE_YAML_CONFIG, SERVICE_YAML_FILE_ENDING); + } + + @VisibleForTesting + private static Optional parseConfigArgument(String pluginProtocArgument, String key) { + if (Strings.isNullOrEmpty(pluginProtocArgument)) { + return Optional.empty(); + } + + for (String argComponent : pluginProtocArgument.split(COMMA)) { + String[] args = argComponent.trim().split(EQUALS); + if (args.length == 2 && key.equals(args[0])) { + return Optional.of(args[1]); + } + } + return Optional.empty(); } @VisibleForTesting @@ -72,10 +93,10 @@ static boolean hasMetadataFlag(String pluginProtocArgument) { return Arrays.stream(pluginProtocArgument.split(COMMA)).anyMatch(s -> s.equals(KEY_METADATA)); } - private static Optional parseArgument( + private static Optional parseFileArgument( String pluginProtocArgument, String key, String fileEnding) { if (Strings.isNullOrEmpty(pluginProtocArgument)) { - return Optional.empty(); + return Optional.empty(); } for (String argComponent : pluginProtocArgument.split(COMMA)) { String[] args = argComponent.trim().split(EQUALS); @@ -93,6 +114,6 @@ private static Optional parseArgument( return Optional.of(valueVal); } } - return Optional.empty(); + return Optional.empty(); } } diff --git a/src/test/java/com/google/api/generator/gapic/composer/BUILD.bazel b/src/test/java/com/google/api/generator/gapic/composer/BUILD.bazel index b243a6e012..464063194c 100644 --- a/src/test/java/com/google/api/generator/gapic/composer/BUILD.bazel +++ b/src/test/java/com/google/api/generator/gapic/composer/BUILD.bazel @@ -4,26 +4,10 @@ load("//:rules_bazel/java/java_diff_test.bzl", "golden_update") package(default_visibility = ["//visibility:public"]) UPDATE_GOLDENS_TESTS = [ - "BatchingDescriptorComposerTest", "ComposerTest", - "GrpcServiceCallableFactoryClassComposerTest", - "GrpcServiceStubClassComposerTest", - "MockServiceClassComposerTest", - "MockServiceImplClassComposerTest", - "ServiceClientClassComposerTest", - "ServiceClientTestClassComposerTest", - "ServiceSettingsClassComposerTest", - "ServiceStubSettingsClassComposerTest", - "ServiceStubClassComposerTest", ] -COMMON_SRCS = [ - "TestProtoLoaderUtil.java", -] - -TESTS = UPDATE_GOLDENS_TESTS + [ - "RetrySettingsComposerTest", -] +TESTS = UPDATE_GOLDENS_TESTS TEST_DEPS = [ ":common_resources_java_proto", @@ -41,7 +25,6 @@ TEST_DEPS = [ "//src/test/java/com/google/api/generator/gapic/testdata:deprecated_service_java_proto", "//src/test/java/com/google/api/generator/gapic/testdata:showcase_java_proto", "//src/test/java/com/google/api/generator/gapic/testdata:testgapic_java_proto", - "//src/test/java/com/google/api/generator/gapic/composer/constants", "@com_google_api_api_common//jar", "@com_google_api_gax_java//gax", "@com_google_api_api_common", @@ -77,7 +60,7 @@ java_proto_library( name = test_name, srcs = [ "{0}.java".format(test_name), - ] + COMMON_SRCS, + ], data = [ "//src/test/java/com/google/api/generator/gapic/composer/goldens:goldens_files", "//src/test/java/com/google/api/generator/gapic/testdata:gapic_config_files", @@ -87,7 +70,6 @@ java_proto_library( deps = TEST_DEPS, ) for test_name in TESTS] -TEST_CLASS_DIR = "com.google.api.generator.gapic.composer." # Run `bazel run src/test/java/com/google/api/generator/gapic/composer:testTargetName_update` # to update goldens as expected generated code. # `ServiceClient*` tests are not supported now since they are still in active development. @@ -96,7 +78,7 @@ TEST_CLASS_DIR = "com.google.api.generator.gapic.composer." name = "{0}_update".format(test_name), srcs = [ "{0}.java".format(test_name), - ] + COMMON_SRCS, + ], data = [ "//src/test/java/com/google/api/generator/gapic/composer/goldens:goldens_files", "//src/test/java/com/google/api/generator/gapic/testdata:gapic_config_files", diff --git a/src/test/java/com/google/api/generator/gapic/composer/ComposerTest.java b/src/test/java/com/google/api/generator/gapic/composer/ComposerTest.java index d033c94f49..d4ceeabce2 100644 --- a/src/test/java/com/google/api/generator/gapic/composer/ComposerTest.java +++ b/src/test/java/com/google/api/generator/gapic/composer/ComposerTest.java @@ -17,7 +17,6 @@ import com.google.api.generator.engine.ast.ClassDefinition; import com.google.api.generator.engine.ast.ScopeNode; import com.google.api.generator.engine.writer.JavaWriterVisitor; -import com.google.api.generator.gapic.composer.constants.ComposerConstants; import com.google.api.generator.gapic.model.GapicClass; import com.google.api.generator.gapic.model.GapicClass.Kind; import com.google.api.generator.test.framework.Assert; @@ -43,7 +42,7 @@ public void gapicClass_addApacheLicense() { gapicClassWithHeaderList.get(0).classDefinition().accept(visitor); Utils.saveCodegenToFile(this.getClass(), "ComposerPostProcOnFooBar.golden", visitor.write()); Path goldenFilePath = - Paths.get(ComposerConstants.GOLDENFILES_DIRECTORY, "ComposerPostProcOnFooBar.golden"); + Paths.get(Utils.getGoldenDir(this.getClass()), "ComposerPostProcOnFooBar.golden"); Assert.assertCodeEquals(goldenFilePath, visitor.write()); } } diff --git a/src/test/java/com/google/api/generator/gapic/composer/common/BUILD.bazel b/src/test/java/com/google/api/generator/gapic/composer/common/BUILD.bazel new file mode 100644 index 0000000000..be31f815b3 --- /dev/null +++ b/src/test/java/com/google/api/generator/gapic/composer/common/BUILD.bazel @@ -0,0 +1,100 @@ +load("@rules_java//java:defs.bzl", "java_proto_library", "java_test") +load("//:rules_bazel/java/java_diff_test.bzl", "golden_update") + +package(default_visibility = ["//visibility:public"]) + +UPDATE_GOLDENS_TESTS = [ + "BatchingDescriptorComposerTest", + "ServiceClientClassComposerTest", + "ServiceStubClassComposerTest", +] + +TESTS = UPDATE_GOLDENS_TESTS + [ + "RetrySettingsComposerTest", +] + +TEST_DEPS = [ + ":common_resources_java_proto", + "//:service_config_java_proto", + "//src/main/java/com/google/api/generator/engine/ast", + "//src/main/java/com/google/api/generator/engine/writer", + "//src/main/java/com/google/api/generator/gapic/composer", + "//src/main/java/com/google/api/generator/gapic/composer/common", + "//src/test/java/com/google/api/generator/test/framework:asserts", + "//src/test/java/com/google/api/generator/test/framework:utils", + "//src/main/java/com/google/api/generator/gapic/composer/samplecode", + "//src/test/java/com/google/api/generator/testutils", + "//src/main/java/com/google/api/generator/gapic/model", + "//src/main/java/com/google/api/generator/gapic/protoparser", + "//src/main/java/com/google/api/generator/gapic/composer/defaultvalue", + "//src/test/java/com/google/api/generator/gapic/testdata:deprecated_service_java_proto", + "//src/test/java/com/google/api/generator/gapic/testdata:showcase_java_proto", + "//src/test/java/com/google/api/generator/gapic/testdata:testgapic_java_proto", + "@com_google_api_api_common//jar", + "@com_google_api_gax_java//gax", + "@com_google_api_api_common", + "@com_google_googleapis//google/logging/v2:logging_java_proto", + "@com_google_googleapis//google/pubsub/v1:pubsub_java_proto", + "@com_google_googleapis//google/rpc:rpc_java_proto", + "@com_google_guava_guava", + "@com_google_protobuf//:protobuf_java", + "@com_google_truth_truth//jar", + "@junit_junit//jar", +] + +java_library( + name = "common", + srcs = ["TestProtoLoader.java"], + deps = TEST_DEPS, +) + +filegroup( + name = "common_files", + srcs = glob(["*.java"]), +) + +java_proto_library( + name = "pubsub_java_proto", + deps = [ + "@com_google_googleapis//google/pubsub/v1:pubsub_proto", + ], +) + +java_proto_library( + name = "common_resources_java_proto", + deps = [ + "@com_google_googleapis//google/cloud:common_resources_proto", + ], +) + +[java_test( + name = test_name, + srcs = [ + "{0}.java".format(test_name), + ], + data = [ + "//src/test/java/com/google/api/generator/gapic/composer/common/goldens:goldens_files", + "//src/test/java/com/google/api/generator/gapic/testdata:gapic_config_files", + "//src/test/java/com/google/api/generator/gapic/testdata:service_config_files", + ], + test_class = "com.google.api.generator.gapic.composer.common.{0}".format(test_name), + deps = TEST_DEPS + [":common"], +) for test_name in TESTS] + +# Run `bazel run src/test/java/com/google/api/generator/gapic/composer/common:testTargetName_update` +# to update goldens as expected generated code. +# `ServiceClient*` tests are not supported now since they are still in active development. + +[golden_update( + name = "{0}_update".format(test_name), + srcs = [ + "{0}.java".format(test_name), + ], + data = [ + "//src/test/java/com/google/api/generator/gapic/composer/common/goldens:goldens_files", + "//src/test/java/com/google/api/generator/gapic/testdata:gapic_config_files", + "//src/test/java/com/google/api/generator/gapic/testdata:service_config_files", + ], + test_class = "com.google.api.generator.gapic.composer.common.{0}".format(test_name), + deps = TEST_DEPS + [":common"], +) for test_name in UPDATE_GOLDENS_TESTS] diff --git a/src/test/java/com/google/api/generator/gapic/composer/BatchingDescriptorComposerTest.java b/src/test/java/com/google/api/generator/gapic/composer/common/BatchingDescriptorComposerTest.java similarity index 92% rename from src/test/java/com/google/api/generator/gapic/composer/BatchingDescriptorComposerTest.java rename to src/test/java/com/google/api/generator/gapic/composer/common/BatchingDescriptorComposerTest.java index 1d674d9fdb..f2ac7a5da5 100644 --- a/src/test/java/com/google/api/generator/gapic/composer/BatchingDescriptorComposerTest.java +++ b/src/test/java/com/google/api/generator/gapic/composer/common/BatchingDescriptorComposerTest.java @@ -12,14 +12,13 @@ // See the License for the specific language governing permissions and // limitations under the License. -package com.google.api.generator.gapic.composer; +package com.google.api.generator.gapic.composer.common; import static junit.framework.Assert.assertEquals; import static junit.framework.Assert.assertTrue; import com.google.api.generator.engine.ast.Expr; import com.google.api.generator.engine.writer.JavaWriterVisitor; -import com.google.api.generator.gapic.composer.constants.ComposerConstants; import com.google.api.generator.gapic.model.GapicBatchingSettings; import com.google.api.generator.gapic.model.GapicServiceConfig; import com.google.api.generator.gapic.model.Message; @@ -82,13 +81,13 @@ public void batchingDescriptor_hasSubresponseField() { outputResourceNames); String filename = "pubsub_gapic.yaml"; - Path path = Paths.get(ComposerConstants.TESTFILES_DIRECTORY, filename); + Path path = Paths.get(TestProtoLoader.instance().getTestFilesDirectory(), filename); Optional> batchingSettingsOpt = BatchingSettingsConfigParser.parse(Optional.of(path.toString())); assertTrue(batchingSettingsOpt.isPresent()); String jsonFilename = "pubsub_grpc_service_config.json"; - Path jsonPath = Paths.get(ComposerConstants.TESTFILES_DIRECTORY, jsonFilename); + Path jsonPath = Paths.get(TestProtoLoader.instance().getTestFilesDirectory(), jsonFilename); Optional configOpt = ServiceConfigParser.parse(jsonPath.toString()); assertTrue(configOpt.isPresent()); GapicServiceConfig config = configOpt.get(); @@ -109,7 +108,7 @@ public void batchingDescriptor_hasSubresponseField() { this.getClass(), "BatchingDescriptorComposerTestSubresponse.golden", writerVisitor.write()); Path goldenFilePath = Paths.get( - ComposerConstants.GOLDENFILES_DIRECTORY, + Utils.getGoldenDir(this.getClass()), "BatchingDescriptorComposerTestSubresponse.golden"); Assert.assertCodeEquals(goldenFilePath, writerVisitor.write()); } @@ -144,13 +143,13 @@ public void batchingDescriptor_noSubresponseField() { outputResourceNames); String filename = "logging_gapic.yaml"; - Path path = Paths.get(ComposerConstants.TESTFILES_DIRECTORY, filename); + Path path = Paths.get(TestProtoLoader.instance().getTestFilesDirectory(), filename); Optional> batchingSettingsOpt = BatchingSettingsConfigParser.parse(Optional.of(path.toString())); assertTrue(batchingSettingsOpt.isPresent()); String jsonFilename = "logging_grpc_service_config.json"; - Path jsonPath = Paths.get(ComposerConstants.TESTFILES_DIRECTORY, jsonFilename); + Path jsonPath = Paths.get(TestProtoLoader.instance().getTestFilesDirectory(), jsonFilename); Optional configOpt = ServiceConfigParser.parse(jsonPath.toString()); assertTrue(configOpt.isPresent()); GapicServiceConfig config = configOpt.get(); @@ -173,7 +172,7 @@ public void batchingDescriptor_noSubresponseField() { writerVisitor.write()); Path goldenFilePath = Paths.get( - ComposerConstants.GOLDENFILES_DIRECTORY, + Utils.getGoldenDir(this.getClass()), "BatchingDescriptorComposerTestNoSubresponse.golden"); Assert.assertCodeEquals(goldenFilePath, writerVisitor.write()); } diff --git a/src/test/java/com/google/api/generator/gapic/composer/RetrySettingsComposerTest.java b/src/test/java/com/google/api/generator/gapic/composer/common/RetrySettingsComposerTest.java similarity index 94% rename from src/test/java/com/google/api/generator/gapic/composer/RetrySettingsComposerTest.java rename to src/test/java/com/google/api/generator/gapic/composer/common/RetrySettingsComposerTest.java index 1344230b8a..09b1bf5b1c 100644 --- a/src/test/java/com/google/api/generator/gapic/composer/RetrySettingsComposerTest.java +++ b/src/test/java/com/google/api/generator/gapic/composer/common/RetrySettingsComposerTest.java @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -package com.google.api.generator.gapic.composer; +package com.google.api.generator.gapic.composer.common; import static com.google.common.truth.Truth.assertThat; import static junit.framework.Assert.assertEquals; @@ -27,7 +27,6 @@ import com.google.api.generator.engine.ast.Variable; import com.google.api.generator.engine.ast.VariableExpr; import com.google.api.generator.engine.writer.JavaWriterVisitor; -import com.google.api.generator.gapic.composer.constants.ComposerConstants; import com.google.api.generator.gapic.model.GapicBatchingSettings; import com.google.api.generator.gapic.model.GapicContext; import com.google.api.generator.gapic.model.GapicServiceConfig; @@ -71,11 +70,11 @@ public void setUp() { @Test public void paramDefinitionsBlock_noConfigsFound() { - GapicContext context = TestProtoLoaderUtil.parseShowcaseEcho(); + GapicContext context = TestProtoLoader.instance().parseShowcaseEcho(); Service service = context.services().get(0); String jsonFilename = "retrying_grpc_service_config.json"; - Path jsonPath = Paths.get(ComposerConstants.TESTFILES_DIRECTORY, jsonFilename); + Path jsonPath = Paths.get(TestProtoLoader.instance().getTestFilesDirectory(), jsonFilename); Optional serviceConfigOpt = ServiceConfigParser.parse(jsonPath.toString()); assertTrue(serviceConfigOpt.isPresent()); GapicServiceConfig serviceConfig = serviceConfigOpt.get(); @@ -99,11 +98,11 @@ public void paramDefinitionsBlock_noConfigsFound() { @Test public void paramDefinitionsBlock_basic() { - GapicContext context = TestProtoLoaderUtil.parseShowcaseEcho(); + GapicContext context = TestProtoLoader.instance().parseShowcaseEcho(); Service service = context.services().get(0); String jsonFilename = "showcase_grpc_service_config.json"; - Path jsonPath = Paths.get(ComposerConstants.TESTFILES_DIRECTORY, jsonFilename); + Path jsonPath = Paths.get(TestProtoLoader.instance().getTestFilesDirectory(), jsonFilename); Optional serviceConfigOpt = ServiceConfigParser.parse(jsonPath.toString()); assertTrue(serviceConfigOpt.isPresent()); GapicServiceConfig serviceConfig = serviceConfigOpt.get(); @@ -154,7 +153,7 @@ public void codesDefinitionsBlock_noConfigsFound() { Service service = services.get(0); String jsonFilename = "retrying_grpc_service_config.json"; - Path jsonPath = Paths.get(ComposerConstants.TESTFILES_DIRECTORY, jsonFilename); + Path jsonPath = Paths.get(TestProtoLoader.instance().getTestFilesDirectory(), jsonFilename); Optional serviceConfigOpt = ServiceConfigParser.parse(jsonPath.toString()); assertTrue(serviceConfigOpt.isPresent()); GapicServiceConfig serviceConfig = serviceConfigOpt.get(); @@ -191,7 +190,7 @@ public void codesDefinitionsBlock_basic() { Service service = services.get(0); String jsonFilename = "showcase_grpc_service_config.json"; - Path jsonPath = Paths.get(ComposerConstants.TESTFILES_DIRECTORY, jsonFilename); + Path jsonPath = Paths.get(TestProtoLoader.instance().getTestFilesDirectory(), jsonFilename); Optional serviceConfigOpt = ServiceConfigParser.parse(jsonPath.toString()); assertTrue(serviceConfigOpt.isPresent()); GapicServiceConfig serviceConfig = serviceConfigOpt.get(); @@ -231,7 +230,7 @@ public void simpleBuilderExpr_basic() { Service service = services.get(0); String jsonFilename = "showcase_grpc_service_config.json"; - Path jsonPath = Paths.get(ComposerConstants.TESTFILES_DIRECTORY, jsonFilename); + Path jsonPath = Paths.get(TestProtoLoader.instance().getTestFilesDirectory(), jsonFilename); Optional serviceConfigOpt = ServiceConfigParser.parse(jsonPath.toString()); assertTrue(serviceConfigOpt.isPresent()); GapicServiceConfig serviceConfig = serviceConfigOpt.get(); @@ -313,7 +312,7 @@ public void lroBuilderExpr() { Service service = services.get(0); String jsonFilename = "showcase_grpc_service_config.json"; - Path jsonPath = Paths.get(ComposerConstants.TESTFILES_DIRECTORY, jsonFilename); + Path jsonPath = Paths.get(TestProtoLoader.instance().getTestFilesDirectory(), jsonFilename); Optional serviceConfigOpt = ServiceConfigParser.parse(jsonPath.toString()); assertTrue(serviceConfigOpt.isPresent()); GapicServiceConfig serviceConfig = serviceConfigOpt.get(); @@ -354,19 +353,19 @@ public void lroBuilderExpr() { @Test public void batchingSettings_minimalFlowControlSettings() { String filename = "pubsub_gapic.yaml"; - Path path = Paths.get(ComposerConstants.TESTFILES_DIRECTORY, filename); + Path path = Paths.get(TestProtoLoader.instance().getTestFilesDirectory(), filename); Optional> batchingSettingsOpt = BatchingSettingsConfigParser.parse(Optional.of(path.toString())); assertTrue(batchingSettingsOpt.isPresent()); String jsonFilename = "pubsub_grpc_service_config.json"; - Path jsonPath = Paths.get(ComposerConstants.TESTFILES_DIRECTORY, jsonFilename); + Path jsonPath = Paths.get(TestProtoLoader.instance().getTestFilesDirectory(), jsonFilename); Optional configOpt = ServiceConfigParser.parse(jsonPath.toString()); assertTrue(configOpt.isPresent()); GapicServiceConfig config = configOpt.get(); config.setBatchingSettings(batchingSettingsOpt); - GapicContext context = TestProtoLoaderUtil.parsePubSubPublisher(); + GapicContext context = TestProtoLoader.instance().parsePubSubPublisher(); Service service = context.services().get(0); assertEquals("Publisher", service.name()); @@ -408,19 +407,19 @@ public void batchingSettings_minimalFlowControlSettings() { @Test public void batchingSettings_fullFlowControlSettings() { String filename = "logging_gapic.yaml"; - Path path = Paths.get(ComposerConstants.TESTFILES_DIRECTORY, filename); + Path path = Paths.get(TestProtoLoader.instance().getTestFilesDirectory(), filename); Optional> batchingSettingsOpt = BatchingSettingsConfigParser.parse(Optional.of(path.toString())); assertTrue(batchingSettingsOpt.isPresent()); String jsonFilename = "logging_grpc_service_config.json"; - Path jsonPath = Paths.get(ComposerConstants.TESTFILES_DIRECTORY, jsonFilename); + Path jsonPath = Paths.get(TestProtoLoader.instance().getTestFilesDirectory(), jsonFilename); Optional configOpt = ServiceConfigParser.parse(jsonPath.toString()); assertTrue(configOpt.isPresent()); GapicServiceConfig config = configOpt.get(); config.setBatchingSettings(batchingSettingsOpt); - GapicContext context = TestProtoLoaderUtil.parseLogging(); + GapicContext context = TestProtoLoader.instance().parseLogging(); Service service = context.services().get(0); assertEquals("LoggingServiceV2", service.name()); diff --git a/src/test/java/com/google/api/generator/gapic/composer/ServiceClientClassComposerTest.java b/src/test/java/com/google/api/generator/gapic/composer/common/ServiceClientClassComposerTest.java similarity index 80% rename from src/test/java/com/google/api/generator/gapic/composer/ServiceClientClassComposerTest.java rename to src/test/java/com/google/api/generator/gapic/composer/common/ServiceClientClassComposerTest.java index 6c59d4c066..3510efaf3f 100644 --- a/src/test/java/com/google/api/generator/gapic/composer/ServiceClientClassComposerTest.java +++ b/src/test/java/com/google/api/generator/gapic/composer/common/ServiceClientClassComposerTest.java @@ -12,12 +12,11 @@ // See the License for the specific language governing permissions and // limitations under the License. -package com.google.api.generator.gapic.composer; +package com.google.api.generator.gapic.composer.common; import static com.google.api.generator.test.framework.Assert.assertCodeEquals; import com.google.api.generator.engine.writer.JavaWriterVisitor; -import com.google.api.generator.gapic.composer.constants.ComposerConstants; import com.google.api.generator.gapic.model.GapicClass; import com.google.api.generator.gapic.model.GapicContext; import com.google.api.generator.gapic.model.Service; @@ -29,20 +28,20 @@ public class ServiceClientClassComposerTest { @Test public void generateServiceClasses() { - GapicContext context = TestProtoLoaderUtil.parseShowcaseEcho(); + GapicContext context = TestProtoLoader.instance().parseShowcaseEcho(); Service echoProtoService = context.services().get(0); GapicClass clazz = ServiceClientClassComposer.instance().generate(context, echoProtoService); JavaWriterVisitor visitor = new JavaWriterVisitor(); clazz.classDefinition().accept(visitor); Utils.saveCodegenToFile(this.getClass(), "EchoClient.golden", visitor.write()); - Path goldenFilePath = Paths.get(ComposerConstants.GOLDENFILES_DIRECTORY, "EchoClient.golden"); + Path goldenFilePath = Paths.get(Utils.getGoldenDir(this.getClass()), "EchoClient.golden"); assertCodeEquals(goldenFilePath, visitor.write()); } @Test public void generateServiceClasses_deprecated() { - GapicContext context = TestProtoLoaderUtil.parseDeprecatedService(); + GapicContext context = TestProtoLoader.instance().parseDeprecatedService(); Service protoService = context.services().get(0); GapicClass clazz = ServiceClientClassComposer.instance().generate(context, protoService); @@ -50,13 +49,13 @@ public void generateServiceClasses_deprecated() { clazz.classDefinition().accept(visitor); Utils.saveCodegenToFile(this.getClass(), "DeprecatedServiceClient.golden", visitor.write()); Path goldenFilePath = - Paths.get(ComposerConstants.GOLDENFILES_DIRECTORY, "DeprecatedServiceClient.golden"); + Paths.get(Utils.getGoldenDir(this.getClass()), "DeprecatedServiceClient.golden"); assertCodeEquals(goldenFilePath, visitor.write()); } @Test public void generateServiceClasses_methodSignatureHasNestedFields() { - GapicContext context = TestProtoLoaderUtil.parseShowcaseIdentity(); + GapicContext context = TestProtoLoader.instance().parseShowcaseIdentity(); Service protoService = context.services().get(0); GapicClass clazz = ServiceClientClassComposer.instance().generate(context, protoService); @@ -64,7 +63,7 @@ public void generateServiceClasses_methodSignatureHasNestedFields() { clazz.classDefinition().accept(visitor); Utils.saveCodegenToFile(this.getClass(), "IdentityClient.golden", visitor.write()); Path goldenFilePath = - Paths.get(ComposerConstants.GOLDENFILES_DIRECTORY, "IdentityClient.golden"); + Paths.get(Utils.getGoldenDir(this.getClass()), "IdentityClient.golden"); assertCodeEquals(goldenFilePath, visitor.write()); } } diff --git a/src/test/java/com/google/api/generator/gapic/composer/ServiceStubClassComposerTest.java b/src/test/java/com/google/api/generator/gapic/composer/common/ServiceStubClassComposerTest.java similarity index 81% rename from src/test/java/com/google/api/generator/gapic/composer/ServiceStubClassComposerTest.java rename to src/test/java/com/google/api/generator/gapic/composer/common/ServiceStubClassComposerTest.java index 739f806d9c..b30ce3630c 100644 --- a/src/test/java/com/google/api/generator/gapic/composer/ServiceStubClassComposerTest.java +++ b/src/test/java/com/google/api/generator/gapic/composer/common/ServiceStubClassComposerTest.java @@ -12,10 +12,9 @@ // See the License for the specific language governing permissions and // limitations under the License. -package com.google.api.generator.gapic.composer; +package com.google.api.generator.gapic.composer.common; import com.google.api.generator.engine.writer.JavaWriterVisitor; -import com.google.api.generator.gapic.composer.constants.ComposerConstants; import com.google.api.generator.gapic.model.GapicClass; import com.google.api.generator.gapic.model.GapicContext; import com.google.api.generator.gapic.model.Service; @@ -28,20 +27,20 @@ public class ServiceStubClassComposerTest { @Test public void generateServiceClasses() { - GapicContext context = TestProtoLoaderUtil.parseShowcaseEcho(); + GapicContext context = TestProtoLoader.instance().parseShowcaseEcho(); Service echoProtoService = context.services().get(0); GapicClass clazz = ServiceStubClassComposer.instance().generate(context, echoProtoService); JavaWriterVisitor visitor = new JavaWriterVisitor(); clazz.classDefinition().accept(visitor); Utils.saveCodegenToFile(this.getClass(), "EchoStub.golden", visitor.write()); - Path goldenFilePath = Paths.get(ComposerConstants.GOLDENFILES_DIRECTORY, "EchoStub.golden"); + Path goldenFilePath = Paths.get(Utils.getGoldenDir(this.getClass()), "EchoStub.golden"); Assert.assertCodeEquals(goldenFilePath, visitor.write()); } @Test public void generateServiceClasses_deprecated() { - GapicContext context = TestProtoLoaderUtil.parseDeprecatedService(); + GapicContext context = TestProtoLoader.instance().parseDeprecatedService(); Service protoService = context.services().get(0); GapicClass clazz = ServiceStubClassComposer.instance().generate(context, protoService); @@ -49,7 +48,7 @@ public void generateServiceClasses_deprecated() { clazz.classDefinition().accept(visitor); Utils.saveCodegenToFile(this.getClass(), "DeprecatedServiceStub.golden", visitor.write()); Path goldenFilePath = - Paths.get(ComposerConstants.GOLDENFILES_DIRECTORY, "DeprecatedServiceStub.golden"); + Paths.get(Utils.getGoldenDir(this.getClass()), "DeprecatedServiceStub.golden"); Assert.assertCodeEquals(goldenFilePath, visitor.write()); } } diff --git a/src/test/java/com/google/api/generator/gapic/composer/TestProtoLoaderUtil.java b/src/test/java/com/google/api/generator/gapic/composer/common/TestProtoLoader.java similarity index 86% rename from src/test/java/com/google/api/generator/gapic/composer/TestProtoLoaderUtil.java rename to src/test/java/com/google/api/generator/gapic/composer/common/TestProtoLoader.java index 88c9360de1..cd7cb34911 100644 --- a/src/test/java/com/google/api/generator/gapic/composer/TestProtoLoaderUtil.java +++ b/src/test/java/com/google/api/generator/gapic/composer/common/TestProtoLoader.java @@ -12,18 +12,18 @@ // See the License for the specific language governing permissions and // limitations under the License. -package com.google.api.generator.gapic.composer; +package com.google.api.generator.gapic.composer.common; import static junit.framework.Assert.assertEquals; import static junit.framework.Assert.assertTrue; -import com.google.api.generator.gapic.composer.constants.ComposerConstants; import com.google.api.generator.gapic.model.GapicBatchingSettings; import com.google.api.generator.gapic.model.GapicContext; import com.google.api.generator.gapic.model.GapicServiceConfig; import com.google.api.generator.gapic.model.Message; import com.google.api.generator.gapic.model.ResourceName; import com.google.api.generator.gapic.model.Service; +import com.google.api.generator.gapic.model.Transport; import com.google.api.generator.gapic.protoparser.BatchingSettingsConfigParser; import com.google.api.generator.gapic.protoparser.Parser; import com.google.api.generator.gapic.protoparser.ServiceConfigParser; @@ -49,8 +49,22 @@ import java.util.Optional; import java.util.Set; -public class TestProtoLoaderUtil { - public static GapicContext parseDeprecatedService() { +public class TestProtoLoader { + private static final TestProtoLoader INSTANCE = + new TestProtoLoader(null, "src/test/java/com/google/api/generator/gapic/testdata/"); + private final Transport transport; + private final String testFilesDirectory; + + protected TestProtoLoader(Transport transport, String testFilesDirectory) { + this.transport = transport; + this.testFilesDirectory = testFilesDirectory; + } + + public static TestProtoLoader instance() { + return INSTANCE; + } + + public GapicContext parseDeprecatedService() { FileDescriptor fileDescriptor = DeprecatedServiceOuterClass.getDescriptor(); ServiceDescriptor serviceDescriptor = fileDescriptor.getServices().get(0); assertEquals(serviceDescriptor.getName(), "DeprecatedService"); @@ -63,7 +77,7 @@ public static GapicContext parseDeprecatedService() { fileDescriptor, messageTypes, resourceNames, Optional.empty(), outputResourceNames); String jsonFilename = "deprecated_service_grpc_service_config.json"; - Path jsonPath = Paths.get(ComposerConstants.TESTFILES_DIRECTORY, jsonFilename); + Path jsonPath = Paths.get(testFilesDirectory, jsonFilename); Optional configOpt = ServiceConfigParser.parse(jsonPath.toString()); assertTrue(configOpt.isPresent()); GapicServiceConfig config = configOpt.get(); @@ -77,7 +91,7 @@ public static GapicContext parseDeprecatedService() { .build(); } - public static GapicContext parseShowcaseEcho() { + public GapicContext parseShowcaseEcho() { FileDescriptor echoFileDescriptor = EchoOuterClass.getDescriptor(); ServiceDescriptor echoServiceDescriptor = echoFileDescriptor.getServices().get(0); assertEquals(echoServiceDescriptor.getName(), "Echo"); @@ -90,7 +104,7 @@ public static GapicContext parseShowcaseEcho() { echoFileDescriptor, messageTypes, resourceNames, Optional.empty(), outputResourceNames); String jsonFilename = "showcase_grpc_service_config.json"; - Path jsonPath = Paths.get(ComposerConstants.TESTFILES_DIRECTORY, jsonFilename); + Path jsonPath = Paths.get(testFilesDirectory, jsonFilename); Optional configOpt = ServiceConfigParser.parse(jsonPath.toString()); assertTrue(configOpt.isPresent()); GapicServiceConfig config = configOpt.get(); @@ -101,10 +115,11 @@ public static GapicContext parseShowcaseEcho() { .setServices(services) .setServiceConfig(config) .setHelperResourceNames(outputResourceNames) + .setTransport(transport) .build(); } - public static GapicContext parseShowcaseIdentity() { + public GapicContext parseShowcaseIdentity() { FileDescriptor fileDescriptor = IdentityOuterClass.getDescriptor(); ServiceDescriptor identityService = fileDescriptor.getServices().get(0); assertEquals(identityService.getName(), "Identity"); @@ -121,10 +136,11 @@ public static GapicContext parseShowcaseIdentity() { .setResourceNames(resourceNames) .setServices(services) .setHelperResourceNames(outputResourceNames) + .setTransport(transport) .build(); } - public static GapicContext parseShowcaseTesting() { + public GapicContext parseShowcaseTesting() { FileDescriptor testingFileDescriptor = TestingOuterClass.getDescriptor(); ServiceDescriptor testingService = testingFileDescriptor.getServices().get(0); assertEquals(testingService.getName(), "Testing"); @@ -145,10 +161,11 @@ public static GapicContext parseShowcaseTesting() { .setResourceNames(resourceNames) .setServices(services) .setHelperResourceNames(outputResourceNames) + .setTransport(transport) .build(); } - public static GapicContext parsePubSubPublisher() { + public GapicContext parsePubSubPublisher() { FileDescriptor serviceFileDescriptor = PubsubProto.getDescriptor(); FileDescriptor commonResourcesFileDescriptor = CommonResources.getDescriptor(); ServiceDescriptor serviceDescriptor = serviceFileDescriptor.getServices().get(0); @@ -169,13 +186,13 @@ public static GapicContext parsePubSubPublisher() { outputResourceNames); String filename = "pubsub_gapic.yaml"; - Path path = Paths.get(ComposerConstants.TESTFILES_DIRECTORY, filename); + Path path = Paths.get(getTestFilesDirectory(), filename); Optional> batchingSettingsOpt = BatchingSettingsConfigParser.parse(Optional.of(path.toString())); assertTrue(batchingSettingsOpt.isPresent()); String jsonFilename = "pubsub_grpc_service_config.json"; - Path jsonPath = Paths.get(ComposerConstants.TESTFILES_DIRECTORY, jsonFilename); + Path jsonPath = Paths.get(getTestFilesDirectory(), jsonFilename); Optional configOpt = ServiceConfigParser.parse(jsonPath.toString()); assertTrue(configOpt.isPresent()); GapicServiceConfig config = configOpt.get(); @@ -187,10 +204,11 @@ public static GapicContext parsePubSubPublisher() { .setServices(services) .setServiceConfig(config) .setHelperResourceNames(outputResourceNames) + .setTransport(transport) .build(); } - public static GapicContext parseLogging() { + public GapicContext parseLogging() { FileDescriptor serviceFileDescriptor = LoggingProto.getDescriptor(); ServiceDescriptor serviceDescriptor = serviceFileDescriptor.getServices().get(0); assertEquals(serviceDescriptor.getName(), "LoggingServiceV2"); @@ -223,13 +241,13 @@ public static GapicContext parseLogging() { outputResourceNames); String filename = "logging_gapic.yaml"; - Path path = Paths.get(ComposerConstants.TESTFILES_DIRECTORY, filename); + Path path = Paths.get(getTestFilesDirectory(), filename); Optional> batchingSettingsOpt = BatchingSettingsConfigParser.parse(Optional.of(path.toString())); assertTrue(batchingSettingsOpt.isPresent()); String jsonFilename = "logging_grpc_service_config.json"; - Path jsonPath = Paths.get(ComposerConstants.TESTFILES_DIRECTORY, jsonFilename); + Path jsonPath = Paths.get(getTestFilesDirectory(), jsonFilename); Optional configOpt = ServiceConfigParser.parse(jsonPath.toString()); assertTrue(configOpt.isPresent()); GapicServiceConfig config = configOpt.get(); @@ -241,6 +259,11 @@ public static GapicContext parseLogging() { .setServices(services) .setServiceConfig(config) .setHelperResourceNames(outputResourceNames) + .setTransport(transport) .build(); } + + public String getTestFilesDirectory() { + return testFilesDirectory; + } } diff --git a/src/test/java/com/google/api/generator/gapic/composer/common/goldens/BUILD.bazel b/src/test/java/com/google/api/generator/gapic/composer/common/goldens/BUILD.bazel new file mode 100644 index 0000000000..85ac1a519e --- /dev/null +++ b/src/test/java/com/google/api/generator/gapic/composer/common/goldens/BUILD.bazel @@ -0,0 +1,6 @@ +package(default_visibility = ["//visibility:public"]) + +filegroup( + name = "goldens_files", + srcs = glob(["*.golden"]), +) diff --git a/src/test/java/com/google/api/generator/gapic/composer/goldens/BatchingDescriptorComposerTestNoSubresponse.golden b/src/test/java/com/google/api/generator/gapic/composer/common/goldens/BatchingDescriptorComposerTestNoSubresponse.golden similarity index 100% rename from src/test/java/com/google/api/generator/gapic/composer/goldens/BatchingDescriptorComposerTestNoSubresponse.golden rename to src/test/java/com/google/api/generator/gapic/composer/common/goldens/BatchingDescriptorComposerTestNoSubresponse.golden diff --git a/src/test/java/com/google/api/generator/gapic/composer/goldens/BatchingDescriptorComposerTestSubresponse.golden b/src/test/java/com/google/api/generator/gapic/composer/common/goldens/BatchingDescriptorComposerTestSubresponse.golden similarity index 100% rename from src/test/java/com/google/api/generator/gapic/composer/goldens/BatchingDescriptorComposerTestSubresponse.golden rename to src/test/java/com/google/api/generator/gapic/composer/common/goldens/BatchingDescriptorComposerTestSubresponse.golden diff --git a/src/test/java/com/google/api/generator/gapic/composer/goldens/DeprecatedServiceClient.golden b/src/test/java/com/google/api/generator/gapic/composer/common/goldens/DeprecatedServiceClient.golden similarity index 100% rename from src/test/java/com/google/api/generator/gapic/composer/goldens/DeprecatedServiceClient.golden rename to src/test/java/com/google/api/generator/gapic/composer/common/goldens/DeprecatedServiceClient.golden diff --git a/src/test/java/com/google/api/generator/gapic/composer/goldens/DeprecatedServiceStub.golden b/src/test/java/com/google/api/generator/gapic/composer/common/goldens/DeprecatedServiceStub.golden similarity index 100% rename from src/test/java/com/google/api/generator/gapic/composer/goldens/DeprecatedServiceStub.golden rename to src/test/java/com/google/api/generator/gapic/composer/common/goldens/DeprecatedServiceStub.golden diff --git a/src/test/java/com/google/api/generator/gapic/composer/goldens/EchoClient.golden b/src/test/java/com/google/api/generator/gapic/composer/common/goldens/EchoClient.golden similarity index 100% rename from src/test/java/com/google/api/generator/gapic/composer/goldens/EchoClient.golden rename to src/test/java/com/google/api/generator/gapic/composer/common/goldens/EchoClient.golden diff --git a/src/test/java/com/google/api/generator/gapic/composer/goldens/EchoStub.golden b/src/test/java/com/google/api/generator/gapic/composer/common/goldens/EchoStub.golden similarity index 100% rename from src/test/java/com/google/api/generator/gapic/composer/goldens/EchoStub.golden rename to src/test/java/com/google/api/generator/gapic/composer/common/goldens/EchoStub.golden diff --git a/src/test/java/com/google/api/generator/gapic/composer/goldens/IdentityClient.golden b/src/test/java/com/google/api/generator/gapic/composer/common/goldens/IdentityClient.golden similarity index 100% rename from src/test/java/com/google/api/generator/gapic/composer/goldens/IdentityClient.golden rename to src/test/java/com/google/api/generator/gapic/composer/common/goldens/IdentityClient.golden diff --git a/src/test/java/com/google/api/generator/gapic/composer/constants/BUILD.bazel b/src/test/java/com/google/api/generator/gapic/composer/constants/BUILD.bazel index c83471c30b..e69de29bb2 100644 --- a/src/test/java/com/google/api/generator/gapic/composer/constants/BUILD.bazel +++ b/src/test/java/com/google/api/generator/gapic/composer/constants/BUILD.bazel @@ -1,13 +0,0 @@ -load("@rules_java//java:defs.bzl", "java_binary") - -package(default_visibility = ["//visibility:public"]) - -filegroup( - name = "constants_files", - srcs = glob(["*.java"]), -) - -java_binary( - name = "constants", - srcs = ["constants_files"], -) diff --git a/src/test/java/com/google/api/generator/gapic/composer/grpc/BUILD.bazel b/src/test/java/com/google/api/generator/gapic/composer/grpc/BUILD.bazel new file mode 100644 index 0000000000..4ac8e2b387 --- /dev/null +++ b/src/test/java/com/google/api/generator/gapic/composer/grpc/BUILD.bazel @@ -0,0 +1,100 @@ +load("@rules_java//java:defs.bzl", "java_proto_library", "java_test") +load("//:rules_bazel/java/java_diff_test.bzl", "golden_update") + +package(default_visibility = ["//visibility:public"]) + +TESTS = [ + "GrpcServiceCallableFactoryClassComposerTest", + "GrpcServiceStubClassComposerTest", + "MockServiceClassComposerTest", + "MockServiceImplClassComposerTest", + "ServiceClientTestClassComposerTest", + "ServiceSettingsClassComposerTest", + "ServiceStubSettingsClassComposerTest", +] + +COMMON_SRCS = [ + "GrpcTestProtoLoader.java", +] + +TEST_DEPS = [ + ":common_resources_java_proto", + "//:service_config_java_proto", + "//src/main/java/com/google/api/generator/engine/ast", + "//src/main/java/com/google/api/generator/engine/writer", + "//src/main/java/com/google/api/generator/gapic/composer", + "//src/main/java/com/google/api/generator/gapic/composer/common", + "//src/main/java/com/google/api/generator/gapic/composer/grpc", + "//src/test/java/com/google/api/generator/gapic/composer/common", + "//src/test/java/com/google/api/generator/test/framework:asserts", + "//src/test/java/com/google/api/generator/test/framework:utils", + "//src/main/java/com/google/api/generator/gapic/composer/samplecode", + "//src/test/java/com/google/api/generator/testutils", + "//src/main/java/com/google/api/generator/gapic/model", + "//src/main/java/com/google/api/generator/gapic/protoparser", + "//src/main/java/com/google/api/generator/gapic/composer/defaultvalue", + "//src/test/java/com/google/api/generator/gapic/testdata:deprecated_service_java_proto", + "//src/test/java/com/google/api/generator/gapic/testdata:showcase_java_proto", + "//src/test/java/com/google/api/generator/gapic/testdata:testgapic_java_proto", + "@com_google_api_api_common//jar", + "@com_google_api_gax_java//gax", + "@com_google_api_api_common", + "@com_google_googleapis//google/logging/v2:logging_java_proto", + "@com_google_googleapis//google/pubsub/v1:pubsub_java_proto", + "@com_google_googleapis//google/rpc:rpc_java_proto", + "@com_google_guava_guava", + "@com_google_protobuf//:protobuf_java", + "@com_google_truth_truth//jar", + "@junit_junit//jar", +] + +filegroup( + name = "composer_files", + srcs = glob(["*.java"]), +) + +java_proto_library( + name = "pubsub_java_proto", + deps = [ + "@com_google_googleapis//google/pubsub/v1:pubsub_proto", + ], +) + +java_proto_library( + name = "common_resources_java_proto", + deps = [ + "@com_google_googleapis//google/cloud:common_resources_proto", + ], +) + +[java_test( + name = test_name, + srcs = [ + "{0}.java".format(test_name), + ] + COMMON_SRCS, + data = [ + "//src/test/java/com/google/api/generator/gapic/composer/grpc/goldens:goldens_files", + "//src/test/java/com/google/api/generator/gapic/testdata:gapic_config_files", + "//src/test/java/com/google/api/generator/gapic/testdata:service_config_files", + ], + test_class = "com.google.api.generator.gapic.composer.grpc.{0}".format(test_name), + deps = TEST_DEPS, +) for test_name in TESTS] + +# Run `bazel run src/test/java/com/google/api/generator/gapic/composer/grpc:testTargetName_update` +# to update goldens as expected generated code. +# `ServiceClient*` tests are not supported now since they are still in active development. + +[golden_update( + name = "{0}_update".format(test_name), + srcs = [ + "{0}.java".format(test_name), + ] + COMMON_SRCS, + data = [ + "//src/test/java/com/google/api/generator/gapic/composer/grpc/goldens:goldens_files", + "//src/test/java/com/google/api/generator/gapic/testdata:gapic_config_files", + "//src/test/java/com/google/api/generator/gapic/testdata:service_config_files", + ], + test_class = "com.google.api.generator.gapic.composer.grpc.{0}".format(test_name), + deps = TEST_DEPS, +) for test_name in TESTS] diff --git a/src/test/java/com/google/api/generator/gapic/composer/GrpcServiceCallableFactoryClassComposerTest.java b/src/test/java/com/google/api/generator/gapic/composer/grpc/GrpcServiceCallableFactoryClassComposerTest.java similarity index 82% rename from src/test/java/com/google/api/generator/gapic/composer/GrpcServiceCallableFactoryClassComposerTest.java rename to src/test/java/com/google/api/generator/gapic/composer/grpc/GrpcServiceCallableFactoryClassComposerTest.java index 8d0f5f9439..3f90ae955f 100644 --- a/src/test/java/com/google/api/generator/gapic/composer/GrpcServiceCallableFactoryClassComposerTest.java +++ b/src/test/java/com/google/api/generator/gapic/composer/grpc/GrpcServiceCallableFactoryClassComposerTest.java @@ -12,10 +12,9 @@ // See the License for the specific language governing permissions and // limitations under the License. -package com.google.api.generator.gapic.composer; +package com.google.api.generator.gapic.composer.grpc; import com.google.api.generator.engine.writer.JavaWriterVisitor; -import com.google.api.generator.gapic.composer.constants.ComposerConstants; import com.google.api.generator.gapic.model.GapicClass; import com.google.api.generator.gapic.model.GapicContext; import com.google.api.generator.gapic.model.Service; @@ -28,7 +27,7 @@ public class GrpcServiceCallableFactoryClassComposerTest { @Test public void generateServiceClasses() { - GapicContext context = TestProtoLoaderUtil.parseShowcaseEcho(); + GapicContext context = GrpcTestProtoLoader.instance().parseShowcaseEcho(); Service echoProtoService = context.services().get(0); GapicClass clazz = GrpcServiceCallableFactoryClassComposer.instance().generate(context, echoProtoService); @@ -37,13 +36,13 @@ public void generateServiceClasses() { clazz.classDefinition().accept(visitor); Utils.saveCodegenToFile(this.getClass(), "GrpcEchoCallableFactory.golden", visitor.write()); Path goldenFilePath = - Paths.get(ComposerConstants.GOLDENFILES_DIRECTORY, "GrpcEchoCallableFactory.golden"); + Paths.get(Utils.getGoldenDir(this.getClass()), "GrpcEchoCallableFactory.golden"); Assert.assertCodeEquals(goldenFilePath, visitor.write()); } @Test public void generateServiceClasses_deprecated() { - GapicContext context = TestProtoLoaderUtil.parseDeprecatedService(); + GapicContext context = GrpcTestProtoLoader.instance().parseDeprecatedService(); Service protoService = context.services().get(0); GapicClass clazz = GrpcServiceCallableFactoryClassComposer.instance().generate(context, protoService); @@ -54,7 +53,7 @@ public void generateServiceClasses_deprecated() { this.getClass(), "GrpcDeprecatedServiceCallableFactory.golden", visitor.write()); Path goldenFilePath = Paths.get( - ComposerConstants.GOLDENFILES_DIRECTORY, "GrpcDeprecatedServiceCallableFactory.golden"); + Utils.getGoldenDir(this.getClass()), "GrpcDeprecatedServiceCallableFactory.golden"); Assert.assertCodeEquals(goldenFilePath, visitor.write()); } } diff --git a/src/test/java/com/google/api/generator/gapic/composer/GrpcServiceStubClassComposerTest.java b/src/test/java/com/google/api/generator/gapic/composer/grpc/GrpcServiceStubClassComposerTest.java similarity index 79% rename from src/test/java/com/google/api/generator/gapic/composer/GrpcServiceStubClassComposerTest.java rename to src/test/java/com/google/api/generator/gapic/composer/grpc/GrpcServiceStubClassComposerTest.java index 4aa49a2f62..8ccbc442ed 100644 --- a/src/test/java/com/google/api/generator/gapic/composer/GrpcServiceStubClassComposerTest.java +++ b/src/test/java/com/google/api/generator/gapic/composer/grpc/GrpcServiceStubClassComposerTest.java @@ -12,10 +12,9 @@ // See the License for the specific language governing permissions and // limitations under the License. -package com.google.api.generator.gapic.composer; +package com.google.api.generator.gapic.composer.grpc; import com.google.api.generator.engine.writer.JavaWriterVisitor; -import com.google.api.generator.gapic.composer.constants.ComposerConstants; import com.google.api.generator.gapic.model.GapicClass; import com.google.api.generator.gapic.model.GapicContext; import com.google.api.generator.gapic.model.Service; @@ -28,20 +27,20 @@ public class GrpcServiceStubClassComposerTest { @Test public void generateGrpcServiceStubClass_simple() { - GapicContext context = TestProtoLoaderUtil.parseShowcaseEcho(); + GapicContext context = GrpcTestProtoLoader.instance().parseShowcaseEcho(); Service echoProtoService = context.services().get(0); GapicClass clazz = GrpcServiceStubClassComposer.instance().generate(context, echoProtoService); JavaWriterVisitor visitor = new JavaWriterVisitor(); clazz.classDefinition().accept(visitor); Utils.saveCodegenToFile(this.getClass(), "GrpcEchoStub.golden", visitor.write()); - Path goldenFilePath = Paths.get(ComposerConstants.GOLDENFILES_DIRECTORY, "GrpcEchoStub.golden"); + Path goldenFilePath = Paths.get(Utils.getGoldenDir(this.getClass()), "GrpcEchoStub.golden"); Assert.assertCodeEquals(goldenFilePath, visitor.write()); } @Test public void generateGrpcServiceStubClass_deprecated() { - GapicContext context = TestProtoLoaderUtil.parseDeprecatedService(); + GapicContext context = GrpcTestProtoLoader.instance().parseDeprecatedService(); Service protoService = context.services().get(0); GapicClass clazz = GrpcServiceStubClassComposer.instance().generate(context, protoService); @@ -49,13 +48,13 @@ public void generateGrpcServiceStubClass_deprecated() { clazz.classDefinition().accept(visitor); Utils.saveCodegenToFile(this.getClass(), "GrpcDeprecatedServiceStub.golden", visitor.write()); Path goldenFilePath = - Paths.get(ComposerConstants.GOLDENFILES_DIRECTORY, "GrpcDeprecatedServiceStub.golden"); + Paths.get(Utils.getGoldenDir(this.getClass()), "GrpcDeprecatedServiceStub.golden"); Assert.assertCodeEquals(goldenFilePath, visitor.write()); } @Test public void generateGrpcServiceStubClass_httpBindings() { - GapicContext context = TestProtoLoaderUtil.parseShowcaseTesting(); + GapicContext context = GrpcTestProtoLoader.instance().parseShowcaseTesting(); Service testingProtoService = context.services().get(0); GapicClass clazz = GrpcServiceStubClassComposer.instance().generate(context, testingProtoService); @@ -64,13 +63,13 @@ public void generateGrpcServiceStubClass_httpBindings() { clazz.classDefinition().accept(visitor); Utils.saveCodegenToFile(this.getClass(), "GrpcTestingStub.golden", visitor.write()); Path goldenFilePath = - Paths.get(ComposerConstants.GOLDENFILES_DIRECTORY, "GrpcTestingStub.golden"); + Paths.get(Utils.getGoldenDir(this.getClass()), "GrpcTestingStub.golden"); Assert.assertCodeEquals(goldenFilePath, visitor.write()); } @Test public void generateGrpcServiceStubClass_httpBindingsWithSubMessageFields() { - GapicContext context = TestProtoLoaderUtil.parsePubSubPublisher(); + GapicContext context = GrpcTestProtoLoader.instance().parsePubSubPublisher(); Service service = context.services().get(0); GapicClass clazz = GrpcServiceStubClassComposer.instance().generate(context, service); @@ -78,7 +77,7 @@ public void generateGrpcServiceStubClass_httpBindingsWithSubMessageFields() { clazz.classDefinition().accept(visitor); Utils.saveCodegenToFile(this.getClass(), "GrpcPublisherStub.golden", visitor.write()); Path goldenFilePath = - Paths.get(ComposerConstants.GOLDENFILES_DIRECTORY, "GrpcPublisherStub.golden"); + Paths.get(Utils.getGoldenDir(this.getClass()), "GrpcPublisherStub.golden"); Assert.assertCodeEquals(goldenFilePath, visitor.write()); } } diff --git a/src/test/java/com/google/api/generator/gapic/composer/grpc/GrpcTestProtoLoader.java b/src/test/java/com/google/api/generator/gapic/composer/grpc/GrpcTestProtoLoader.java new file mode 100644 index 0000000000..5f6197ed8a --- /dev/null +++ b/src/test/java/com/google/api/generator/gapic/composer/grpc/GrpcTestProtoLoader.java @@ -0,0 +1,30 @@ +// Copyright 2021 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 +// +// http://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. + +package com.google.api.generator.gapic.composer.grpc; + +import com.google.api.generator.gapic.composer.common.TestProtoLoader; +import com.google.api.generator.gapic.model.Transport; + +public class GrpcTestProtoLoader extends TestProtoLoader { + private static GrpcTestProtoLoader INSTANCE = new GrpcTestProtoLoader(); + + protected GrpcTestProtoLoader() { + super(Transport.GRPC, "src/test/java/com/google/api/generator/gapic/testdata/"); + } + + public static GrpcTestProtoLoader instance() { + return INSTANCE; + } +} diff --git a/src/test/java/com/google/api/generator/gapic/composer/MockServiceClassComposerTest.java b/src/test/java/com/google/api/generator/gapic/composer/grpc/MockServiceClassComposerTest.java similarity index 81% rename from src/test/java/com/google/api/generator/gapic/composer/MockServiceClassComposerTest.java rename to src/test/java/com/google/api/generator/gapic/composer/grpc/MockServiceClassComposerTest.java index 5126817fdb..b8f17b5934 100644 --- a/src/test/java/com/google/api/generator/gapic/composer/MockServiceClassComposerTest.java +++ b/src/test/java/com/google/api/generator/gapic/composer/grpc/MockServiceClassComposerTest.java @@ -12,10 +12,9 @@ // See the License for the specific language governing permissions and // limitations under the License. -package com.google.api.generator.gapic.composer; +package com.google.api.generator.gapic.composer.grpc; import com.google.api.generator.engine.writer.JavaWriterVisitor; -import com.google.api.generator.gapic.composer.constants.ComposerConstants; import com.google.api.generator.gapic.model.GapicClass; import com.google.api.generator.gapic.model.GapicContext; import com.google.api.generator.gapic.model.Service; @@ -28,20 +27,20 @@ public class MockServiceClassComposerTest { @Test public void generateServiceClasses() { - GapicContext context = TestProtoLoaderUtil.parseShowcaseEcho(); + GapicContext context = GrpcTestProtoLoader.instance().parseShowcaseEcho(); Service echoProtoService = context.services().get(0); GapicClass clazz = MockServiceClassComposer.instance().generate(context, echoProtoService); JavaWriterVisitor visitor = new JavaWriterVisitor(); clazz.classDefinition().accept(visitor); Utils.saveCodegenToFile(this.getClass(), "MockEcho.golden", visitor.write()); - Path goldenFilePath = Paths.get(ComposerConstants.GOLDENFILES_DIRECTORY, "MockEcho.golden"); + Path goldenFilePath = Paths.get(Utils.getGoldenDir(this.getClass()), "MockEcho.golden"); Assert.assertCodeEquals(goldenFilePath, visitor.write()); } @Test public void generateServiceClasses_deprecated() { - GapicContext context = TestProtoLoaderUtil.parseDeprecatedService(); + GapicContext context = GrpcTestProtoLoader.instance().parseDeprecatedService(); Service protoService = context.services().get(0); GapicClass clazz = MockServiceClassComposer.instance().generate(context, protoService); @@ -49,7 +48,7 @@ public void generateServiceClasses_deprecated() { clazz.classDefinition().accept(visitor); Utils.saveCodegenToFile(this.getClass(), "MockDeprecatedService.golden", visitor.write()); Path goldenFilePath = - Paths.get(ComposerConstants.GOLDENFILES_DIRECTORY, "MockDeprecatedService.golden"); + Paths.get(Utils.getGoldenDir(this.getClass()), "MockDeprecatedService.golden"); Assert.assertCodeEquals(goldenFilePath, visitor.write()); } } diff --git a/src/test/java/com/google/api/generator/gapic/composer/MockServiceImplClassComposerTest.java b/src/test/java/com/google/api/generator/gapic/composer/grpc/MockServiceImplClassComposerTest.java similarity index 81% rename from src/test/java/com/google/api/generator/gapic/composer/MockServiceImplClassComposerTest.java rename to src/test/java/com/google/api/generator/gapic/composer/grpc/MockServiceImplClassComposerTest.java index a4464ad1c5..854d0772dd 100644 --- a/src/test/java/com/google/api/generator/gapic/composer/MockServiceImplClassComposerTest.java +++ b/src/test/java/com/google/api/generator/gapic/composer/grpc/MockServiceImplClassComposerTest.java @@ -12,10 +12,9 @@ // See the License for the specific language governing permissions and // limitations under the License. -package com.google.api.generator.gapic.composer; +package com.google.api.generator.gapic.composer.grpc; import com.google.api.generator.engine.writer.JavaWriterVisitor; -import com.google.api.generator.gapic.composer.constants.ComposerConstants; import com.google.api.generator.gapic.model.GapicClass; import com.google.api.generator.gapic.model.GapicContext; import com.google.api.generator.gapic.model.Service; @@ -28,20 +27,20 @@ public class MockServiceImplClassComposerTest { @Test public void generateServiceClasses() { - GapicContext context = TestProtoLoaderUtil.parseShowcaseEcho(); + GapicContext context = GrpcTestProtoLoader.instance().parseShowcaseEcho(); Service echoProtoService = context.services().get(0); GapicClass clazz = MockServiceImplClassComposer.instance().generate(context, echoProtoService); JavaWriterVisitor visitor = new JavaWriterVisitor(); clazz.classDefinition().accept(visitor); Utils.saveCodegenToFile(this.getClass(), "MockEchoImpl.golden", visitor.write()); - Path goldenFilePath = Paths.get(ComposerConstants.GOLDENFILES_DIRECTORY, "MockEchoImpl.golden"); + Path goldenFilePath = Paths.get(Utils.getGoldenDir(this.getClass()), "MockEchoImpl.golden"); Assert.assertCodeEquals(goldenFilePath, visitor.write()); } @Test public void generateServiceClasses_deprecated() { - GapicContext context = TestProtoLoaderUtil.parseDeprecatedService(); + GapicContext context = GrpcTestProtoLoader.instance().parseDeprecatedService(); Service protoService = context.services().get(0); GapicClass clazz = MockServiceImplClassComposer.instance().generate(context, protoService); @@ -49,7 +48,7 @@ public void generateServiceClasses_deprecated() { clazz.classDefinition().accept(visitor); Utils.saveCodegenToFile(this.getClass(), "MockDeprecatedServiceImpl.golden", visitor.write()); Path goldenFilePath = - Paths.get(ComposerConstants.GOLDENFILES_DIRECTORY, "MockDeprecatedServiceImpl.golden"); + Paths.get(Utils.getGoldenDir(this.getClass()), "MockDeprecatedServiceImpl.golden"); Assert.assertCodeEquals(goldenFilePath, visitor.write()); } } diff --git a/src/test/java/com/google/api/generator/gapic/composer/ServiceClientTestClassComposerTest.java b/src/test/java/com/google/api/generator/gapic/composer/grpc/ServiceClientTestClassComposerTest.java similarity index 77% rename from src/test/java/com/google/api/generator/gapic/composer/ServiceClientTestClassComposerTest.java rename to src/test/java/com/google/api/generator/gapic/composer/grpc/ServiceClientTestClassComposerTest.java index d4932a1ace..cbb6bae23b 100644 --- a/src/test/java/com/google/api/generator/gapic/composer/ServiceClientTestClassComposerTest.java +++ b/src/test/java/com/google/api/generator/gapic/composer/grpc/ServiceClientTestClassComposerTest.java @@ -12,13 +12,13 @@ // See the License for the specific language governing permissions and // limitations under the License. -package com.google.api.generator.gapic.composer; +package com.google.api.generator.gapic.composer.grpc; import static com.google.api.generator.test.framework.Assert.assertCodeEquals; import static junit.framework.Assert.assertEquals; import com.google.api.generator.engine.writer.JavaWriterVisitor; -import com.google.api.generator.gapic.composer.constants.ComposerConstants; +import com.google.api.generator.gapic.composer.common.ServiceClientClassComposer; import com.google.api.generator.gapic.model.GapicClass; import com.google.api.generator.gapic.model.GapicContext; import com.google.api.generator.gapic.model.Service; @@ -30,7 +30,7 @@ public class ServiceClientTestClassComposerTest { @Test public void generateClientTest_echoClient() { - GapicContext context = TestProtoLoaderUtil.parseShowcaseEcho(); + GapicContext context = GrpcTestProtoLoader.instance().parseShowcaseEcho(); Service echoProtoService = context.services().get(0); GapicClass clazz = ServiceClientTestClassComposer.instance().generate(context, echoProtoService); @@ -39,27 +39,27 @@ public void generateClientTest_echoClient() { clazz.classDefinition().accept(visitor); Utils.saveCodegenToFile(this.getClass(), "EchoClientTest.golden", visitor.write()); Path goldenFilePath = - Paths.get(ComposerConstants.GOLDENFILES_DIRECTORY, "EchoClientTest.golden"); + Paths.get(Utils.getGoldenDir(this.getClass()), "EchoClientTest.golden"); assertCodeEquals(goldenFilePath, visitor.write()); } @Test public void generateClientTest_deprecatedServiceClient() { - GapicContext context = TestProtoLoaderUtil.parseDeprecatedService(); + GapicContext context = GrpcTestProtoLoader.instance().parseDeprecatedService(); Service protoService = context.services().get(0); - GapicClass clazz = ServiceClientClassComposer.instance().generate(context, protoService); + GapicClass clazz = ServiceClientTestClassComposer.instance().generate(context, protoService); JavaWriterVisitor visitor = new JavaWriterVisitor(); clazz.classDefinition().accept(visitor); Utils.saveCodegenToFile(this.getClass(), "DeprecatedServiceClientTest.golden", visitor.write()); Path goldenFilePath = - Paths.get(ComposerConstants.GOLDENFILES_DIRECTORY, "DeprecatedServiceClientTest.golden"); + Paths.get(Utils.getGoldenDir(this.getClass()), "DeprecatedServiceClientTest.golden"); assertCodeEquals(goldenFilePath, visitor.write()); } @Test public void generateClientTest_testingClientResnameWithOnePatternWithNonSlashSepNames() { - GapicContext context = TestProtoLoaderUtil.parseShowcaseTesting(); + GapicContext context = GrpcTestProtoLoader.instance().parseShowcaseTesting(); Service testingProtoService = context.services().get(0); GapicClass clazz = ServiceClientTestClassComposer.instance().generate(context, testingProtoService); @@ -68,13 +68,13 @@ public void generateClientTest_testingClientResnameWithOnePatternWithNonSlashSep clazz.classDefinition().accept(visitor); Utils.saveCodegenToFile(this.getClass(), "TestingClientTest.golden", visitor.write()); Path goldenFilePath = - Paths.get(ComposerConstants.GOLDENFILES_DIRECTORY, "TestingClientTest.golden"); + Paths.get(Utils.getGoldenDir(this.getClass()), "TestingClientTest.golden"); assertCodeEquals(goldenFilePath, visitor.write()); } @Test public void generateClientTest_pubSubPublisherClient() { - GapicContext context = TestProtoLoaderUtil.parsePubSubPublisher(); + GapicContext context = GrpcTestProtoLoader.instance().parsePubSubPublisher(); Service subscriptionService = context.services().get(1); assertEquals("Subscriber", subscriptionService.name()); GapicClass clazz = @@ -84,13 +84,13 @@ public void generateClientTest_pubSubPublisherClient() { clazz.classDefinition().accept(visitor); Utils.saveCodegenToFile(this.getClass(), "SubscriberClientTest.golden", visitor.write()); Path goldenFilePath = - Paths.get(ComposerConstants.GOLDENFILES_DIRECTORY, "SubscriberClientTest.golden"); + Paths.get(Utils.getGoldenDir(this.getClass()), "SubscriberClientTest.golden"); assertCodeEquals(goldenFilePath, visitor.write()); } @Test public void generateClientTest_logging() { - GapicContext context = TestProtoLoaderUtil.parseLogging(); + GapicContext context = GrpcTestProtoLoader.instance().parseLogging(); Service loggingService = context.services().get(0); GapicClass clazz = ServiceClientTestClassComposer.instance().generate(context, loggingService); @@ -98,7 +98,7 @@ public void generateClientTest_logging() { clazz.classDefinition().accept(visitor); Utils.saveCodegenToFile(this.getClass(), "LoggingClientTest.golden", visitor.write()); Path goldenFilePath = - Paths.get(ComposerConstants.GOLDENFILES_DIRECTORY, "LoggingClientTest.golden"); + Paths.get(Utils.getGoldenDir(this.getClass()), "LoggingClientTest.golden"); assertCodeEquals(goldenFilePath, visitor.write()); } } diff --git a/src/test/java/com/google/api/generator/gapic/composer/ServiceSettingsClassComposerTest.java b/src/test/java/com/google/api/generator/gapic/composer/grpc/ServiceSettingsClassComposerTest.java similarity index 80% rename from src/test/java/com/google/api/generator/gapic/composer/ServiceSettingsClassComposerTest.java rename to src/test/java/com/google/api/generator/gapic/composer/grpc/ServiceSettingsClassComposerTest.java index 9075e0dd95..70b1b32b6b 100644 --- a/src/test/java/com/google/api/generator/gapic/composer/ServiceSettingsClassComposerTest.java +++ b/src/test/java/com/google/api/generator/gapic/composer/grpc/ServiceSettingsClassComposerTest.java @@ -12,10 +12,10 @@ // See the License for the specific language governing permissions and // limitations under the License. -package com.google.api.generator.gapic.composer; +package com.google.api.generator.gapic.composer.grpc; import com.google.api.generator.engine.writer.JavaWriterVisitor; -import com.google.api.generator.gapic.composer.constants.ComposerConstants; +import com.google.api.generator.gapic.composer.common.ServiceClientClassComposer; import com.google.api.generator.gapic.model.GapicClass; import com.google.api.generator.gapic.model.GapicContext; import com.google.api.generator.gapic.model.Service; @@ -28,20 +28,20 @@ public class ServiceSettingsClassComposerTest { @Test public void generateServiceClasses() { - GapicContext context = TestProtoLoaderUtil.parseShowcaseEcho(); + GapicContext context = GrpcTestProtoLoader.instance().parseShowcaseEcho(); Service echoProtoService = context.services().get(0); GapicClass clazz = ServiceSettingsClassComposer.instance().generate(context, echoProtoService); JavaWriterVisitor visitor = new JavaWriterVisitor(); clazz.classDefinition().accept(visitor); Utils.saveCodegenToFile(this.getClass(), "EchoSettings.golden", visitor.write()); - Path goldenFilePath = Paths.get(ComposerConstants.GOLDENFILES_DIRECTORY, "EchoSettings.golden"); + Path goldenFilePath = Paths.get(Utils.getGoldenDir(this.getClass()), "EchoSettings.golden"); Assert.assertCodeEquals(goldenFilePath, visitor.write()); } @Test public void generateServiceClasses_deprecated() { - GapicContext context = TestProtoLoaderUtil.parseDeprecatedService(); + GapicContext context = GrpcTestProtoLoader.instance().parseDeprecatedService(); Service protoService = context.services().get(0); GapicClass clazz = ServiceSettingsClassComposer.instance().generate(context, protoService); @@ -49,7 +49,7 @@ public void generateServiceClasses_deprecated() { clazz.classDefinition().accept(visitor); Utils.saveCodegenToFile(this.getClass(), "DeprecatedServiceSettings.golden", visitor.write()); Path goldenFilePath = - Paths.get(ComposerConstants.GOLDENFILES_DIRECTORY, "DeprecatedServiceSettings.golden"); + Paths.get(Utils.getGoldenDir(this.getClass()), "DeprecatedServiceSettings.golden"); Assert.assertCodeEquals(goldenFilePath, visitor.write()); } } diff --git a/src/test/java/com/google/api/generator/gapic/composer/ServiceStubSettingsClassComposerTest.java b/src/test/java/com/google/api/generator/gapic/composer/grpc/ServiceStubSettingsClassComposerTest.java similarity index 75% rename from src/test/java/com/google/api/generator/gapic/composer/ServiceStubSettingsClassComposerTest.java rename to src/test/java/com/google/api/generator/gapic/composer/grpc/ServiceStubSettingsClassComposerTest.java index 33a23fac52..3a907c432f 100644 --- a/src/test/java/com/google/api/generator/gapic/composer/ServiceStubSettingsClassComposerTest.java +++ b/src/test/java/com/google/api/generator/gapic/composer/grpc/ServiceStubSettingsClassComposerTest.java @@ -12,26 +12,24 @@ // See the License for the specific language governing permissions and // limitations under the License. -package com.google.api.generator.gapic.composer; +package com.google.api.generator.gapic.composer.grpc; import static junit.framework.Assert.assertEquals; import com.google.api.generator.engine.writer.JavaWriterVisitor; -import com.google.api.generator.gapic.composer.constants.ComposerConstants; import com.google.api.generator.gapic.model.GapicClass; import com.google.api.generator.gapic.model.GapicContext; import com.google.api.generator.gapic.model.Service; import com.google.api.generator.test.framework.Assert; import com.google.api.generator.test.framework.Utils; -import java.io.IOException; import java.nio.file.Path; import java.nio.file.Paths; import org.junit.Test; public class ServiceStubSettingsClassComposerTest { @Test - public void generateServiceStubSettingsClasses_batchingWithEmptyResponses() throws IOException { - GapicContext context = TestProtoLoaderUtil.parseLogging(); + public void generateServiceStubSettingsClasses_batchingWithEmptyResponses() { + GapicContext context = GrpcTestProtoLoader.instance().parseLogging(); Service protoService = context.services().get(0); GapicClass clazz = ServiceStubSettingsClassComposer.instance().generate(context, protoService); @@ -40,14 +38,13 @@ public void generateServiceStubSettingsClasses_batchingWithEmptyResponses() thro Utils.saveCodegenToFile( this.getClass(), "LoggingServiceV2StubSettings.golden", visitor.write()); Path goldenFilePath = - Paths.get(ComposerConstants.GOLDENFILES_DIRECTORY, "LoggingServiceV2StubSettings.golden"); + Paths.get(Utils.getGoldenDir(this.getClass()), "LoggingServiceV2StubSettings.golden"); Assert.assertCodeEquals(goldenFilePath, visitor.write()); } @Test - public void generateServiceStubSettingsClasses_batchingWithNonemptyResponses() - throws IOException { - GapicContext context = TestProtoLoaderUtil.parsePubSubPublisher(); + public void generateServiceStubSettingsClasses_batchingWithNonemptyResponses() { + GapicContext context = GrpcTestProtoLoader.instance().parsePubSubPublisher(); Service protoService = context.services().get(0); assertEquals("Publisher", protoService.name()); GapicClass clazz = ServiceStubSettingsClassComposer.instance().generate(context, protoService); @@ -56,13 +53,13 @@ public void generateServiceStubSettingsClasses_batchingWithNonemptyResponses() clazz.classDefinition().accept(visitor); Utils.saveCodegenToFile(this.getClass(), "PublisherStubSettings.golden", visitor.write()); Path goldenFilePath = - Paths.get(ComposerConstants.GOLDENFILES_DIRECTORY, "PublisherStubSettings.golden"); + Paths.get(Utils.getGoldenDir(this.getClass()), "PublisherStubSettings.golden"); Assert.assertCodeEquals(goldenFilePath, visitor.write()); } @Test - public void generateServiceStubSettingsClasses_basic() throws IOException { - GapicContext context = TestProtoLoaderUtil.parseShowcaseEcho(); + public void generateServiceStubSettingsClasses_basic() { + GapicContext context = GrpcTestProtoLoader.instance().parseShowcaseEcho(); Service echoProtoService = context.services().get(0); GapicClass clazz = ServiceStubSettingsClassComposer.instance().generate(context, echoProtoService); @@ -71,13 +68,13 @@ public void generateServiceStubSettingsClasses_basic() throws IOException { clazz.classDefinition().accept(visitor); Utils.saveCodegenToFile(this.getClass(), "EchoStubSettings.golden", visitor.write()); Path goldenFilePath = - Paths.get(ComposerConstants.GOLDENFILES_DIRECTORY, "EchoStubSettings.golden"); + Paths.get(Utils.getGoldenDir(this.getClass()), "EchoStubSettings.golden"); Assert.assertCodeEquals(goldenFilePath, visitor.write()); } @Test - public void generateServiceStubSettingsClasses_deprecated() throws IOException { - GapicContext context = TestProtoLoaderUtil.parseDeprecatedService(); + public void generateServiceStubSettingsClasses_deprecated() { + GapicContext context = GrpcTestProtoLoader.instance().parseDeprecatedService(); Service protoService = context.services().get(0); GapicClass clazz = ServiceStubSettingsClassComposer.instance().generate(context, protoService); @@ -86,7 +83,7 @@ public void generateServiceStubSettingsClasses_deprecated() throws IOException { Utils.saveCodegenToFile( this.getClass(), "DeprecatedServiceStubSettings.golden", visitor.write()); Path goldenFilePath = - Paths.get(ComposerConstants.GOLDENFILES_DIRECTORY, "DeprecatedServiceStubSettings.golden"); + Paths.get(Utils.getGoldenDir(this.getClass()), "DeprecatedServiceStubSettings.golden"); Assert.assertCodeEquals(goldenFilePath, visitor.write()); } } diff --git a/src/test/java/com/google/api/generator/gapic/composer/grpc/goldens/BUILD.bazel b/src/test/java/com/google/api/generator/gapic/composer/grpc/goldens/BUILD.bazel new file mode 100644 index 0000000000..85ac1a519e --- /dev/null +++ b/src/test/java/com/google/api/generator/gapic/composer/grpc/goldens/BUILD.bazel @@ -0,0 +1,6 @@ +package(default_visibility = ["//visibility:public"]) + +filegroup( + name = "goldens_files", + srcs = glob(["*.golden"]), +) diff --git a/src/test/java/com/google/api/generator/gapic/composer/goldens/DeprecatedServiceClientTest.golden b/src/test/java/com/google/api/generator/gapic/composer/grpc/goldens/DeprecatedServiceClientTest.golden similarity index 100% rename from src/test/java/com/google/api/generator/gapic/composer/goldens/DeprecatedServiceClientTest.golden rename to src/test/java/com/google/api/generator/gapic/composer/grpc/goldens/DeprecatedServiceClientTest.golden diff --git a/src/test/java/com/google/api/generator/gapic/composer/goldens/DeprecatedServiceSettings.golden b/src/test/java/com/google/api/generator/gapic/composer/grpc/goldens/DeprecatedServiceSettings.golden similarity index 100% rename from src/test/java/com/google/api/generator/gapic/composer/goldens/DeprecatedServiceSettings.golden rename to src/test/java/com/google/api/generator/gapic/composer/grpc/goldens/DeprecatedServiceSettings.golden diff --git a/src/test/java/com/google/api/generator/gapic/composer/goldens/DeprecatedServiceStubSettings.golden b/src/test/java/com/google/api/generator/gapic/composer/grpc/goldens/DeprecatedServiceStubSettings.golden similarity index 100% rename from src/test/java/com/google/api/generator/gapic/composer/goldens/DeprecatedServiceStubSettings.golden rename to src/test/java/com/google/api/generator/gapic/composer/grpc/goldens/DeprecatedServiceStubSettings.golden diff --git a/src/test/java/com/google/api/generator/gapic/composer/goldens/EchoClientTest.golden b/src/test/java/com/google/api/generator/gapic/composer/grpc/goldens/EchoClientTest.golden similarity index 100% rename from src/test/java/com/google/api/generator/gapic/composer/goldens/EchoClientTest.golden rename to src/test/java/com/google/api/generator/gapic/composer/grpc/goldens/EchoClientTest.golden diff --git a/src/test/java/com/google/api/generator/gapic/composer/goldens/EchoSettings.golden b/src/test/java/com/google/api/generator/gapic/composer/grpc/goldens/EchoSettings.golden similarity index 100% rename from src/test/java/com/google/api/generator/gapic/composer/goldens/EchoSettings.golden rename to src/test/java/com/google/api/generator/gapic/composer/grpc/goldens/EchoSettings.golden diff --git a/src/test/java/com/google/api/generator/gapic/composer/goldens/EchoStubSettings.golden b/src/test/java/com/google/api/generator/gapic/composer/grpc/goldens/EchoStubSettings.golden similarity index 100% rename from src/test/java/com/google/api/generator/gapic/composer/goldens/EchoStubSettings.golden rename to src/test/java/com/google/api/generator/gapic/composer/grpc/goldens/EchoStubSettings.golden diff --git a/src/test/java/com/google/api/generator/gapic/composer/goldens/GrpcDeprecatedServiceCallableFactory.golden b/src/test/java/com/google/api/generator/gapic/composer/grpc/goldens/GrpcDeprecatedServiceCallableFactory.golden similarity index 100% rename from src/test/java/com/google/api/generator/gapic/composer/goldens/GrpcDeprecatedServiceCallableFactory.golden rename to src/test/java/com/google/api/generator/gapic/composer/grpc/goldens/GrpcDeprecatedServiceCallableFactory.golden diff --git a/src/test/java/com/google/api/generator/gapic/composer/goldens/GrpcDeprecatedServiceStub.golden b/src/test/java/com/google/api/generator/gapic/composer/grpc/goldens/GrpcDeprecatedServiceStub.golden similarity index 100% rename from src/test/java/com/google/api/generator/gapic/composer/goldens/GrpcDeprecatedServiceStub.golden rename to src/test/java/com/google/api/generator/gapic/composer/grpc/goldens/GrpcDeprecatedServiceStub.golden diff --git a/src/test/java/com/google/api/generator/gapic/composer/goldens/GrpcEchoCallableFactory.golden b/src/test/java/com/google/api/generator/gapic/composer/grpc/goldens/GrpcEchoCallableFactory.golden similarity index 100% rename from src/test/java/com/google/api/generator/gapic/composer/goldens/GrpcEchoCallableFactory.golden rename to src/test/java/com/google/api/generator/gapic/composer/grpc/goldens/GrpcEchoCallableFactory.golden diff --git a/src/test/java/com/google/api/generator/gapic/composer/goldens/GrpcEchoStub.golden b/src/test/java/com/google/api/generator/gapic/composer/grpc/goldens/GrpcEchoStub.golden similarity index 100% rename from src/test/java/com/google/api/generator/gapic/composer/goldens/GrpcEchoStub.golden rename to src/test/java/com/google/api/generator/gapic/composer/grpc/goldens/GrpcEchoStub.golden diff --git a/src/test/java/com/google/api/generator/gapic/composer/goldens/GrpcPublisherStub.golden b/src/test/java/com/google/api/generator/gapic/composer/grpc/goldens/GrpcPublisherStub.golden similarity index 100% rename from src/test/java/com/google/api/generator/gapic/composer/goldens/GrpcPublisherStub.golden rename to src/test/java/com/google/api/generator/gapic/composer/grpc/goldens/GrpcPublisherStub.golden diff --git a/src/test/java/com/google/api/generator/gapic/composer/goldens/GrpcTestingStub.golden b/src/test/java/com/google/api/generator/gapic/composer/grpc/goldens/GrpcTestingStub.golden similarity index 100% rename from src/test/java/com/google/api/generator/gapic/composer/goldens/GrpcTestingStub.golden rename to src/test/java/com/google/api/generator/gapic/composer/grpc/goldens/GrpcTestingStub.golden diff --git a/src/test/java/com/google/api/generator/gapic/composer/goldens/LoggingClientTest.golden b/src/test/java/com/google/api/generator/gapic/composer/grpc/goldens/LoggingClientTest.golden similarity index 100% rename from src/test/java/com/google/api/generator/gapic/composer/goldens/LoggingClientTest.golden rename to src/test/java/com/google/api/generator/gapic/composer/grpc/goldens/LoggingClientTest.golden diff --git a/src/test/java/com/google/api/generator/gapic/composer/goldens/LoggingServiceV2StubSettings.golden b/src/test/java/com/google/api/generator/gapic/composer/grpc/goldens/LoggingServiceV2StubSettings.golden similarity index 100% rename from src/test/java/com/google/api/generator/gapic/composer/goldens/LoggingServiceV2StubSettings.golden rename to src/test/java/com/google/api/generator/gapic/composer/grpc/goldens/LoggingServiceV2StubSettings.golden diff --git a/src/test/java/com/google/api/generator/gapic/composer/goldens/MockDeprecatedService.golden b/src/test/java/com/google/api/generator/gapic/composer/grpc/goldens/MockDeprecatedService.golden similarity index 100% rename from src/test/java/com/google/api/generator/gapic/composer/goldens/MockDeprecatedService.golden rename to src/test/java/com/google/api/generator/gapic/composer/grpc/goldens/MockDeprecatedService.golden diff --git a/src/test/java/com/google/api/generator/gapic/composer/goldens/MockDeprecatedServiceImpl.golden b/src/test/java/com/google/api/generator/gapic/composer/grpc/goldens/MockDeprecatedServiceImpl.golden similarity index 100% rename from src/test/java/com/google/api/generator/gapic/composer/goldens/MockDeprecatedServiceImpl.golden rename to src/test/java/com/google/api/generator/gapic/composer/grpc/goldens/MockDeprecatedServiceImpl.golden diff --git a/src/test/java/com/google/api/generator/gapic/composer/goldens/MockEcho.golden b/src/test/java/com/google/api/generator/gapic/composer/grpc/goldens/MockEcho.golden similarity index 100% rename from src/test/java/com/google/api/generator/gapic/composer/goldens/MockEcho.golden rename to src/test/java/com/google/api/generator/gapic/composer/grpc/goldens/MockEcho.golden diff --git a/src/test/java/com/google/api/generator/gapic/composer/goldens/MockEchoImpl.golden b/src/test/java/com/google/api/generator/gapic/composer/grpc/goldens/MockEchoImpl.golden similarity index 100% rename from src/test/java/com/google/api/generator/gapic/composer/goldens/MockEchoImpl.golden rename to src/test/java/com/google/api/generator/gapic/composer/grpc/goldens/MockEchoImpl.golden diff --git a/src/test/java/com/google/api/generator/gapic/composer/goldens/PublisherStubSettings.golden b/src/test/java/com/google/api/generator/gapic/composer/grpc/goldens/PublisherStubSettings.golden similarity index 100% rename from src/test/java/com/google/api/generator/gapic/composer/goldens/PublisherStubSettings.golden rename to src/test/java/com/google/api/generator/gapic/composer/grpc/goldens/PublisherStubSettings.golden diff --git a/src/test/java/com/google/api/generator/gapic/composer/goldens/SubscriberClientTest.golden b/src/test/java/com/google/api/generator/gapic/composer/grpc/goldens/SubscriberClientTest.golden similarity index 100% rename from src/test/java/com/google/api/generator/gapic/composer/goldens/SubscriberClientTest.golden rename to src/test/java/com/google/api/generator/gapic/composer/grpc/goldens/SubscriberClientTest.golden diff --git a/src/test/java/com/google/api/generator/gapic/composer/goldens/TestingClientTest.golden b/src/test/java/com/google/api/generator/gapic/composer/grpc/goldens/TestingClientTest.golden similarity index 100% rename from src/test/java/com/google/api/generator/gapic/composer/goldens/TestingClientTest.golden rename to src/test/java/com/google/api/generator/gapic/composer/grpc/goldens/TestingClientTest.golden diff --git a/src/test/java/com/google/api/generator/gapic/composer/resourcename/BUILD.bazel b/src/test/java/com/google/api/generator/gapic/composer/resourcename/BUILD.bazel index 17b37c640b..a62cd2dad8 100644 --- a/src/test/java/com/google/api/generator/gapic/composer/resourcename/BUILD.bazel +++ b/src/test/java/com/google/api/generator/gapic/composer/resourcename/BUILD.bazel @@ -1,9 +1,13 @@ load("@rules_java//java:defs.bzl", "java_proto_library", "java_test") +load("//:rules_bazel/java/java_diff_test.bzl", "golden_update") package(default_visibility = ["//visibility:public"]) -TESTS = [ +UPDATE_GOLDENS_TESTS = [ "ResourceNameHelperClassComposerTest", +] + +TESTS = UPDATE_GOLDENS_TESTS + [ "ResourceNameTokenizerTest", ] @@ -12,36 +16,37 @@ filegroup( srcs = ["{0}.java".format(f) for f in TESTS], ) +TEST_DEPS = [ + ":common_resources_java_proto", + "//src/main/java/com/google/api/generator/engine/ast", + "//src/main/java/com/google/api/generator/engine/writer", + "//src/main/java/com/google/api/generator/gapic/composer/resourcename", + "//src/main/java/com/google/api/generator/gapic/model", + "//src/main/java/com/google/api/generator/gapic/protoparser", + "//src/test/java/com/google/api/generator/gapic/testdata:showcase_java_proto", + "//src/test/java/com/google/api/generator/test/framework:asserts", + "//src/test/java/com/google/api/generator/test/framework:utils", + "//src/test/java/com/google/api/generator/testutils", + "@com_google_api_api_common//jar", + "@com_google_api_gax_java//gax", + "@com_google_googleapis//google/logging/v2:logging_java_proto", + "@com_google_googleapis//google/rpc:rpc_java_proto", + "@com_google_guava_guava", + "@com_google_protobuf//:protobuf_java", + "@com_google_truth_truth//jar", + "@junit_junit//jar", +] + [java_test( name = test_name, srcs = ["{0}.java".format(test_name)], data = [ - "//src/test/java/com/google/api/generator/gapic/composer/goldens:goldens_files", + "//src/test/java/com/google/api/generator/gapic/composer/resourcename/goldens:goldens_files", "//src/test/java/com/google/api/generator/gapic/testdata:gapic_config_files", "//src/test/java/com/google/api/generator/gapic/testdata:service_config_files", ], test_class = "com.google.api.generator.gapic.composer.resourcename.{0}".format(test_name), - deps = [ - ":common_resources_java_proto", - "//src/main/java/com/google/api/generator/engine/ast", - "//src/main/java/com/google/api/generator/engine/writer", - "//src/main/java/com/google/api/generator/gapic/composer/resourcename", - "//src/main/java/com/google/api/generator/gapic/model", - "//src/main/java/com/google/api/generator/gapic/protoparser", - "//src/test/java/com/google/api/generator/gapic/composer/constants", - "//src/test/java/com/google/api/generator/gapic/testdata:showcase_java_proto", - "//src/test/java/com/google/api/generator/test/framework:asserts", - "//src/test/java/com/google/api/generator/test/framework:utils", - "//src/test/java/com/google/api/generator/testutils", - "@com_google_api_api_common//jar", - "@com_google_api_gax_java//gax", - "@com_google_googleapis//google/logging/v2:logging_java_proto", - "@com_google_googleapis//google/rpc:rpc_java_proto", - "@com_google_guava_guava", - "@com_google_protobuf//:protobuf_java", - "@com_google_truth_truth//jar", - "@junit_junit//jar", - ], + deps = TEST_DEPS, ) for test_name in TESTS] java_proto_library( @@ -50,3 +55,21 @@ java_proto_library( "@com_google_googleapis//google/cloud:common_resources_proto", ], ) + +# Run `bazel run src/test/java/com/google/api/generator/gapic/composer/resourcename:testTargetName_update` +# to update goldens as expected generated code. +# `ServiceClient*` tests are not supported now since they are still in active development. + +[golden_update( + name = "{0}_update".format(test_name), + srcs = [ + "{0}.java".format(test_name), + ], + data = [ + "//src/test/java/com/google/api/generator/gapic/composer/resourcename/goldens:goldens_files", + "//src/test/java/com/google/api/generator/gapic/testdata:gapic_config_files", + "//src/test/java/com/google/api/generator/gapic/testdata:service_config_files", + ], + test_class = "com.google.api.generator.gapic.composer.resourcename.{0}".format(test_name), + deps = TEST_DEPS, +) for test_name in UPDATE_GOLDENS_TESTS] diff --git a/src/test/java/com/google/api/generator/gapic/composer/resourcename/ResourceNameHelperClassComposerTest.java b/src/test/java/com/google/api/generator/gapic/composer/resourcename/ResourceNameHelperClassComposerTest.java index cd918c865d..16251dc124 100644 --- a/src/test/java/com/google/api/generator/gapic/composer/resourcename/ResourceNameHelperClassComposerTest.java +++ b/src/test/java/com/google/api/generator/gapic/composer/resourcename/ResourceNameHelperClassComposerTest.java @@ -18,7 +18,6 @@ import static junit.framework.Assert.assertEquals; import com.google.api.generator.engine.writer.JavaWriterVisitor; -import com.google.api.generator.gapic.composer.constants.ComposerConstants; import com.google.api.generator.gapic.model.GapicClass; import com.google.api.generator.gapic.model.Message; import com.google.api.generator.gapic.model.ResourceName; @@ -107,7 +106,7 @@ public void generateResourceNameClass_echoFoobarMultiplePatterns() { JavaWriterVisitor visitor = new JavaWriterVisitor(); clazz.classDefinition().accept(visitor); Utils.saveCodegenToFile(this.getClass(), "FoobarName.golden", visitor.write()); - Path goldenFilePath = Paths.get(ComposerConstants.GOLDENFILES_DIRECTORY, "FoobarName.golden"); + Path goldenFilePath = Paths.get(Utils.getGoldenDir(this.getClass()), "FoobarName.golden"); Assert.assertCodeEquals(goldenFilePath, visitor.write()); } @@ -156,7 +155,7 @@ public void generateResourceNameClass_loggingOnePatternMultipleVariables() { clazz.classDefinition().accept(visitor); Utils.saveCodegenToFile(this.getClass(), "BillingAccountLocationName.golden", visitor.write()); Path goldenFilePath = - Paths.get(ComposerConstants.GOLDENFILES_DIRECTORY, "BillingAccountLocationName.golden"); + Paths.get(Utils.getGoldenDir(this.getClass()), "BillingAccountLocationName.golden"); Assert.assertCodeEquals(goldenFilePath, visitor.write()); } @@ -185,7 +184,7 @@ public void generateResourceNameClass_testingSessionOnePattern() { JavaWriterVisitor visitor = new JavaWriterVisitor(); clazz.classDefinition().accept(visitor); Utils.saveCodegenToFile(this.getClass(), "SessionName.golden", visitor.write()); - Path goldenFilePath = Paths.get(ComposerConstants.GOLDENFILES_DIRECTORY, "SessionName.golden"); + Path goldenFilePath = Paths.get(Utils.getGoldenDir(this.getClass()), "SessionName.golden"); Assert.assertCodeEquals(goldenFilePath, visitor.write()); } @@ -214,7 +213,7 @@ public void generateResourceNameClass_testingBlueprintPatternWithNonSlashSeparat JavaWriterVisitor visitor = new JavaWriterVisitor(); clazz.classDefinition().accept(visitor); Utils.saveCodegenToFile(this.getClass(), "TestName.golden", visitor.write()); - Path goldenFilePath = Paths.get(ComposerConstants.GOLDENFILES_DIRECTORY, "TestName.golden"); + Path goldenFilePath = Paths.get(Utils.getGoldenDir(this.getClass()), "TestName.golden"); Assert.assertCodeEquals(goldenFilePath, visitor.write()); } @@ -236,7 +235,7 @@ public void generateResourceNameClass_childSingleton() { JavaWriterVisitor visitor = new JavaWriterVisitor(); clazz.classDefinition().accept(visitor); Utils.saveCodegenToFile(this.getClass(), "AgentName.golden", visitor.write()); - Path goldenFilePath = Paths.get(ComposerConstants.GOLDENFILES_DIRECTORY, "AgentName.golden"); + Path goldenFilePath = Paths.get(Utils.getGoldenDir(this.getClass()), "AgentName.golden"); Assert.assertCodeEquals(goldenFilePath, visitor.write()); } } diff --git a/src/test/java/com/google/api/generator/gapic/composer/goldens/AgentName.golden b/src/test/java/com/google/api/generator/gapic/composer/resourcename/goldens/AgentName.golden similarity index 100% rename from src/test/java/com/google/api/generator/gapic/composer/goldens/AgentName.golden rename to src/test/java/com/google/api/generator/gapic/composer/resourcename/goldens/AgentName.golden diff --git a/src/test/java/com/google/api/generator/gapic/composer/resourcename/goldens/BUILD.bazel b/src/test/java/com/google/api/generator/gapic/composer/resourcename/goldens/BUILD.bazel new file mode 100644 index 0000000000..85ac1a519e --- /dev/null +++ b/src/test/java/com/google/api/generator/gapic/composer/resourcename/goldens/BUILD.bazel @@ -0,0 +1,6 @@ +package(default_visibility = ["//visibility:public"]) + +filegroup( + name = "goldens_files", + srcs = glob(["*.golden"]), +) diff --git a/src/test/java/com/google/api/generator/gapic/composer/goldens/BillingAccountLocationName.golden b/src/test/java/com/google/api/generator/gapic/composer/resourcename/goldens/BillingAccountLocationName.golden similarity index 100% rename from src/test/java/com/google/api/generator/gapic/composer/goldens/BillingAccountLocationName.golden rename to src/test/java/com/google/api/generator/gapic/composer/resourcename/goldens/BillingAccountLocationName.golden diff --git a/src/test/java/com/google/api/generator/gapic/composer/goldens/FoobarName.golden b/src/test/java/com/google/api/generator/gapic/composer/resourcename/goldens/FoobarName.golden similarity index 100% rename from src/test/java/com/google/api/generator/gapic/composer/goldens/FoobarName.golden rename to src/test/java/com/google/api/generator/gapic/composer/resourcename/goldens/FoobarName.golden diff --git a/src/test/java/com/google/api/generator/gapic/composer/goldens/SessionName.golden b/src/test/java/com/google/api/generator/gapic/composer/resourcename/goldens/SessionName.golden similarity index 100% rename from src/test/java/com/google/api/generator/gapic/composer/goldens/SessionName.golden rename to src/test/java/com/google/api/generator/gapic/composer/resourcename/goldens/SessionName.golden diff --git a/src/test/java/com/google/api/generator/gapic/composer/goldens/TestName.golden b/src/test/java/com/google/api/generator/gapic/composer/resourcename/goldens/TestName.golden similarity index 100% rename from src/test/java/com/google/api/generator/gapic/composer/goldens/TestName.golden rename to src/test/java/com/google/api/generator/gapic/composer/resourcename/goldens/TestName.golden diff --git a/src/test/java/com/google/api/generator/gapic/protoparser/HttpRuleParserTest.java b/src/test/java/com/google/api/generator/gapic/protoparser/HttpRuleParserTest.java index 1aed7b9f92..c2383142bb 100644 --- a/src/test/java/com/google/api/generator/gapic/protoparser/HttpRuleParserTest.java +++ b/src/test/java/com/google/api/generator/gapic/protoparser/HttpRuleParserTest.java @@ -16,18 +16,16 @@ import static com.google.common.truth.Truth.assertThat; import static junit.framework.Assert.assertEquals; -import static junit.framework.Assert.assertFalse; import static junit.framework.Assert.assertTrue; import static org.junit.Assert.assertThrows; +import com.google.api.generator.gapic.model.HttpRuleBindings; import com.google.api.generator.gapic.model.Message; import com.google.protobuf.Descriptors.FileDescriptor; import com.google.protobuf.Descriptors.MethodDescriptor; import com.google.protobuf.Descriptors.ServiceDescriptor; import com.google.showcase.v1beta1.TestingOuterClass; -import java.util.List; import java.util.Map; -import java.util.Optional; import org.junit.Test; public class HttpRuleParserTest { @@ -42,16 +40,14 @@ public void parseHttpAnnotation_basic() { // CreateSession method. MethodDescriptor rpcMethod = testingService.getMethods().get(0); Message inputMessage = messages.get("CreateSessionRequest"); - Optional> httpBindingsOpt = - HttpRuleParser.parseHttpBindings(rpcMethod, inputMessage, messages); - assertFalse(httpBindingsOpt.isPresent()); + HttpRuleBindings httpBindings = HttpRuleParser.parse(rpcMethod, inputMessage, messages); + assertTrue(httpBindings.pathParameters().isEmpty()); // GetSession method. rpcMethod = testingService.getMethods().get(1); inputMessage = messages.get("GetSessionRequest"); - httpBindingsOpt = HttpRuleParser.parseHttpBindings(rpcMethod, inputMessage, messages); - assertTrue(httpBindingsOpt.isPresent()); - assertThat(httpBindingsOpt.get()).containsExactly("name"); + httpBindings = HttpRuleParser.parse(rpcMethod, inputMessage, messages); + assertThat(httpBindings.pathParameters()).containsExactly("name"); } @Test @@ -66,10 +62,8 @@ public void parseHttpAnnotation_multipleBindings() { MethodDescriptor rpcMethod = testingService.getMethods().get(testingService.getMethods().size() - 1); Message inputMessage = messages.get("VerifyTestRequest"); - Optional> httpBindingsOpt = - HttpRuleParser.parseHttpBindings(rpcMethod, inputMessage, messages); - assertTrue(httpBindingsOpt.isPresent()); - assertThat(httpBindingsOpt.get()) + HttpRuleBindings httpBindings = HttpRuleParser.parse(rpcMethod, inputMessage, messages); + assertThat(httpBindings.pathParameters()) .containsExactly("answer", "foo", "name", "test_to_verify.name"); } @@ -86,7 +80,6 @@ public void parseHttpAnnotation_missingFieldFromMessage() { testingService.getMethods().get(testingService.getMethods().size() - 1); Message inputMessage = messages.get("CreateSessionRequest"); assertThrows( - IllegalStateException.class, - () -> HttpRuleParser.parseHttpBindings(rpcMethod, inputMessage, messages)); + IllegalStateException.class, () -> HttpRuleParser.parse(rpcMethod, inputMessage, messages)); } } diff --git a/src/test/java/com/google/api/generator/test/framework/Differ.java b/src/test/java/com/google/api/generator/test/framework/Differ.java index 6a3c364d33..488282c070 100644 --- a/src/test/java/com/google/api/generator/test/framework/Differ.java +++ b/src/test/java/com/google/api/generator/test/framework/Differ.java @@ -34,7 +34,7 @@ public static List diff(Path goldenFilePath, String codegen) { original = Files.readAllLines(goldenFilePath); } catch (IOException e) { throw new GoldenFileReadException( - String.format("Error occurs when reading golden file %s", goldenFilePath)); + String.format("Error occurs when reading golden file %s", goldenFilePath), e); } return diffTwoStringLists(original, revised); } @@ -50,7 +50,7 @@ private static List diffTwoStringLists(List original, List unifiedDiff = UnifiedDiffUtils.generateUnifiedDiff("golden", "codegen", original, diff, 2); @@ -58,14 +58,20 @@ private static List diffTwoStringLists(List original, List Date: Wed, 21 Apr 2021 15:22:24 -0700 Subject: [PATCH 02/16] Fix DeprecatedServiceClientTest.golden --- .../DeprecatedServiceClientTest.golden | 298 ++++++------------ 1 file changed, 97 insertions(+), 201 deletions(-) diff --git a/src/test/java/com/google/api/generator/gapic/composer/grpc/goldens/DeprecatedServiceClientTest.golden b/src/test/java/com/google/api/generator/gapic/composer/grpc/goldens/DeprecatedServiceClientTest.golden index 9af83eb743..bf7356d98c 100644 --- a/src/test/java/com/google/api/generator/gapic/composer/grpc/goldens/DeprecatedServiceClientTest.golden +++ b/src/test/java/com/google/api/generator/gapic/composer/grpc/goldens/DeprecatedServiceClientTest.golden @@ -1,234 +1,130 @@ package com.google.testdata.v1; -import com.google.api.core.BetaApi; -import com.google.api.gax.core.BackgroundResource; -import com.google.api.gax.rpc.UnaryCallable; +import com.google.api.gax.core.NoCredentialsProvider; +import com.google.api.gax.grpc.GaxGrpcProperties; +import com.google.api.gax.grpc.testing.LocalChannelProvider; +import com.google.api.gax.grpc.testing.MockGrpcService; +import com.google.api.gax.grpc.testing.MockServiceHelper; +import com.google.api.gax.rpc.ApiClientHeaderProvider; +import com.google.api.gax.rpc.InvalidArgumentException; +import com.google.protobuf.AbstractMessage; import com.google.protobuf.Empty; -import com.google.testdata.v1.stub.DeprecatedServiceStub; -import com.google.testdata.v1.stub.DeprecatedServiceStubSettings; +import io.grpc.StatusRuntimeException; import java.io.IOException; -import java.util.concurrent.TimeUnit; +import java.util.Arrays; +import java.util.List; +import java.util.UUID; import javax.annotation.Generated; +import org.junit.After; +import org.junit.AfterClass; +import org.junit.Assert; +import org.junit.Before; +import org.junit.BeforeClass; +import org.junit.Test; -// AUTO-GENERATED DOCUMENTATION AND CLASS. -/** - * This class provides the ability to make remote calls to the backing service through method calls - * that map to API methods. Sample code to get started: - * - *
{@code
- * try (DeprecatedServiceClient deprecatedServiceClient = DeprecatedServiceClient.create()) {
- *   FibonacciRequest request = FibonacciRequest.newBuilder().setValue(111972721).build();
- *   deprecatedServiceClient.fastFibonacci(request);
- * }
- * }
- * - *

Note: close() needs to be called on the DeprecatedServiceClient object to clean up resources - * such as threads. In the example above, try-with-resources is used, which automatically calls - * close(). - * - *

The surface of this class includes several types of Java methods for each of the API's - * methods: - * - *

    - *
  1. A "flattened" method. With this type of method, the fields of the request type have been - * converted into function parameters. It may be the case that not all fields are available as - * parameters, and not every API method will have a flattened method entry point. - *
  2. A "request object" method. This type of method only takes one parameter, a request object, - * which must be constructed before the call. Not every API method will have a request object - * method. - *
  3. A "callable" method. This type of method takes no parameters and returns an immutable API - * callable object, which can be used to initiate calls to the service. - *
- * - *

See the individual methods for example code. - * - *

Many parameters require resource names to be formatted in a particular way. To assist with - * these names, this class includes a format method for each type of name, and additionally a parse - * method to extract the individual identifiers contained within names that are returned. - * - *

This class can be customized by passing in a custom instance of DeprecatedServiceSettings to - * create(). For example: - * - *

To customize credentials: - * - *

{@code
- * DeprecatedServiceSettings deprecatedServiceSettings =
- *     DeprecatedServiceSettings.newBuilder()
- *         .setCredentialsProvider(FixedCredentialsProvider.create(myCredentials))
- *         .build();
- * DeprecatedServiceClient deprecatedServiceClient =
- *     DeprecatedServiceClient.create(deprecatedServiceSettings);
- * }
- * - *

To customize the endpoint: - * - *

{@code
- * DeprecatedServiceSettings deprecatedServiceSettings =
- *     DeprecatedServiceSettings.newBuilder().setEndpoint(myEndpoint).build();
- * DeprecatedServiceClient deprecatedServiceClient =
- *     DeprecatedServiceClient.create(deprecatedServiceSettings);
- * }
- * - *

Please refer to the GitHub repository's samples for more quickstart code snippets. - * - * @deprecated This class is deprecated and will be removed in the next major version update. - */ -@Deprecated @Generated("by gapic-generator-java") -public class DeprecatedServiceClient implements BackgroundResource { - private final DeprecatedServiceSettings settings; - private final DeprecatedServiceStub stub; +public class DeprecatedServiceClientTest { + private static MockDeprecatedService mockDeprecatedService; + private static MockServiceHelper mockServiceHelper; + private DeprecatedServiceClient client; + private LocalChannelProvider channelProvider; - /** Constructs an instance of DeprecatedServiceClient with default settings. */ - public static final DeprecatedServiceClient create() throws IOException { - return create(DeprecatedServiceSettings.newBuilder().build()); + @BeforeClass + public static void startStaticServer() { + mockDeprecatedService = new MockDeprecatedService(); + mockServiceHelper = + new MockServiceHelper( + UUID.randomUUID().toString(), Arrays.asList(mockDeprecatedService)); + mockServiceHelper.start(); } - /** - * Constructs an instance of DeprecatedServiceClient, using the given settings. The channels are - * created based on the settings passed in, or defaults for any settings that are not set. - */ - public static final DeprecatedServiceClient create(DeprecatedServiceSettings settings) - throws IOException { - return new DeprecatedServiceClient(settings); + @AfterClass + public static void stopServer() { + mockServiceHelper.stop(); } - /** - * Constructs an instance of DeprecatedServiceClient, using the given stub for making calls. This - * is for advanced usage - prefer using create(DeprecatedServiceSettings). - */ - @BetaApi("A restructuring of stub classes is planned, so this may break in the future") - public static final DeprecatedServiceClient create(DeprecatedServiceStub stub) { - return new DeprecatedServiceClient(stub); + @Before + public void setUp() throws IOException { + mockServiceHelper.reset(); + channelProvider = mockServiceHelper.createChannelProvider(); + DeprecatedServiceSettings settings = + DeprecatedServiceSettings.newBuilder() + .setTransportChannelProvider(channelProvider) + .setCredentialsProvider(NoCredentialsProvider.create()) + .build(); + client = DeprecatedServiceClient.create(settings); } - /** - * Constructs an instance of DeprecatedServiceClient, using the given settings. This is protected - * so that it is easy to make a subclass, but otherwise, the static factory methods should be - * preferred. - */ - protected DeprecatedServiceClient(DeprecatedServiceSettings settings) throws IOException { - this.settings = settings; - this.stub = ((DeprecatedServiceStubSettings) settings.getStubSettings()).createStub(); + @After + public void tearDown() throws Exception { + client.close(); } - @BetaApi("A restructuring of stub classes is planned, so this may break in the future") - protected DeprecatedServiceClient(DeprecatedServiceStub stub) { - this.settings = null; - this.stub = stub; - } + @Test + public void fastFibonacciTest() throws Exception { + Empty expectedResponse = Empty.newBuilder().build(); + mockDeprecatedService.addResponse(expectedResponse); - public final DeprecatedServiceSettings getSettings() { - return settings; - } + FibonacciRequest request = FibonacciRequest.newBuilder().setValue(111972721).build(); - @BetaApi("A restructuring of stub classes is planned, so this may break in the future") - public DeprecatedServiceStub getStub() { - return stub; - } + client.fastFibonacci(request); - // AUTO-GENERATED DOCUMENTATION AND METHOD. - /** - * Sample code: - * - *

{@code
-   * try (DeprecatedServiceClient deprecatedServiceClient = DeprecatedServiceClient.create()) {
-   *   FibonacciRequest request = FibonacciRequest.newBuilder().setValue(111972721).build();
-   *   deprecatedServiceClient.fastFibonacci(request);
-   * }
-   * }
- * - * @param request The request object containing all of the parameters for the API call. - * @throws com.google.api.gax.rpc.ApiException if the remote call fails - */ - public final void fastFibonacci(FibonacciRequest request) { - fastFibonacciCallable().call(request); - } + List actualRequests = mockDeprecatedService.getRequests(); + Assert.assertEquals(1, actualRequests.size()); + FibonacciRequest actualRequest = ((FibonacciRequest) actualRequests.get(0)); - // AUTO-GENERATED DOCUMENTATION AND METHOD. - /** - * Sample code: - * - *
{@code
-   * try (DeprecatedServiceClient deprecatedServiceClient = DeprecatedServiceClient.create()) {
-   *   FibonacciRequest request = FibonacciRequest.newBuilder().setValue(111972721).build();
-   *   ApiFuture future = deprecatedServiceClient.fastFibonacciCallable().futureCall(request);
-   *   // Do something.
-   *   future.get();
-   * }
-   * }
- */ - public final UnaryCallable fastFibonacciCallable() { - return stub.fastFibonacciCallable(); + Assert.assertEquals(request.getValue(), actualRequest.getValue()); + Assert.assertTrue( + channelProvider.isHeaderSent( + ApiClientHeaderProvider.getDefaultApiClientHeaderKey(), + GaxGrpcProperties.getDefaultApiClientHeaderPattern())); } - // AUTO-GENERATED DOCUMENTATION AND METHOD. - /** - * Sample code: - * - *
{@code
-   * try (DeprecatedServiceClient deprecatedServiceClient = DeprecatedServiceClient.create()) {
-   *   FibonacciRequest request = FibonacciRequest.newBuilder().setValue(111972721).build();
-   *   deprecatedServiceClient.slowFibonacci(request);
-   * }
-   * }
- * - * @param request The request object containing all of the parameters for the API call. - * @throws com.google.api.gax.rpc.ApiException if the remote call fails - * @deprecated This method is deprecated and will be removed in the next major version update. - */ - @Deprecated - public final void slowFibonacci(FibonacciRequest request) { - slowFibonacciCallable().call(request); - } + @Test + public void fastFibonacciExceptionTest() throws Exception { + StatusRuntimeException exception = new StatusRuntimeException(io.grpc.Status.INVALID_ARGUMENT); + mockDeprecatedService.addException(exception); - // AUTO-GENERATED DOCUMENTATION AND METHOD. - /** - * Sample code: - * - *
{@code
-   * try (DeprecatedServiceClient deprecatedServiceClient = DeprecatedServiceClient.create()) {
-   *   FibonacciRequest request = FibonacciRequest.newBuilder().setValue(111972721).build();
-   *   ApiFuture future = deprecatedServiceClient.slowFibonacciCallable().futureCall(request);
-   *   // Do something.
-   *   future.get();
-   * }
-   * }
- * - * @deprecated This method is deprecated and will be removed in the next major version update. - */ - @Deprecated - public final UnaryCallable slowFibonacciCallable() { - return stub.slowFibonacciCallable(); + try { + FibonacciRequest request = FibonacciRequest.newBuilder().setValue(111972721).build(); + client.fastFibonacci(request); + Assert.fail("No exception raised"); + } catch (InvalidArgumentException e) { + // Expected exception. + } } - @Override - public final void close() { - stub.close(); - } + @Test + public void slowFibonacciTest() throws Exception { + Empty expectedResponse = Empty.newBuilder().build(); + mockDeprecatedService.addResponse(expectedResponse); - @Override - public void shutdown() { - stub.shutdown(); - } + FibonacciRequest request = FibonacciRequest.newBuilder().setValue(111972721).build(); - @Override - public boolean isShutdown() { - return stub.isShutdown(); - } + client.slowFibonacci(request); - @Override - public boolean isTerminated() { - return stub.isTerminated(); - } + List actualRequests = mockDeprecatedService.getRequests(); + Assert.assertEquals(1, actualRequests.size()); + FibonacciRequest actualRequest = ((FibonacciRequest) actualRequests.get(0)); - @Override - public void shutdownNow() { - stub.shutdownNow(); + Assert.assertEquals(request.getValue(), actualRequest.getValue()); + Assert.assertTrue( + channelProvider.isHeaderSent( + ApiClientHeaderProvider.getDefaultApiClientHeaderKey(), + GaxGrpcProperties.getDefaultApiClientHeaderPattern())); } - @Override - public boolean awaitTermination(long duration, TimeUnit unit) throws InterruptedException { - return stub.awaitTermination(duration, unit); + @Test + public void slowFibonacciExceptionTest() throws Exception { + StatusRuntimeException exception = new StatusRuntimeException(io.grpc.Status.INVALID_ARGUMENT); + mockDeprecatedService.addException(exception); + + try { + FibonacciRequest request = FibonacciRequest.newBuilder().setValue(111972721).build(); + client.slowFibonacci(request); + Assert.fail("No exception raised"); + } catch (InvalidArgumentException e) { + // Expected exception. + } } } From 0561d5b8d2fdb8dd265ab9ccc95b01ca42c305ab Mon Sep 17 00:00:00 2001 From: vam-google Date: Wed, 21 Apr 2021 16:34:46 -0700 Subject: [PATCH 03/16] chore: Pre-DIREGAPIC Refactoring --- BUILD.bazel | 26 - rules_java_gapic/java_gapic.bzl | 14 +- .../com/google/api/generator/MainDumper.java | 50 -- .../google/api/generator/MainFromFile.java | 60 -- .../api/generator/gapic/composer/BUILD.bazel | 1 - .../generator/gapic/composer/Composer.java | 48 +- .../grpc/GrpcServiceStubClassComposer.java | 2 +- .../gapic/composer/httpjson/BUILD.bazel | 52 -- ...onServiceCallableFactoryClassComposer.java | 100 ---- .../HttpJsonServiceStubClassComposer.java | 513 ------------------ .../ServiceClientTestClassComposer.java | 508 ----------------- .../ServiceSettingsClassComposer.java | 42 -- .../ServiceStubSettingsClassComposer.java | 176 ------ .../generator/gapic/model/GapicContext.java | 5 - .../gapic/model/HttpRuleBindings.java | 58 -- .../api/generator/gapic/model/Method.java | 9 +- .../api/generator/gapic/model/Transport.java | 25 - .../gapic/protoparser/HttpRuleParser.java | 85 ++- .../generator/gapic/protoparser/Parser.java | 11 +- .../protoparser/PluginArgumentParser.java | 33 +- .../composer/common/TestProtoLoader.java | 12 +- .../composer/grpc/GrpcTestProtoLoader.java | 3 +- .../gapic/protoparser/HttpRuleParserTest.java | 23 +- 23 files changed, 80 insertions(+), 1776 deletions(-) delete mode 100644 src/main/java/com/google/api/generator/MainDumper.java delete mode 100644 src/main/java/com/google/api/generator/MainFromFile.java delete mode 100644 src/main/java/com/google/api/generator/gapic/composer/httpjson/BUILD.bazel delete mode 100644 src/main/java/com/google/api/generator/gapic/composer/httpjson/HttpJsonServiceCallableFactoryClassComposer.java delete mode 100644 src/main/java/com/google/api/generator/gapic/composer/httpjson/HttpJsonServiceStubClassComposer.java delete mode 100644 src/main/java/com/google/api/generator/gapic/composer/httpjson/ServiceClientTestClassComposer.java delete mode 100644 src/main/java/com/google/api/generator/gapic/composer/httpjson/ServiceSettingsClassComposer.java delete mode 100644 src/main/java/com/google/api/generator/gapic/composer/httpjson/ServiceStubSettingsClassComposer.java delete mode 100644 src/main/java/com/google/api/generator/gapic/model/HttpRuleBindings.java delete mode 100644 src/main/java/com/google/api/generator/gapic/model/Transport.java diff --git a/BUILD.bazel b/BUILD.bazel index fa2b80f062..8823250fca 100644 --- a/BUILD.bazel +++ b/BUILD.bazel @@ -45,32 +45,6 @@ java_binary( ], ) -java_binary( - name = "protoc-gen-java_dumper", - main_class = "com.google.api.generator.MainDumper", - runtime_deps = [ - "//src/main/java/com/google/api/generator", - "//src/main/java/com/google/api/generator/gapic", - "@com_google_googleapis//google/api:api_java_proto", - "@com_google_googleapis//google/longrunning:longrunning_java_proto", - "@com_google_guava_guava", - "@com_google_protobuf//:protobuf_java", - ], -) - -java_binary( - name = "protoc-gen-java_gapicfromfile", - main_class = "com.google.api.generator.MainFromFile", - runtime_deps = [ - "//src/main/java/com/google/api/generator", - "//src/main/java/com/google/api/generator/gapic", - "@com_google_googleapis//google/api:api_java_proto", - "@com_google_googleapis//google/longrunning:longrunning_java_proto", - "@com_google_guava_guava", - "@com_google_protobuf//:protobuf_java", - ], -) - # google-java-format java_binary( name = "google_java_format_binary", diff --git a/rules_java_gapic/java_gapic.bzl b/rules_java_gapic/java_gapic.bzl index f366e42897..e9cb1ec064 100644 --- a/rules_java_gapic/java_gapic.bzl +++ b/rules_java_gapic/java_gapic.bzl @@ -127,14 +127,12 @@ def java_gapic_library( service_yaml = None, deps = [], test_deps = [], - transport = None, - java_generator_name = "java_gapic", **kwargs): file_args_dict = {} if grpc_service_config: file_args_dict[grpc_service_config] = "grpc-service-config" - elif transport != "rest": + else: for keyword in NO_GRPC_CONFIG_ALLOWLIST: if keyword not in name: fail("Missing a gRPC service config file") @@ -159,25 +157,21 @@ def java_gapic_library( srcjar_name = name + "_srcjar" raw_srcjar_name = srcjar_name + "_raw" output_suffix = ".srcjar" - opt_args = [] - - if transport: - opt_args.append("transport=%s" % transport) # Produces the GAPIC metadata file if this flag is set. to any value. # Protoc invocation: --java_gapic_opt=metadata plugin_args = ["metadata"] + _java_generator_name = "java_gapic" proto_custom_library( name = raw_srcjar_name, deps = srcs, - plugin = Label("@gapic_generator_java//:protoc-gen-%s" % java_generator_name), + plugin = Label("@gapic_generator_java//:protoc-gen-%s" % _java_generator_name), plugin_args = plugin_args, plugin_file_args = {}, opt_file_args = file_args_dict, - output_type = java_generator_name, + output_type = _java_generator_name, output_suffix = output_suffix, - opt_args = opt_args, **kwargs ) diff --git a/src/main/java/com/google/api/generator/MainDumper.java b/src/main/java/com/google/api/generator/MainDumper.java deleted file mode 100644 index 018106b883..0000000000 --- a/src/main/java/com/google/api/generator/MainDumper.java +++ /dev/null @@ -1,50 +0,0 @@ -// Copyright 2021 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 -// -// http://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. - -package com.google.api.generator; - -import com.google.api.AnnotationsProto; -import com.google.api.ClientProto; -import com.google.api.FieldBehaviorProto; -import com.google.api.ResourceProto; -import com.google.longrunning.OperationsProto; -import com.google.protobuf.ExtensionRegistry; -import com.google.protobuf.compiler.PluginProtos.CodeGeneratorRequest; -import com.google.protobuf.compiler.PluginProtos.CodeGeneratorResponse; -import java.io.IOException; - -public class MainDumper { - public static void main(String[] args) throws IOException { - ExtensionRegistry registry = ExtensionRegistry.newInstance(); - registerAllExtensions(registry); - CodeGeneratorRequest request = CodeGeneratorRequest.parseFrom(System.in, registry); - - CodeGeneratorResponse.Builder response = CodeGeneratorResponse.newBuilder(); - response - .setSupportedFeatures(CodeGeneratorResponse.Feature.FEATURE_PROTO3_OPTIONAL_VALUE) - .addFileBuilder() - .setName("desc-dump.bin") - .setContentBytes(request.toByteString()); - response.build().writeTo(System.out); - } - - /** Register all extensions needed to process API protofiles. */ - private static void registerAllExtensions(ExtensionRegistry extensionRegistry) { - OperationsProto.registerAllExtensions(extensionRegistry); - AnnotationsProto.registerAllExtensions(extensionRegistry); - ClientProto.registerAllExtensions(extensionRegistry); - ResourceProto.registerAllExtensions(extensionRegistry); - FieldBehaviorProto.registerAllExtensions(extensionRegistry); - } -} diff --git a/src/main/java/com/google/api/generator/MainFromFile.java b/src/main/java/com/google/api/generator/MainFromFile.java deleted file mode 100644 index e93f2db6ca..0000000000 --- a/src/main/java/com/google/api/generator/MainFromFile.java +++ /dev/null @@ -1,60 +0,0 @@ -// Copyright 2021 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 -// -// http://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. - -package com.google.api.generator; - -import com.google.api.AnnotationsProto; -import com.google.api.ClientProto; -import com.google.api.FieldBehaviorProto; -import com.google.api.ResourceProto; -import com.google.api.generator.gapic.Generator; -import com.google.longrunning.OperationsProto; -import com.google.protobuf.Descriptors.DescriptorValidationException; -import com.google.protobuf.ExtensionRegistry; -import com.google.protobuf.compiler.PluginProtos.CodeGeneratorRequest; -import com.google.protobuf.compiler.PluginProtos.CodeGeneratorResponse; -import java.io.FileInputStream; -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; - -public class MainFromFile { - public static void main(String[] args) - throws IOException, InterruptedException, DescriptorValidationException { - ExtensionRegistry registry = ExtensionRegistry.newInstance(); - registerAllExtensions(registry); - - String inputFile = args[0]; - String outputFile = args[1]; - - try (InputStream inputStream = new FileInputStream(inputFile); - OutputStream outputStream = new FileOutputStream(outputFile); ) { - CodeGeneratorRequest request = CodeGeneratorRequest.parseFrom(inputStream, registry); - CodeGeneratorResponse response = Generator.generateGapic(request); - response.writeTo(outputStream); - } catch (IOException ex) { - ex.printStackTrace(); - } - } - - /** Register all extensions needed to process API protofiles. */ - private static void registerAllExtensions(ExtensionRegistry extensionRegistry) { - OperationsProto.registerAllExtensions(extensionRegistry); - AnnotationsProto.registerAllExtensions(extensionRegistry); - ClientProto.registerAllExtensions(extensionRegistry); - ResourceProto.registerAllExtensions(extensionRegistry); - FieldBehaviorProto.registerAllExtensions(extensionRegistry); - } -} diff --git a/src/main/java/com/google/api/generator/gapic/composer/BUILD.bazel b/src/main/java/com/google/api/generator/gapic/composer/BUILD.bazel index 6610ba4f91..ae08ecda8b 100644 --- a/src/main/java/com/google/api/generator/gapic/composer/BUILD.bazel +++ b/src/main/java/com/google/api/generator/gapic/composer/BUILD.bazel @@ -21,7 +21,6 @@ java_library( "//src/main/java/com/google/api/generator/gapic/composer/common", "//src/main/java/com/google/api/generator/gapic/composer/defaultvalue", "//src/main/java/com/google/api/generator/gapic/composer/grpc", - "//src/main/java/com/google/api/generator/gapic/composer/httpjson", "//src/main/java/com/google/api/generator/gapic/composer/resourcename", "//src/main/java/com/google/api/generator/gapic/composer/samplecode", "//src/main/java/com/google/api/generator/gapic/composer/store", diff --git a/src/main/java/com/google/api/generator/gapic/composer/Composer.java b/src/main/java/com/google/api/generator/gapic/composer/Composer.java index 2d5b7c0e75..8dd716eb2a 100644 --- a/src/main/java/com/google/api/generator/gapic/composer/Composer.java +++ b/src/main/java/com/google/api/generator/gapic/composer/Composer.java @@ -26,8 +26,6 @@ import com.google.api.generator.gapic.composer.grpc.ServiceClientTestClassComposer; import com.google.api.generator.gapic.composer.grpc.ServiceSettingsClassComposer; import com.google.api.generator.gapic.composer.grpc.ServiceStubSettingsClassComposer; -import com.google.api.generator.gapic.composer.httpjson.HttpJsonServiceCallableFactoryClassComposer; -import com.google.api.generator.gapic.composer.httpjson.HttpJsonServiceStubClassComposer; import com.google.api.generator.gapic.composer.resourcename.ResourceNameHelperClassComposer; import com.google.api.generator.gapic.model.GapicClass; import com.google.api.generator.gapic.model.GapicClass.Kind; @@ -35,7 +33,6 @@ import com.google.api.generator.gapic.model.GapicPackageInfo; import com.google.api.generator.gapic.model.ResourceName; import com.google.api.generator.gapic.model.Service; -import com.google.api.generator.gapic.model.Transport; import com.google.common.annotations.VisibleForTesting; import java.util.ArrayList; import java.util.List; @@ -83,20 +80,9 @@ public static List generateStubClasses(GapicContext context) { .forEach( s -> { clazzes.add(ServiceStubClassComposer.instance().generate(context, s)); - if (context.transport() == Transport.REST) { - clazzes.add( - com.google.api.generator.gapic.composer.httpjson - .ServiceStubSettingsClassComposer.instance() - .generate(context, s)); - clazzes.add( - HttpJsonServiceCallableFactoryClassComposer.instance().generate(context, s)); - clazzes.add(HttpJsonServiceStubClassComposer.instance().generate(context, s)); - } else { - clazzes.add(ServiceStubSettingsClassComposer.instance().generate(context, s)); - clazzes.add( - GrpcServiceCallableFactoryClassComposer.instance().generate(context, s)); - clazzes.add(GrpcServiceStubClassComposer.instance().generate(context, s)); - } + clazzes.add(ServiceStubSettingsClassComposer.instance().generate(context, s)); + clazzes.add(GrpcServiceCallableFactoryClassComposer.instance().generate(context, s)); + clazzes.add(GrpcServiceStubClassComposer.instance().generate(context, s)); }); return clazzes; } @@ -108,14 +94,7 @@ public static List generateClientSettingsClasses(GapicContext contex .forEach( s -> { clazzes.add(ServiceClientClassComposer.instance().generate(context, s)); - if (context.transport() == Transport.REST) { - clazzes.add( - com.google.api.generator.gapic.composer.httpjson.ServiceSettingsClassComposer - .instance() - .generate(context, s)); - } else { - clazzes.add(ServiceSettingsClassComposer.instance().generate(context, s)); - } + clazzes.add(ServiceSettingsClassComposer.instance().generate(context, s)); }); return clazzes; } @@ -124,28 +103,15 @@ public static List generateMockClasses(GapicContext context, List clazzes = new ArrayList<>(); services.forEach( s -> { - if (context.transport() == Transport.REST) { - // REST transport tests donot not use mock services. - } else { - clazzes.add(MockServiceClassComposer.instance().generate(context, s)); - clazzes.add(MockServiceImplClassComposer.instance().generate(context, s)); - } + clazzes.add(MockServiceClassComposer.instance().generate(context, s)); + clazzes.add(MockServiceImplClassComposer.instance().generate(context, s)); }); return clazzes; } public static List generateTestClasses(GapicContext context) { return context.services().stream() - .map( - s -> { - if (context.transport() == Transport.REST) { - return com.google.api.generator.gapic.composer.httpjson - .ServiceClientTestClassComposer.instance() - .generate(context, s); - } else { - return ServiceClientTestClassComposer.instance().generate(context, s); - } - }) + .map(s -> ServiceClientTestClassComposer.instance().generate(context, s)) .collect(Collectors.toList()); } diff --git a/src/main/java/com/google/api/generator/gapic/composer/grpc/GrpcServiceStubClassComposer.java b/src/main/java/com/google/api/generator/gapic/composer/grpc/GrpcServiceStubClassComposer.java index e92c6d67f0..41eeca7644 100644 --- a/src/main/java/com/google/api/generator/gapic/composer/grpc/GrpcServiceStubClassComposer.java +++ b/src/main/java/com/google/api/generator/gapic/composer/grpc/GrpcServiceStubClassComposer.java @@ -265,7 +265,7 @@ private AnonymousClassExpr createRequestParamsExtractorAnonClass(Method method) VariableExpr.withVariable( Variable.builder().setType(method.inputType()).setName("request").build()); - for (String httpBindingFieldName : method.httpBindings().pathParameters()) { + for (String httpBindingFieldName : method.httpBindings()) { // Handle foo.bar cases by descending into the subfields. MethodInvocationExpr.Builder requestFieldGetterExprBuilder = MethodInvocationExpr.builder().setExprReferenceExpr(requestVarExpr); diff --git a/src/main/java/com/google/api/generator/gapic/composer/httpjson/BUILD.bazel b/src/main/java/com/google/api/generator/gapic/composer/httpjson/BUILD.bazel deleted file mode 100644 index 44ed244337..0000000000 --- a/src/main/java/com/google/api/generator/gapic/composer/httpjson/BUILD.bazel +++ /dev/null @@ -1,52 +0,0 @@ -load("@rules_java//java:defs.bzl", "java_library") - -package(default_visibility = ["//visibility:public"]) - -filegroup( - name = "httpjson_files", - srcs = glob(["*.java"]), -) - -java_library( - name = "httpjson", - srcs = [ - ":httpjson_files", - ], - deps = [ - "//:service_config_java_proto", - "//src/main/java/com/google/api/generator/engine/ast", - "//src/main/java/com/google/api/generator/engine/writer", - "//src/main/java/com/google/api/generator/gapic:status_java_proto", - "//src/main/java/com/google/api/generator/gapic/composer/common", - "//src/main/java/com/google/api/generator/gapic/composer/comment", - "//src/main/java/com/google/api/generator/gapic/composer/defaultvalue", - "//src/main/java/com/google/api/generator/gapic/composer/resourcename", - "//src/main/java/com/google/api/generator/gapic/composer/samplecode", - "//src/main/java/com/google/api/generator/gapic/composer/store", - "//src/main/java/com/google/api/generator/gapic/composer/utils", - "//src/main/java/com/google/api/generator/gapic/model", - "//src/main/java/com/google/api/generator/gapic/utils", - "//src/main/java/com/google/api/generator/util", - "@com_google_api_api_common//jar", - "@com_google_api_gax_java//gax:gax", - "@com_google_api_gax_java//gax:gax_testlib", - "@com_google_api_gax_java//gax-httpjson:gax_httpjson", - "@com_google_api_gax_java//gax-httpjson:gax_httpjson_testlib", - "@com_google_code_findbugs_jsr305//jar", - "@com_google_googleapis//gapic/metadata:metadata_java_proto", - "@com_google_googleapis//google/api:api_java_proto", - "@com_google_googleapis//google/longrunning:longrunning_java_proto", - "@com_google_googleapis//google/rpc:rpc_java_proto", - "@com_google_guava_guava//jar", - "@com_google_http_client_google_http_client//jar", - "@com_google_protobuf//:protobuf_java", - "@com_google_protobuf//:protobuf_java_util", - "@com_google_protobuf//java/core", - "@io_grpc_grpc_java//api", - "@io_grpc_grpc_java//protobuf", - "@io_grpc_grpc_java//stub", - "@javax_annotation_javax_annotation_api//jar", - "@junit_junit//jar", - "@org_threeten_threetenbp//jar", - ], -) diff --git a/src/main/java/com/google/api/generator/gapic/composer/httpjson/HttpJsonServiceCallableFactoryClassComposer.java b/src/main/java/com/google/api/generator/gapic/composer/httpjson/HttpJsonServiceCallableFactoryClassComposer.java deleted file mode 100644 index e5ac6a85f9..0000000000 --- a/src/main/java/com/google/api/generator/gapic/composer/httpjson/HttpJsonServiceCallableFactoryClassComposer.java +++ /dev/null @@ -1,100 +0,0 @@ -// Copyright 2021 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 -// -// http://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. - -package com.google.api.generator.gapic.composer.httpjson; - -import com.google.api.gax.core.BackgroundResource; -import com.google.api.gax.httpjson.ApiMessage; -import com.google.api.gax.httpjson.HttpJsonCallSettings; -import com.google.api.gax.httpjson.HttpJsonCallableFactory; -import com.google.api.gax.httpjson.HttpJsonStubCallableFactory; -import com.google.api.generator.engine.ast.MethodDefinition; -import com.google.api.generator.engine.ast.TypeNode; -import com.google.api.generator.engine.ast.ValueExpr; -import com.google.api.generator.gapic.composer.common.AbstractServiceCallableFactoryClassComposer; -import com.google.api.generator.gapic.composer.comment.StubCommentComposer; -import com.google.api.generator.gapic.composer.store.TypeStore; -import com.google.api.generator.gapic.composer.utils.ClassNames; -import java.util.Arrays; -import java.util.List; -import java.util.stream.Collectors; - -public class HttpJsonServiceCallableFactoryClassComposer - extends AbstractServiceCallableFactoryClassComposer { - private static final HttpJsonServiceCallableFactoryClassComposer INSTANCE = - new HttpJsonServiceCallableFactoryClassComposer(); - - private HttpJsonServiceCallableFactoryClassComposer() { - super( - createTypes(), - new StubCommentComposer("REST"), - new ClassNames("HttpJson"), - HttpJsonCallSettings.class, - HttpJsonCallableFactory.class, - BackgroundResource.class, - "httpJsonCallSettings"); - } - - public static HttpJsonServiceCallableFactoryClassComposer instance() { - return INSTANCE; - } - - private static TypeStore createTypes() { - TypeStore typeStore = createCommonTypes(); - typeStore.putAll( - Arrays.asList( - ApiMessage.class, - BackgroundResource.class, - HttpJsonCallSettings.class, - HttpJsonCallableFactory.class, - HttpJsonStubCallableFactory.class)); - return typeStore; - } - - @Override - protected List createClassImplements(TypeStore typeStore) { - return Arrays.asList( - TypeNode.withReference( - typeStore - .get("HttpJsonStubCallableFactory") - .reference() - .copyAndSetGenerics( - Arrays.asList( - typeStore.get("ApiMessage").reference(), - typeStore.get("BackgroundResource").reference())))); - } - - @Override - protected MethodDefinition createOperationCallableMethod(TypeStore typeStore) { - String methodVariantName = "Operation"; - String requestTemplateName = "RequestT"; - String responseTemplateName = "ResponseT"; - List methodTemplateNames = - Arrays.asList(requestTemplateName, responseTemplateName, "MetadataT"); - MethodDefinition method = - createGenericCallableMethod( - typeStore, - /*methodTemplateNames=*/ methodTemplateNames, - /*returnCallableKindName=*/ methodVariantName, - /*returnCallableTemplateNames=*/ methodTemplateNames, - /*methodVariantName=*/ methodVariantName, - /*httpJsonCallSettingsTemplateObjects=*/ Arrays.asList( - requestTemplateName, typeStore.get("ApiMessage")), - /*callSettingsVariantName=*/ methodVariantName, - /*callSettingsTemplateObjects=*/ methodTemplateNames.stream() - .map(n -> (Object) n) - .collect(Collectors.toList())); - return method.toBuilder().setReturnExpr(ValueExpr.createNullExpr()).build(); - } -} diff --git a/src/main/java/com/google/api/generator/gapic/composer/httpjson/HttpJsonServiceStubClassComposer.java b/src/main/java/com/google/api/generator/gapic/composer/httpjson/HttpJsonServiceStubClassComposer.java deleted file mode 100644 index 72a2a14a55..0000000000 --- a/src/main/java/com/google/api/generator/gapic/composer/httpjson/HttpJsonServiceStubClassComposer.java +++ /dev/null @@ -1,513 +0,0 @@ -// Copyright 2021 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 -// -// http://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. - -package com.google.api.generator.gapic.composer.httpjson; - -import com.google.api.client.http.HttpMethods; -import com.google.api.core.InternalApi; -import com.google.api.gax.httpjson.ApiMethodDescriptor; -import com.google.api.gax.httpjson.FieldsExtractor; -import com.google.api.gax.httpjson.HttpJsonCallSettings; -import com.google.api.gax.httpjson.HttpJsonStubCallableFactory; -import com.google.api.gax.httpjson.ProtoMessageRequestFormatter; -import com.google.api.gax.httpjson.ProtoMessageResponseParser; -import com.google.api.gax.httpjson.ProtoRestSerializer; -import com.google.api.generator.engine.ast.AnnotationNode; -import com.google.api.generator.engine.ast.AnonymousClassExpr; -import com.google.api.generator.engine.ast.AssignmentExpr; -import com.google.api.generator.engine.ast.ConcreteReference; -import com.google.api.generator.engine.ast.EnumRefExpr; -import com.google.api.generator.engine.ast.Expr; -import com.google.api.generator.engine.ast.ExprStatement; -import com.google.api.generator.engine.ast.MethodDefinition; -import com.google.api.generator.engine.ast.MethodInvocationExpr; -import com.google.api.generator.engine.ast.NewObjectExpr; -import com.google.api.generator.engine.ast.ScopeNode; -import com.google.api.generator.engine.ast.Statement; -import com.google.api.generator.engine.ast.StringObjectValue; -import com.google.api.generator.engine.ast.TypeNode; -import com.google.api.generator.engine.ast.ValueExpr; -import com.google.api.generator.engine.ast.Variable; -import com.google.api.generator.engine.ast.VariableExpr; -import com.google.api.generator.gapic.composer.common.AbstractServiceStubClassComposer; -import com.google.api.generator.gapic.composer.comment.StubCommentComposer; -import com.google.api.generator.gapic.composer.store.TypeStore; -import com.google.api.generator.gapic.composer.utils.ClassNames; -import com.google.api.generator.gapic.model.Method; -import com.google.api.generator.gapic.model.Service; -import com.google.api.generator.gapic.utils.JavaStyle; -import com.google.common.base.Preconditions; -import com.google.common.collect.ImmutableList; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collections; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Set; -import java.util.function.BiFunction; -import java.util.function.Function; -import java.util.stream.Collectors; - -public class HttpJsonServiceStubClassComposer extends AbstractServiceStubClassComposer { - private static final HttpJsonServiceStubClassComposer INSTANCE = - new HttpJsonServiceStubClassComposer(); - - protected HttpJsonServiceStubClassComposer() { - super( - createStaticTypes(), - new StubCommentComposer("REST"), - new ClassNames("HttpJson"), - HttpJsonCallSettings.class, - HttpJsonStubCallableFactory.class, - ApiMethodDescriptor.class, - null); - } - - public static HttpJsonServiceStubClassComposer instance() { - return INSTANCE; - } - - private static TypeStore createStaticTypes() { - TypeStore typeStore = createCommonStaticTypes(); - typeStore.putAll( - Arrays.asList( - ApiMethodDescriptor.class, - ArrayList.class, - FieldsExtractor.class, - InternalApi.class, - HashMap.class, - HttpJsonCallSettings.class, - HttpJsonStubCallableFactory.class, - Map.class, - ProtoMessageRequestFormatter.class, - ProtoMessageResponseParser.class, - ProtoRestSerializer.class)); - - return typeStore; - } - - @Override - protected Statement createMethodDescriptorVariableDecl( - Service service, Method protoMethod, VariableExpr methodDescriptorVarExpr) { - MethodInvocationExpr expr = - MethodInvocationExpr.builder() - .setMethodName("newBuilder") - .setStaticReferenceType( - getFixedTypeStore().get(ApiMethodDescriptor.class.getSimpleName())) - .setGenerics(methodDescriptorVarExpr.variable().type().reference().generics()) - .build(); - - BiFunction, Function> maker = - getMethodMaker(); - - String codeMethodNameArg = getProtoRpcFullMethodName(service, protoMethod); - expr = - maker - .apply( - "setFullMethodName", - Arrays.asList(ValueExpr.withValue(StringObjectValue.withValue(codeMethodNameArg)))) - .apply(expr); - - expr = maker.apply("setHttpMethod", getHttpMethodTypeExpr(protoMethod)).apply(expr); - expr = maker.apply("setRequestFormatter", getRequestFormatterExpr(protoMethod)).apply(expr); - - expr = maker.apply("setResponseParser", setResponseParserExpr(protoMethod)).apply(expr); - - expr = - MethodInvocationExpr.builder() - .setMethodName("build") - .setExprReferenceExpr(expr) - .setReturnType(methodDescriptorVarExpr.type()) - .build(); - - return ExprStatement.withExpr( - AssignmentExpr.builder() - .setVariableExpr( - methodDescriptorVarExpr - .toBuilder() - .setIsDecl(true) - .setScope(ScopeNode.PUBLIC) - .setIsStatic(true) - .setIsFinal(true) - .build()) - .setValueExpr(expr) - .build()); - } - - @Override - protected List createOperationsStubGetterMethod( - VariableExpr operationsStubVarExpr) { - return Collections.emptyList(); - } - - @Override - protected Expr createTransportSettingsInitExpr( - Method method, VariableExpr transportSettingsVarExpr, VariableExpr methodDescriptorVarExpr) { - MethodInvocationExpr callSettingsBuilderExpr = - MethodInvocationExpr.builder() - .setStaticReferenceType( - getFixedTypeStore().get(HttpJsonCallSettings.class.getSimpleName())) - .setGenerics(transportSettingsVarExpr.type().reference().generics()) - .setMethodName("newBuilder") - .build(); - callSettingsBuilderExpr = - MethodInvocationExpr.builder() - .setExprReferenceExpr(callSettingsBuilderExpr) - .setMethodName("setMethodDescriptor") - .setArguments(Arrays.asList(methodDescriptorVarExpr)) - .build(); - - callSettingsBuilderExpr = - MethodInvocationExpr.builder() - .setExprReferenceExpr(callSettingsBuilderExpr) - .setMethodName("build") - .setReturnType(transportSettingsVarExpr.type()) - .build(); - return AssignmentExpr.builder() - .setVariableExpr(transportSettingsVarExpr.toBuilder().setIsDecl(true).build()) - .setValueExpr(callSettingsBuilderExpr) - .build(); - } - - @Override - protected List createClassAnnotations(Service service) { - List annotations = super.createClassAnnotations(service); - - annotations.add( - AnnotationNode.builder() - .setType(getFixedTypeStore().get("BetaApi")) - .setDescription( - "A restructuring of stub classes is planned, so this may break in the future") - .build()); - return annotations; - } - - @Override - protected List createGetMethodDescriptorsMethod( - Service service, - TypeStore typeStore, - Map protoMethodNameToDescriptorVarExprs) { - - List bodyExprs = new ArrayList<>(); - - VariableExpr methodDescriptorsVarExpr = - VariableExpr.withVariable( - Variable.builder() - .setType( - TypeNode.withReference( - ConcreteReference.builder() - .setClazz(List.class) - .setGenerics( - Arrays.asList( - getFixedTypeStore().get("ApiMethodDescriptor").reference())) - .build())) - .setName("methodDescriptors") - .build()); - - bodyExprs.add( - AssignmentExpr.builder() - .setVariableExpr(methodDescriptorsVarExpr.toBuilder().setIsDecl(true).build()) - .setValueExpr( - NewObjectExpr.builder() - .setType(getFixedTypeStore().get("ArrayList")) - .setIsGeneric(true) - .build()) - .build()); - - for (VariableExpr methodDescriptorVarExpr : protoMethodNameToDescriptorVarExprs.values()) { - bodyExprs.add( - MethodInvocationExpr.builder() - .setExprReferenceExpr(methodDescriptorsVarExpr) - .setMethodName("add") - .setArguments(methodDescriptorVarExpr) - .build()); - } - - return Arrays.asList( - MethodDefinition.builder() - .setScope(ScopeNode.PUBLIC) - .setIsStatic(true) - .setReturnType(methodDescriptorsVarExpr.type()) - .setReturnExpr(methodDescriptorsVarExpr) - .setAnnotations( - Arrays.asList(AnnotationNode.withType(getFixedTypeStore().get("InternalApi")))) - .setName("getMethodDescriptors") - .setBody(bodyExprs.stream().map(ExprStatement::withExpr).collect(Collectors.toList())) - .build()); - } - - private BiFunction, Function> - getMethodMaker() { - return (mName, argExpr) -> - (m) -> - MethodInvocationExpr.builder() - .setMethodName(mName) - .setArguments(argExpr) - .setExprReferenceExpr(m) - .build(); - } - - private List getRequestFormatterExpr(Method protoMethod) { - BiFunction, Function> - methodMaker = getMethodMaker(); - - MethodInvocationExpr expr = - MethodInvocationExpr.builder() - .setStaticReferenceType( - getFixedTypeStore().get(ProtoMessageRequestFormatter.class.getSimpleName())) - .setMethodName("newBuilder") - .setGenerics(Collections.singletonList(protoMethod.inputType().reference())) - // .setArguments(Arrays.asList(m)) - .build(); - - TypeNode extractorVarType = - TypeNode.withReference( - ConcreteReference.builder() - .setClazz(Map.class) - .setGenerics(TypeNode.STRING.reference(), TypeNode.STRING.reference()) - .build()); - - expr = - methodMaker - .apply( - "setPath", - Arrays.asList( - ValueExpr.withValue( - StringObjectValue.withValue(protoMethod.httpBindings().pattern())), - createFieldsExtractorAnonClass( - protoMethod, - extractorVarType, - protoMethod.httpBindings().pathParameters(), - "putPathParam"))) - .apply(expr); - - TypeNode fieldsVarGenericType = - TypeNode.withReference( - ConcreteReference.builder() - .setClazz(List.class) - .setGenerics(TypeNode.STRING.reference()) - .build()); - - extractorVarType = - TypeNode.withReference( - ConcreteReference.builder() - .setClazz(Map.class) - .setGenerics(TypeNode.STRING.reference(), fieldsVarGenericType.reference()) - .build()); - - expr = - methodMaker - .apply( - "setQueryParamsExtractor", - Arrays.asList( - createFieldsExtractorAnonClass( - protoMethod, - extractorVarType, - protoMethod.httpBindings().queryParameters(), - "putQueryParam"))) - .apply(expr); - - extractorVarType = TypeNode.STRING; - expr = - methodMaker - .apply( - "setRequestBodyExtractor", - Arrays.asList( - createFieldsExtractorAnonClass( - protoMethod, - extractorVarType, - protoMethod.httpBindings().bodyParameters(), - "toBody"))) - .apply(expr); - expr = methodMaker.apply("build", Collections.emptyList()).apply(expr); - - return Collections.singletonList(expr); - } - - private List setResponseParserExpr(Method protoMethod) { - BiFunction, Function> - methodMaker = getMethodMaker(); - - MethodInvocationExpr expr = - MethodInvocationExpr.builder() - .setStaticReferenceType( - getFixedTypeStore().get(ProtoMessageResponseParser.class.getSimpleName())) - .setMethodName("newBuilder") - .setGenerics(Collections.singletonList(protoMethod.outputType().reference())) - // .setArguments(Arrays.asList(m)) - .build(); - - expr = - methodMaker - .apply( - "setDefaultInstance", - Arrays.asList( - MethodInvocationExpr.builder() - .setStaticReferenceType(protoMethod.outputType()) - .setMethodName("getDefaultInstance") - .setReturnType(protoMethod.outputType()) - .build())) - .apply(expr); - expr = methodMaker.apply("build", Collections.emptyList()).apply(expr); - - return Collections.singletonList(expr); - } - - private Expr createFieldsExtractorAnonClass( - Method method, - TypeNode extractorReturnType, - Set httpBindingFieldNames, - String serializerMethodName) { - Preconditions.checkState( - method.hasHttpBindings(), String.format("Method %s has no HTTP binding", method.name())); - - List bodyExprs = new ArrayList<>(); - - Expr returnExpr = null; - VariableExpr fieldsVarExpr = null; - if (!extractorReturnType.isProtoPrimitiveType()) { - fieldsVarExpr = - VariableExpr.withVariable( - Variable.builder().setName("fields").setType(extractorReturnType).build()); - Expr fieldsAssignExpr = - AssignmentExpr.builder() - .setVariableExpr(fieldsVarExpr.toBuilder().setIsDecl(true).build()) - .setValueExpr( - NewObjectExpr.builder() - .setType(getFixedTypeStore().get(HashMap.class.getSimpleName())) - .setIsGeneric(true) - .build()) - .build(); - - bodyExprs.add(fieldsAssignExpr); - returnExpr = fieldsVarExpr; - } - - TypeNode serializerVarType = - TypeNode.withReference( - ConcreteReference.builder() - .setClazz(ProtoRestSerializer.class) - .setGenerics(method.inputType().reference()) - .build()); - - VariableExpr serializerVarExpr = - VariableExpr.withVariable( - Variable.builder().setName("serializer").setType(serializerVarType).build()); - - Expr serializerAssignExpr = - AssignmentExpr.builder() - .setVariableExpr(serializerVarExpr.toBuilder().setIsDecl(true).build()) - .setValueExpr( - MethodInvocationExpr.builder() - .setStaticReferenceType( - getFixedTypeStore().get(ProtoRestSerializer.class.getSimpleName())) - .setMethodName("create") - .setReturnType(serializerVarType) - .build()) - .build(); - - bodyExprs.add(serializerAssignExpr); - - VariableExpr requestVarExpr = - VariableExpr.withVariable( - Variable.builder().setType(method.inputType()).setName("request").build()); - - for (String httpBindingFieldName : httpBindingFieldNames) { - // Handle foo.bar cases by descending into the subfields. - MethodInvocationExpr.Builder requestFieldGetterExprBuilder = - MethodInvocationExpr.builder().setExprReferenceExpr(requestVarExpr); - String[] descendantFields = httpBindingFieldName.split("\\."); - for (int i = 0; i < descendantFields.length; i++) { - String currFieldName = descendantFields[i]; - String bindingFieldMethodName = - String.format("get%s", JavaStyle.toUpperCamelCase(currFieldName)); - requestFieldGetterExprBuilder = - requestFieldGetterExprBuilder.setMethodName(bindingFieldMethodName); - if (i < descendantFields.length - 1) { - requestFieldGetterExprBuilder = - MethodInvocationExpr.builder() - .setExprReferenceExpr(requestFieldGetterExprBuilder.build()); - } - } - - MethodInvocationExpr requestBuilderExpr = requestFieldGetterExprBuilder.build(); - - ImmutableList.Builder paramsPutArgs = ImmutableList.builder(); - if (fieldsVarExpr != null) { - paramsPutArgs.add(fieldsVarExpr); - } - paramsPutArgs.add( - ValueExpr.withValue( - StringObjectValue.withValue(JavaStyle.toLowerCamelCase(httpBindingFieldName)))); - paramsPutArgs.add(requestBuilderExpr); - - if (fieldsVarExpr == null) { - Expr paramsPutExpr = - MethodInvocationExpr.builder() - .setExprReferenceExpr(serializerVarExpr) - .setMethodName(serializerMethodName) - .setArguments(paramsPutArgs.build()) - .setReturnType(extractorReturnType) - .build(); - - returnExpr = paramsPutExpr; - } else { - Expr paramsPutExpr = - MethodInvocationExpr.builder() - .setExprReferenceExpr(serializerVarExpr) - .setMethodName(serializerMethodName) - .setArguments(paramsPutArgs.build()) - .build(); - bodyExprs.add(paramsPutExpr); - } - } - - if (httpBindingFieldNames.isEmpty()) { - bodyExprs = Collections.emptyList(); - returnExpr = ValueExpr.createNullExpr(); - } - - MethodDefinition extractMethod = - MethodDefinition.builder() - .setIsOverride(true) - .setScope(ScopeNode.PUBLIC) - .setReturnType(extractorReturnType) - .setName("extract") - .setArguments(requestVarExpr.toBuilder().setIsDecl(true).build()) - .setBody(bodyExprs.stream().map(ExprStatement::withExpr).collect(Collectors.toList())) - .setReturnExpr(returnExpr) - .build(); - - TypeNode anonClassType = - TypeNode.withReference( - ConcreteReference.builder() - .setClazz(FieldsExtractor.class) - .setGenerics(method.inputType().reference(), extractorReturnType.reference()) - .build()); - - return AnonymousClassExpr.builder().setType(anonClassType).setMethods(extractMethod).build(); - } - - private List getHttpMethodTypeExpr(Method protoMethod) { - EnumRefExpr expr = - EnumRefExpr.builder() - .setName(protoMethod.httpBindings().httpVerb()) - .setType( - TypeNode.withReference( - ConcreteReference.builder().setClazz(HttpMethods.class).build())) - .build(); - return Collections.singletonList(expr); - } -} diff --git a/src/main/java/com/google/api/generator/gapic/composer/httpjson/ServiceClientTestClassComposer.java b/src/main/java/com/google/api/generator/gapic/composer/httpjson/ServiceClientTestClassComposer.java deleted file mode 100644 index a3b9696351..0000000000 --- a/src/main/java/com/google/api/generator/gapic/composer/httpjson/ServiceClientTestClassComposer.java +++ /dev/null @@ -1,508 +0,0 @@ -// Copyright 2021 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 -// -// http://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. - -package com.google.api.generator.gapic.composer.httpjson; - -import com.google.api.gax.httpjson.ApiMethodDescriptor; -import com.google.api.gax.httpjson.GaxHttpJsonProperties; -import com.google.api.gax.httpjson.testing.MockHttpService; -import com.google.api.gax.rpc.ApiClientHeaderProvider; -import com.google.api.gax.rpc.ApiException; -import com.google.api.gax.rpc.ApiExceptionFactory; -import com.google.api.gax.rpc.StatusCode.Code; -import com.google.api.gax.rpc.testing.FakeStatusCode; -import com.google.api.generator.engine.ast.AnnotationNode; -import com.google.api.generator.engine.ast.AssignmentExpr; -import com.google.api.generator.engine.ast.ConcreteReference; -import com.google.api.generator.engine.ast.EnumRefExpr; -import com.google.api.generator.engine.ast.Expr; -import com.google.api.generator.engine.ast.ExprStatement; -import com.google.api.generator.engine.ast.MethodDefinition; -import com.google.api.generator.engine.ast.MethodInvocationExpr; -import com.google.api.generator.engine.ast.NewObjectExpr; -import com.google.api.generator.engine.ast.PrimitiveValue; -import com.google.api.generator.engine.ast.ScopeNode; -import com.google.api.generator.engine.ast.Statement; -import com.google.api.generator.engine.ast.TypeNode; -import com.google.api.generator.engine.ast.ValueExpr; -import com.google.api.generator.engine.ast.Variable; -import com.google.api.generator.engine.ast.VariableExpr; -import com.google.api.generator.gapic.composer.common.AbstractServiceClientTestClassComposer; -import com.google.api.generator.gapic.composer.store.TypeStore; -import com.google.api.generator.gapic.composer.utils.ClassNames; -import com.google.api.generator.gapic.model.GapicContext; -import com.google.api.generator.gapic.model.Message; -import com.google.api.generator.gapic.model.Method; -import com.google.api.generator.gapic.model.MethodArgument; -import com.google.api.generator.gapic.model.ResourceName; -import com.google.api.generator.gapic.model.Service; -import com.google.api.generator.gapic.utils.JavaStyle; -import com.google.common.collect.ImmutableList; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.LinkedHashMap; -import java.util.List; -import java.util.Map; -import java.util.function.BiFunction; -import java.util.function.Function; -import java.util.stream.Collectors; - -public class ServiceClientTestClassComposer extends AbstractServiceClientTestClassComposer { - private static final String MOCK_SERVICE_VAR_NAME = "mockService"; - private static final String METHOD_DESCRIPTOR_NAME_PATTERN = "%sMethodDescriptor"; - - private static final ServiceClientTestClassComposer INSTANCE = - new ServiceClientTestClassComposer(); - - protected ServiceClientTestClassComposer() { - super(createTypes(), new ClassNames("HttpJson")); - } - - public static ServiceClientTestClassComposer instance() { - return INSTANCE; - } - - private static TypeStore createTypes() { - TypeStore typeStore = createCommonTypes(); - typeStore.putAll( - Arrays.asList( - ApiClientHeaderProvider.class, - ApiException.class, - ApiExceptionFactory.class, - ApiMethodDescriptor.class, - Code.class, - Exception.class, - FakeStatusCode.class, - GaxHttpJsonProperties.class, - ImmutableList.class, - MockHttpService.class, - String.class)); - return typeStore; - } - - @Override - protected Map createClassMemberVarExprs( - Service service, GapicContext context, TypeStore typeStore) { - BiFunction varExprFn = - (name, type) -> - VariableExpr.withVariable(Variable.builder().setName(name).setType(type).build()); - Map fields = new LinkedHashMap<>(); - fields.put( - MOCK_SERVICE_VAR_NAME, getFixedTypeStore().get(MockHttpService.class.getSimpleName())); - fields.put(CLIENT_VAR_NAME, typeStore.get(ClassNames.getServiceClientClassName(service))); - return fields.entrySet().stream() - .collect(Collectors.toMap(e -> e.getKey(), e -> varExprFn.apply(e.getKey(), e.getValue()))); - } - - @Override - protected List createClassMemberFieldDecls( - Map classMemberVarExprs) { - return classMemberVarExprs.values().stream() - .map( - v -> - ExprStatement.withExpr( - v.toBuilder() - .setIsDecl(true) - .setScope(ScopeNode.PRIVATE) - .setIsStatic(true) - .build())) - .collect(Collectors.toList()); - } - - @Override - protected MethodDefinition createStartStaticServerMethod( - Service service, - GapicContext context, - Map classMemberVarExprs, - TypeStore typeStore) { - - VariableExpr mockServiceVarExpr = classMemberVarExprs.get(MOCK_SERVICE_VAR_NAME); - VariableExpr clientVarExpr = classMemberVarExprs.get(CLIENT_VAR_NAME); - TypeNode settingsType = typeStore.get(ClassNames.getServiceSettingsClassName(service)); - TypeNode transportStubType = - typeStore.get(getClassNames().getTransportServiceStubClassName(service)); - - Function> methodBuilderFn = - methodExpr -> - (mName, argExpr) -> - MethodInvocationExpr.builder() - .setExprReferenceExpr(methodExpr) - .setMethodName(mName) - .setArguments(Arrays.asList(argExpr)) - .build(); - - Expr initMockServiceExpr = - AssignmentExpr.builder() - .setVariableExpr(mockServiceVarExpr) - .setValueExpr( - NewObjectExpr.builder() - .setType(mockServiceVarExpr.type()) - .setArguments( - MethodInvocationExpr.builder() - .setStaticReferenceType(transportStubType) - .setMethodName("getMethodDescriptors") - .build(), - MethodInvocationExpr.builder() - .setStaticReferenceType(settingsType) - .setMethodName("getDefaultEndpoint") - .build()) - .build()) - .build(); - - VariableExpr localSettingsVarExpr = - VariableExpr.withVariable( - Variable.builder().setName("settings").setType(settingsType).build()); - - Expr settingsBuilderExpr = - MethodInvocationExpr.builder() - .setStaticReferenceType(settingsType) - .setMethodName("newBuilder") - .build(); - - Expr transportChannelProviderExpr = - MethodInvocationExpr.builder() - .setStaticReferenceType(settingsType) - .setMethodName("defaultHttpJsonTransportProviderBuilder") - .build(); - - transportChannelProviderExpr = - methodBuilderFn - .apply(transportChannelProviderExpr) - .apply("setHttpTransport", mockServiceVarExpr); - - transportChannelProviderExpr = - MethodInvocationExpr.builder() - .setExprReferenceExpr(transportChannelProviderExpr) - .setMethodName("build") - .setReturnType(localSettingsVarExpr.type()) - .build(); - - settingsBuilderExpr = - methodBuilderFn - .apply(settingsBuilderExpr) - .apply("setTransportChannelProvider", transportChannelProviderExpr); - - settingsBuilderExpr = - methodBuilderFn - .apply(settingsBuilderExpr) - .apply( - "setCredentialsProvider", - MethodInvocationExpr.builder() - .setStaticReferenceType(getFixedTypeStore().get("NoCredentialsProvider")) - .setMethodName("create") - .build()); - settingsBuilderExpr = - MethodInvocationExpr.builder() - .setExprReferenceExpr(settingsBuilderExpr) - .setMethodName("build") - .setReturnType(localSettingsVarExpr.type()) - .build(); - - Expr initLocalSettingsExpr = - AssignmentExpr.builder() - .setVariableExpr(localSettingsVarExpr.toBuilder().setIsDecl(true).build()) - .setValueExpr(settingsBuilderExpr) - .build(); - - Expr initClientExpr = - AssignmentExpr.builder() - .setVariableExpr(clientVarExpr) - .setValueExpr( - MethodInvocationExpr.builder() - .setStaticReferenceType( - typeStore.get(ClassNames.getServiceClientClassName(service))) - .setMethodName("create") - .setArguments(Arrays.asList(localSettingsVarExpr)) - .setReturnType(clientVarExpr.type()) - .build()) - .build(); - - return MethodDefinition.builder() - .setAnnotations( - Arrays.asList(AnnotationNode.withType(getFixedTypeStore().get("BeforeClass")))) - .setScope(ScopeNode.PUBLIC) - .setReturnType(TypeNode.VOID) - .setName("startStaticServer") - .setThrowsExceptions(Arrays.asList(getFixedTypeStore().get("IOException"))) - .setIsStatic(true) - .setBody( - Arrays.asList(initMockServiceExpr, initLocalSettingsExpr, initClientExpr).stream() - .map(e -> ExprStatement.withExpr(e)) - .collect(Collectors.toList())) - .build(); - } - - @Override - protected MethodDefinition createStopServerMethod( - Service service, Map classMemberVarExprs) { - return MethodDefinition.builder() - .setAnnotations( - Arrays.asList(AnnotationNode.withType(getFixedTypeStore().get("AfterClass")))) - .setScope(ScopeNode.PUBLIC) - .setIsStatic(true) - .setReturnType(TypeNode.VOID) - .setName("stopServer") - .setBody( - Arrays.asList( - ExprStatement.withExpr( - MethodInvocationExpr.builder() - .setExprReferenceExpr(classMemberVarExprs.get(CLIENT_VAR_NAME)) - .setMethodName("close") - .build()))) - .build(); - } - - @Override - protected MethodDefinition createSetUpMethod( - Service service, Map classMemberVarExprs, TypeStore typeStore) { - - return MethodDefinition.builder() - .setAnnotations(Arrays.asList(AnnotationNode.withType(getFixedTypeStore().get("Before")))) - .setScope(ScopeNode.PUBLIC) - .setReturnType(TypeNode.VOID) - .setName("setUp") - .setBody(Arrays.asList()) - .build(); - } - - @Override - protected MethodDefinition createTearDownMethod( - Service service, Map classMemberVarExprs) { - return MethodDefinition.builder() - .setAnnotations(Arrays.asList(AnnotationNode.withType(getFixedTypeStore().get("After")))) - .setScope(ScopeNode.PUBLIC) - .setReturnType(TypeNode.VOID) - .setName("tearDown") - .setThrowsExceptions( - Arrays.asList(TypeNode.withReference(ConcreteReference.withClazz(Exception.class)))) - .setBody( - Arrays.asList( - ExprStatement.withExpr( - MethodInvocationExpr.builder() - .setExprReferenceExpr(classMemberVarExprs.get(MOCK_SERVICE_VAR_NAME)) - .setMethodName("reset") - .build()))) - .build(); - } - - @Override - protected List constructRpcTestCheckerLogic( - Method method, - Service service, - boolean isRequestArg, - Map classMemberVarExprs, - VariableExpr requestVarExpr, - Message requestMessage, - List argExprs) { - - List methodExprs = new ArrayList<>(); - List methodStatements = new ArrayList<>(); - - VariableExpr actualRequestsVarExpr = - VariableExpr.withVariable( - Variable.builder() - .setType( - TypeNode.withReference( - ConcreteReference.builder() - .setClazz(List.class) - .setGenerics( - Arrays.asList(getFixedTypeStore().get("String").reference())) - .build())) - .setName("actualRequests") - .build()); - methodExprs.add( - AssignmentExpr.builder() - .setVariableExpr(actualRequestsVarExpr.toBuilder().setIsDecl(true).build()) - .setValueExpr( - MethodInvocationExpr.builder() - .setExprReferenceExpr(classMemberVarExprs.get(getMockServiceVarName(service))) - .setMethodName("getRequestPaths") - .setReturnType(actualRequestsVarExpr.type()) - .build()) - .build()); - - methodExprs.add( - MethodInvocationExpr.builder() - .setStaticReferenceType(getFixedTypeStore().get("Assert")) - .setMethodName("assertEquals") - .setArguments( - ValueExpr.withValue( - PrimitiveValue.builder().setType(TypeNode.INT).setValue("1").build()), - MethodInvocationExpr.builder() - .setExprReferenceExpr(actualRequestsVarExpr) - .setMethodName("size") - .build()) - .build()); - - methodStatements.addAll( - methodExprs.stream().map(ExprStatement::withExpr).collect(Collectors.toList())); - - methodExprs.clear(); - methodStatements.add(EMPTY_LINE_STATEMENT); - - VariableExpr apiClientHeaderKeyVarExpr = - VariableExpr.withVariable( - Variable.builder() - .setType(getFixedTypeStore().get("String")) - .setName("apiClientHeaderKey") - .build()); - - AssignmentExpr apiClientHeaderKeyAssignExpr = - AssignmentExpr.builder() - .setVariableExpr(apiClientHeaderKeyVarExpr.toBuilder().setIsDecl(true).build()) - .setValueExpr( - MethodInvocationExpr.builder() - .setMethodName("next") - .setReturnType(apiClientHeaderKeyVarExpr.type()) - .setExprReferenceExpr( - MethodInvocationExpr.builder() - .setMethodName("iterator") - .setExprReferenceExpr( - MethodInvocationExpr.builder() - .setMethodName("get") - .setArguments( - MethodInvocationExpr.builder() - .setMethodName("getDefaultApiClientHeaderKey") - .setStaticReferenceType( - getFixedTypeStore().get("ApiClientHeaderProvider")) - .build()) - .setExprReferenceExpr( - MethodInvocationExpr.builder() - .setMethodName("getRequestHeaders") - .setExprReferenceExpr( - classMemberVarExprs.get( - getMockServiceVarName(service))) - .build()) - .build()) - .build()) - .build()) - .build(); - - methodExprs.add(apiClientHeaderKeyAssignExpr); - - methodExprs.add( - MethodInvocationExpr.builder() - .setMethodName("assertTrue") - .setStaticReferenceType(getFixedTypeStore().get("Assert")) - .setArguments( - MethodInvocationExpr.builder() - .setMethodName("matches") - .setExprReferenceExpr( - MethodInvocationExpr.builder() - .setMethodName("matcher") - .setArguments(apiClientHeaderKeyVarExpr) - .setExprReferenceExpr( - MethodInvocationExpr.builder() - .setMethodName("getDefaultApiClientHeaderPattern") - .setStaticReferenceType( - getFixedTypeStore().get("GaxHttpJsonProperties")) - .build()) - .build()) - .build()) - .build()); - - methodStatements.addAll( - methodExprs.stream().map(ExprStatement::withExpr).collect(Collectors.toList())); - methodExprs.clear(); - - return methodStatements; - } - - @Override - protected MethodDefinition createRpcExceptionTestMethod( - Method method, - Service service, - List methodSignature, - int variantIndex, - Map classMemberVarExprs, - Map resourceNames, - Map messageTypes) { - VariableExpr exceptionVarExpr = - VariableExpr.withVariable( - Variable.builder() - .setType(getFixedTypeStore().get("ApiException")) - .setName("exception") - .build()); - - // First two assignment lines. - - Expr exceptionAssignExpr = - AssignmentExpr.builder() - .setVariableExpr(exceptionVarExpr.toBuilder().setIsDecl(true).build()) - .setValueExpr( - MethodInvocationExpr.builder() - .setMethodName("createException") - .setStaticReferenceType(getFixedTypeStore().get("ApiExceptionFactory")) - .setArguments( - NewObjectExpr.withType(getFixedTypeStore().get("Exception")), - MethodInvocationExpr.builder() - .setMethodName("of") - .setStaticReferenceType(getFixedTypeStore().get("FakeStatusCode")) - .setArguments( - EnumRefExpr.builder() - .setName("INVALID_ARGUMENT") - .setType(getFixedTypeStore().get("Code")) - .build()) - .build(), - ValueExpr.withValue( - PrimitiveValue.builder() - .setType(TypeNode.BOOLEAN) - .setValue("false") - .build())) - .setReturnType(exceptionVarExpr.type()) - .build()) - .build(); - - Expr addExceptionExpr = - MethodInvocationExpr.builder() - .setExprReferenceExpr(classMemberVarExprs.get(getMockServiceVarName(service))) - .setMethodName("addException") - .setArguments(exceptionVarExpr) - .build(); - - // Try-catch block. Build the method call. - String exceptionTestMethodName = - String.format( - "%sExceptionTest%s", - JavaStyle.toLowerCamelCase(method.name()), variantIndex > 0 ? variantIndex + 1 : ""); - - boolean isStreaming = !method.stream().equals(Method.Stream.NONE); - List methodBody = new ArrayList<>(); - methodBody.add(ExprStatement.withExpr(exceptionAssignExpr)); - methodBody.add(ExprStatement.withExpr(addExceptionExpr)); - if (isStreaming) { - methodBody.addAll( - createStreamingRpcExceptionTestStatements( - method, classMemberVarExprs, resourceNames, messageTypes)); - } else { - methodBody.addAll( - createRpcExceptionTestStatements( - method, methodSignature, classMemberVarExprs, resourceNames, messageTypes)); - } - - return MethodDefinition.builder() - .setAnnotations(Arrays.asList(getTestAnnotation())) - .setScope(ScopeNode.PUBLIC) - .setReturnType(TypeNode.VOID) - .setName(exceptionTestMethodName) - .setThrowsExceptions(Arrays.asList(TypeNode.withExceptionClazz(Exception.class))) - .setBody(methodBody) - .build(); - } - - @Override - protected String getMockServiceVarName(Service service) { - return String.format(MOCK_SERVICE_VAR_NAME); - } -} diff --git a/src/main/java/com/google/api/generator/gapic/composer/httpjson/ServiceSettingsClassComposer.java b/src/main/java/com/google/api/generator/gapic/composer/httpjson/ServiceSettingsClassComposer.java deleted file mode 100644 index bd9d0d97bb..0000000000 --- a/src/main/java/com/google/api/generator/gapic/composer/httpjson/ServiceSettingsClassComposer.java +++ /dev/null @@ -1,42 +0,0 @@ -// Copyright 2021 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 -// -// http://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. - -package com.google.api.generator.gapic.composer.httpjson; - -import com.google.api.gax.httpjson.InstantiatingHttpJsonChannelProvider; -import com.google.api.generator.gapic.composer.common.AbstractServiceSettingsClassComposer; -import com.google.api.generator.gapic.composer.store.TypeStore; -import java.util.Arrays; - -public class ServiceSettingsClassComposer extends AbstractServiceSettingsClassComposer { - private static final ServiceSettingsClassComposer INSTANCE = - new ServiceSettingsClassComposer(); - - protected ServiceSettingsClassComposer() { - super( - createTypes(), - InstantiatingHttpJsonChannelProvider.Builder.class, - "defaultHttpJsonTransportProviderBuilder"); - } - - public static ServiceSettingsClassComposer instance() { - return INSTANCE; - } - - private static TypeStore createTypes() { - TypeStore typeStore = createCommonTypes(); - typeStore.putAll(Arrays.asList(InstantiatingHttpJsonChannelProvider.class)); - return typeStore; - } -} diff --git a/src/main/java/com/google/api/generator/gapic/composer/httpjson/ServiceStubSettingsClassComposer.java b/src/main/java/com/google/api/generator/gapic/composer/httpjson/ServiceStubSettingsClassComposer.java deleted file mode 100644 index 9a2f14c8fb..0000000000 --- a/src/main/java/com/google/api/generator/gapic/composer/httpjson/ServiceStubSettingsClassComposer.java +++ /dev/null @@ -1,176 +0,0 @@ -// Copyright 2021 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 -// -// http://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. - -package com.google.api.generator.gapic.composer.httpjson; - -import com.google.api.gax.httpjson.GaxHttpJsonProperties; -import com.google.api.gax.httpjson.HttpJsonTransportChannel; -import com.google.api.gax.httpjson.InstantiatingHttpJsonChannelProvider; -import com.google.api.gax.rpc.ApiClientHeaderProvider; -import com.google.api.generator.engine.ast.AnnotationNode; -import com.google.api.generator.engine.ast.ConcreteReference; -import com.google.api.generator.engine.ast.MethodDefinition; -import com.google.api.generator.engine.ast.MethodInvocationExpr; -import com.google.api.generator.engine.ast.ScopeNode; -import com.google.api.generator.engine.ast.StringObjectValue; -import com.google.api.generator.engine.ast.TypeNode; -import com.google.api.generator.engine.ast.ValueExpr; -import com.google.api.generator.engine.ast.Variable; -import com.google.api.generator.engine.ast.VariableExpr; -import com.google.api.generator.gapic.composer.common.AbstractServiceStubSettingsClassComposer; -import com.google.api.generator.gapic.composer.comment.SettingsCommentComposer; -import com.google.api.generator.gapic.composer.store.TypeStore; -import com.google.api.generator.gapic.composer.utils.ClassNames; -import com.google.api.generator.gapic.model.Service; -import java.util.Arrays; - -public class ServiceStubSettingsClassComposer extends - AbstractServiceStubSettingsClassComposer { - private static final ServiceStubSettingsClassComposer INSTANCE = - new ServiceStubSettingsClassComposer(); - - public static ServiceStubSettingsClassComposer instance() { - return INSTANCE; - } - - protected ServiceStubSettingsClassComposer() { - super( - createStaticTypes(), - new ClassNames("HttpJson"), - HttpJsonTransportChannel.class, - "getHttpJsonTransportName"); - } - - private static TypeStore createStaticTypes() { - TypeStore typeStore = createCommonStaticTypes(); - typeStore.putAll( - Arrays.asList( - GaxHttpJsonProperties.class, - HttpJsonTransportChannel.class, - InstantiatingHttpJsonChannelProvider.class)); - return typeStore; - } - - @Override - protected MethodDefinition createDefaultTransportTransportProviderBuilderMethod() { - // Create the defaultHttpJsonTransportProviderBuilder method. - TypeNode returnType = - TypeNode.withReference( - ConcreteReference.withClazz(InstantiatingHttpJsonChannelProvider.Builder.class)); - MethodInvocationExpr transportChannelProviderBuilderExpr = - MethodInvocationExpr.builder() - .setStaticReferenceType( - getFixedTypeStore().get(InstantiatingHttpJsonChannelProvider.class.getSimpleName())) - .setMethodName("newBuilder") - .setReturnType(returnType) - .build(); - return MethodDefinition.builder() - .setHeaderCommentStatements( - SettingsCommentComposer.DEFAULT_TRANSPORT_PROVIDER_BUILDER_METHOD_COMMENT) - .setScope(ScopeNode.PUBLIC) - .setIsStatic(true) - .setReturnType(returnType) - .setName("defaultHttpJsonTransportProviderBuilder") - .setReturnExpr(transportChannelProviderBuilderExpr) - .build(); - } - - @Override - protected MethodDefinition createDefaultApiClientHeaderProviderBuilderMethod( - Service service, TypeStore typeStore) { - // Create the defaultApiClientHeaderProviderBuilder method. - TypeNode returnType = - TypeNode.withReference(ConcreteReference.withClazz(ApiClientHeaderProvider.Builder.class)); - MethodInvocationExpr returnExpr = - MethodInvocationExpr.builder() - .setStaticReferenceType(getFixedTypeStore().get("ApiClientHeaderProvider")) - .setMethodName("newBuilder") - .build(); - - MethodInvocationExpr versionArgExpr = - MethodInvocationExpr.builder() - .setStaticReferenceType(getFixedTypeStore().get("GaxProperties")) - .setMethodName("getLibraryVersion") - .setArguments( - VariableExpr.builder() - .setVariable( - Variable.builder().setType(TypeNode.CLASS_OBJECT).setName("class").build()) - .setStaticReferenceType( - typeStore.get(ClassNames.getServiceStubSettingsClassName(service))) - .build()) - .build(); - - returnExpr = - MethodInvocationExpr.builder() - .setExprReferenceExpr(returnExpr) - .setMethodName("setGeneratedLibToken") - .setArguments(ValueExpr.withValue(StringObjectValue.withValue("gapic")), versionArgExpr) - .build(); - returnExpr = - MethodInvocationExpr.builder() - .setExprReferenceExpr(returnExpr) - .setMethodName("setTransportToken") - .setArguments( - MethodInvocationExpr.builder() - .setStaticReferenceType( - getFixedTypeStore().get(GaxHttpJsonProperties.class.getSimpleName())) - .setMethodName("getHttpJsonTokenName") - .build(), - MethodInvocationExpr.builder() - .setStaticReferenceType( - getFixedTypeStore().get(GaxHttpJsonProperties.class.getSimpleName())) - .setMethodName("getHttpJsonVersion") - .build()) - .setReturnType(returnType) - .build(); - - AnnotationNode annotation = - AnnotationNode.builder() - .setType(getFixedTypeStore().get("BetaApi")) - .setDescription( - "The surface for customizing headers is not stable yet and may change in the" - + " future.") - .build(); - return MethodDefinition.builder() - .setAnnotations(Arrays.asList(annotation)) - .setScope(ScopeNode.PUBLIC) - .setIsStatic(true) - .setReturnType(returnType) - .setName("defaultApiClientHeaderProviderBuilder") - .setReturnExpr(returnExpr) - .build(); - } - - @Override - public MethodDefinition createDefaultTransportChannelProviderMethod() { - TypeNode returnType = getFixedTypeStore().get("TransportChannelProvider"); - MethodInvocationExpr transportProviderBuilderExpr = - MethodInvocationExpr.builder() - .setMethodName("defaultHttpJsonTransportProviderBuilder") - .build(); - transportProviderBuilderExpr = - MethodInvocationExpr.builder() - .setExprReferenceExpr(transportProviderBuilderExpr) - .setMethodName("build") - .setReturnType(returnType) - .build(); - return MethodDefinition.builder() - .setScope(ScopeNode.PUBLIC) - .setIsStatic(true) - .setReturnType(returnType) - .setName("defaultTransportChannelProvider") - .setReturnExpr(transportProviderBuilderExpr) - .build(); - } -} diff --git a/src/main/java/com/google/api/generator/gapic/model/GapicContext.java b/src/main/java/com/google/api/generator/gapic/model/GapicContext.java index f209f55aa3..bc4561a0ad 100644 --- a/src/main/java/com/google/api/generator/gapic/model/GapicContext.java +++ b/src/main/java/com/google/api/generator/gapic/model/GapicContext.java @@ -56,9 +56,6 @@ public GapicMetadata gapicMetadata() { @Nullable public abstract com.google.api.Service serviceYamlProto(); - @Nullable - public abstract Transport transport(); - public boolean hasServiceYamlProto() { return serviceYamlProto() != null; } @@ -107,8 +104,6 @@ public Builder setHelperResourceNames(Set helperResourceNames) { public abstract Builder setServiceYamlProto(com.google.api.Service serviceYamlProto); - public abstract Builder setTransport(Transport transport); - public abstract Builder setGapicMetadataEnabled(boolean gapicMetadataEnabled); public abstract GapicContext build(); diff --git a/src/main/java/com/google/api/generator/gapic/model/HttpRuleBindings.java b/src/main/java/com/google/api/generator/gapic/model/HttpRuleBindings.java deleted file mode 100644 index 073069be06..0000000000 --- a/src/main/java/com/google/api/generator/gapic/model/HttpRuleBindings.java +++ /dev/null @@ -1,58 +0,0 @@ -// Copyright 2021 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 -// -// http://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. - -package com.google.api.generator.gapic.model; - -import com.google.auto.value.AutoValue; -import com.google.common.collect.ImmutableSet; -import java.util.Set; - -@AutoValue -public abstract class HttpRuleBindings { - public abstract String httpVerb(); - - public abstract String pattern(); - - public abstract Set pathParameters(); - - public abstract Set queryParameters(); - - public abstract Set bodyParameters(); - - // Private. - public static HttpRuleBindings.Builder builder() { - return new AutoValue_HttpRuleBindings.Builder() - .setHttpVerb("") - .setPattern("") - .setPathParameters(ImmutableSet.of()) - .setQueryParameters(ImmutableSet.of()) - .setBodyParameters(ImmutableSet.of()); - } - - // Private. - @AutoValue.Builder - public abstract static class Builder { - public abstract HttpRuleBindings.Builder setHttpVerb(String httpVerb); - - public abstract HttpRuleBindings.Builder setPattern(String pattern); - - public abstract HttpRuleBindings.Builder setPathParameters(Set pathParameters); - - public abstract HttpRuleBindings.Builder setQueryParameters(Set queryParameters); - - public abstract HttpRuleBindings.Builder setBodyParameters(Set bodyParameters); - - public abstract HttpRuleBindings build(); - } -} diff --git a/src/main/java/com/google/api/generator/gapic/model/Method.java b/src/main/java/com/google/api/generator/gapic/model/Method.java index 82d5e46760..df5a9aa668 100644 --- a/src/main/java/com/google/api/generator/gapic/model/Method.java +++ b/src/main/java/com/google/api/generator/gapic/model/Method.java @@ -53,8 +53,9 @@ public enum Stream { @Nullable public abstract String mixedInApiName(); + // TODO(miraleung): May need to change this to MethodArgument, Field, or some new struct // HttpBinding pending dotted reference support. - public abstract HttpRuleBindings httpBindings(); + public abstract List httpBindings(); // Example from Expand in echo.proto: Thet TypeNodes that map to // [["content", "error"], ["content", "error", "info"]]. @@ -69,7 +70,7 @@ public boolean hasDescription() { } public boolean hasHttpBindings() { - return !httpBindings().pathParameters().isEmpty(); + return !httpBindings().isEmpty(); } public boolean isMixin() { @@ -82,7 +83,7 @@ public static Builder builder() { return new AutoValue_Method.Builder() .setStream(Stream.NONE) .setMethodSignatures(ImmutableList.of()) - .setHttpBindings(HttpRuleBindings.builder().build()) + .setHttpBindings(ImmutableList.of()) .setIsBatching(false) .setIsPaged(false) .setIsDeprecated(false); @@ -117,7 +118,7 @@ public abstract static class Builder { public abstract Builder setMixedInApiName(String mixedInApiName); - public abstract Builder setHttpBindings(HttpRuleBindings httpBindings); + public abstract Builder setHttpBindings(List httpBindings); public abstract Builder setMethodSignatures(List> methodSignature); diff --git a/src/main/java/com/google/api/generator/gapic/model/Transport.java b/src/main/java/com/google/api/generator/gapic/model/Transport.java deleted file mode 100644 index f07efc4dac..0000000000 --- a/src/main/java/com/google/api/generator/gapic/model/Transport.java +++ /dev/null @@ -1,25 +0,0 @@ -// Copyright 2021 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 -// -// http://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. - -package com.google.api.generator.gapic.model; - -public enum Transport { - REST, - GRPC, - GRPC_REST; - - public static Transport parse(String name) { - return valueOf(name.replace('+', '_').toUpperCase()); - } -} diff --git a/src/main/java/com/google/api/generator/gapic/protoparser/HttpRuleParser.java b/src/main/java/com/google/api/generator/gapic/protoparser/HttpRuleParser.java index e2d5b6896e..488bc52cea 100644 --- a/src/main/java/com/google/api/generator/gapic/protoparser/HttpRuleParser.java +++ b/src/main/java/com/google/api/generator/gapic/protoparser/HttpRuleParser.java @@ -18,29 +18,29 @@ import com.google.api.HttpRule; import com.google.api.HttpRule.PatternCase; import com.google.api.generator.gapic.model.Field; -import com.google.api.generator.gapic.model.HttpRuleBindings; import com.google.api.generator.gapic.model.Message; import com.google.api.pathtemplate.PathTemplate; import com.google.common.base.Preconditions; import com.google.common.base.Strings; -import com.google.common.collect.ImmutableSet; -import com.google.common.collect.ImmutableSortedSet; -import com.google.common.collect.Sets; import com.google.protobuf.DescriptorProtos.MethodOptions; import com.google.protobuf.Descriptors.MethodDescriptor; +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashSet; +import java.util.List; import java.util.Map; +import java.util.Optional; import java.util.Set; import java.util.stream.Collectors; public class HttpRuleParser { private static final String ASTERISK = "*"; - public static HttpRuleBindings parse( + public static Optional> parseHttpBindings( MethodDescriptor protoMethod, Message inputMessage, Map messageTypes) { MethodOptions methodOptions = protoMethod.getOptions(); - HttpRuleBindings.Builder httpBindings = HttpRuleBindings.builder(); if (!methodOptions.hasExtension(AnnotationsProto.http)) { - return httpBindings.build(); + return Optional.empty(); } HttpRule httpRule = methodOptions.getExtension(AnnotationsProto.http); @@ -51,16 +51,19 @@ public static HttpRuleBindings parse( } // Get pattern. - String pattern = getPattern(httpRule); - ImmutableSet.Builder bindingsBuilder = getPatternBindings(pattern); + Set uniqueBindings = getPatternBindings(httpRule); + if (uniqueBindings.isEmpty()) { + return Optional.empty(); + } + if (httpRule.getAdditionalBindingsCount() > 0) { for (HttpRule additionalRule : httpRule.getAdditionalBindingsList()) { - // TODO: save additional bindings path in HttpRuleBindings - bindingsBuilder.addAll(getPatternBindings(getPattern(additionalRule)).build()); + uniqueBindings.addAll(getPatternBindings(additionalRule)); } } - Set bindings = bindingsBuilder.build(); + List bindings = new ArrayList<>(uniqueBindings); + Collections.sort(bindings); // Binding validation. for (String binding : bindings) { @@ -83,60 +86,40 @@ public static HttpRuleBindings parse( } } - String body = httpRule.getBody(); - Set bodyParameters; - Set queryParameters; - if (Strings.isNullOrEmpty(body)) { - bodyParameters = ImmutableSet.of(); - queryParameters = Sets.difference(inputMessage.fieldMap().keySet(), bindings); - } else if (body.equals(ASTERISK)) { - bodyParameters = Sets.difference(inputMessage.fieldMap().keySet(), bindings); - queryParameters = ImmutableSet.of(); - } else { - bodyParameters = ImmutableSet.of(body); - Set bodyBinidngsUnion = Sets.union(bodyParameters, bindings); - queryParameters = Sets.difference(inputMessage.fieldMap().keySet(), bodyBinidngsUnion); - } - - httpBindings.setHttpVerb(httpRule.getPatternCase().toString()); - httpBindings.setPattern(pattern); - httpBindings.setPathParameters(ImmutableSortedSet.copyOf(bindings)); - httpBindings.setQueryParameters(ImmutableSortedSet.copyOf(queryParameters)); - httpBindings.setBodyParameters(ImmutableSortedSet.copyOf(bodyParameters)); - - return httpBindings.build(); + return Optional.of(bindings); } - private static String getPattern(HttpRule httpRule) { + private static Set getPatternBindings(HttpRule httpRule) { + String pattern = null; + // Assign a temp variable to prevent the formatter from removing the import. PatternCase patternCase = httpRule.getPatternCase(); switch (patternCase) { case GET: - return httpRule.getGet(); + pattern = httpRule.getGet(); + break; case PUT: - return httpRule.getPut(); + pattern = httpRule.getPut(); + break; case POST: - return httpRule.getPost(); + pattern = httpRule.getPost(); + break; case DELETE: - return httpRule.getDelete(); + pattern = httpRule.getDelete(); + break; case PATCH: - return httpRule.getPatch(); + pattern = httpRule.getPatch(); + break; case CUSTOM: // Invalid pattern. // Fall through. default: - return ""; - } - } - - private static ImmutableSortedSet.Builder getPatternBindings(String pattern) { - ImmutableSortedSet.Builder bindings = ImmutableSortedSet.naturalOrder(); - if (pattern.isEmpty()) { - return bindings; + return Collections.emptySet(); } PathTemplate template = PathTemplate.create(pattern); - // Filter out any unbound variable like "$0, $1, etc. - bindings.addAll( - template.vars().stream().filter(s -> !s.contains("$")).collect(Collectors.toSet())); + Set bindings = + new HashSet( + // Filter out any unbound variable like "$0, $1, etc. + template.vars().stream().filter(s -> !s.contains("$")).collect(Collectors.toList())); return bindings; } diff --git a/src/main/java/com/google/api/generator/gapic/protoparser/Parser.java b/src/main/java/com/google/api/generator/gapic/protoparser/Parser.java index 19a92ef6d9..fee1587c49 100644 --- a/src/main/java/com/google/api/generator/gapic/protoparser/Parser.java +++ b/src/main/java/com/google/api/generator/gapic/protoparser/Parser.java @@ -24,7 +24,6 @@ import com.google.api.generator.gapic.model.GapicLanguageSettings; import com.google.api.generator.gapic.model.GapicLroRetrySettings; import com.google.api.generator.gapic.model.GapicServiceConfig; -import com.google.api.generator.gapic.model.HttpRuleBindings; import com.google.api.generator.gapic.model.LongrunningOperation; import com.google.api.generator.gapic.model.Message; import com.google.api.generator.gapic.model.Method; @@ -32,7 +31,6 @@ import com.google.api.generator.gapic.model.ResourceReference; import com.google.api.generator.gapic.model.Service; import com.google.api.generator.gapic.model.SourceCodeInfoLocation; -import com.google.api.generator.gapic.model.Transport; import com.google.api.generator.gapic.utils.ResourceNameConstants; import com.google.common.annotations.VisibleForTesting; import com.google.common.base.Preconditions; @@ -105,7 +103,6 @@ public static GapicContext parse(CodeGeneratorRequest request) { GapicLroRetrySettingsParser.parse(gapicYamlConfigPathOpt); Optional languageSettingsOpt = GapicLanguageSettingsParser.parse(gapicYamlConfigPathOpt); - Optional transportOpt = PluginArgumentParser.parseTransport(request); boolean willGenerateMetadata = PluginArgumentParser.hasMetadataFlag(request); @@ -186,7 +183,6 @@ public static GapicContext parse(CodeGeneratorRequest request) { .setServiceConfig(serviceConfigOpt.isPresent() ? serviceConfigOpt.get() : null) .setGapicMetadataEnabled(willGenerateMetadata) .setServiceYamlProto(serviceYamlProtoOpt.isPresent() ? serviceYamlProtoOpt.get() : null) - .setTransport(Transport.parse(transportOpt.orElse(Transport.GRPC.toString()))) .build(); } @@ -488,7 +484,7 @@ private static boolean isMapType(Descriptor messageDescriptor) { * Populates ResourceName objects in Message POJOs. * * @param messageTypes A map of the message type name (as in the protobuf) to Message POJOs. - * @param resources A list of ResourceName POJOs. + * @param resourceNames A list of ResourceName POJOs. * @return The updated messageTypes map. */ public static Map updateResourceNamesInMessages( @@ -561,7 +557,10 @@ static List parseMethods( Preconditions.checkNotNull( inputMessage, String.format("No message found for %s", inputType.reference().simpleName())); - HttpRuleBindings httpBindings = HttpRuleParser.parse(protoMethod, inputMessage, messageTypes); + Optional> httpBindingsOpt = + HttpRuleParser.parseHttpBindings(protoMethod, inputMessage, messageTypes); + List httpBindings = + httpBindingsOpt.isPresent() ? httpBindingsOpt.get() : Collections.emptyList(); boolean isBatching = !serviceConfigOpt.isPresent() ? false diff --git a/src/main/java/com/google/api/generator/gapic/protoparser/PluginArgumentParser.java b/src/main/java/com/google/api/generator/gapic/protoparser/PluginArgumentParser.java index d5a7de1f79..53cd0f32f3 100644 --- a/src/main/java/com/google/api/generator/gapic/protoparser/PluginArgumentParser.java +++ b/src/main/java/com/google/api/generator/gapic/protoparser/PluginArgumentParser.java @@ -30,7 +30,6 @@ public class PluginArgumentParser { @VisibleForTesting static final String KEY_GAPIC_CONFIG = "gapic-config"; @VisibleForTesting static final String KEY_METADATA = "metadata"; @VisibleForTesting static final String KEY_SERVICE_YAML_CONFIG = "api-service-config"; - @VisibleForTesting static final String KEY_TRANSPORT = "transport"; private static final String JSON_FILE_ENDING = "grpc_service_config.json"; private static final String GAPIC_YAML_FILE_ENDING = "gapic.yaml"; @@ -48,10 +47,6 @@ static Optional parseServiceYamlConfigPath(CodeGeneratorRequest request) return parseServiceYamlConfigPath(request.getParameter()); } - static Optional parseTransport(CodeGeneratorRequest request) { - return parseConfigArgument(request.getParameter(), KEY_TRANSPORT); - } - static boolean hasMetadataFlag(CodeGeneratorRequest request) { return hasMetadataFlag(request.getParameter()); } @@ -59,33 +54,17 @@ static boolean hasMetadataFlag(CodeGeneratorRequest request) { /** Expects a comma-separated list of file paths. */ @VisibleForTesting static Optional parseJsonConfigPath(String pluginProtocArgument) { - return parseFileArgument(pluginProtocArgument, KEY_GRPC_SERVICE_CONFIG, JSON_FILE_ENDING); + return parseArgument(pluginProtocArgument, KEY_GRPC_SERVICE_CONFIG, JSON_FILE_ENDING); } @VisibleForTesting static Optional parseGapicYamlConfigPath(String pluginProtocArgument) { - return parseFileArgument(pluginProtocArgument, KEY_GAPIC_CONFIG, GAPIC_YAML_FILE_ENDING); + return parseArgument(pluginProtocArgument, KEY_GAPIC_CONFIG, GAPIC_YAML_FILE_ENDING); } @VisibleForTesting static Optional parseServiceYamlConfigPath(String pluginProtocArgument) { - return parseFileArgument( - pluginProtocArgument, KEY_SERVICE_YAML_CONFIG, SERVICE_YAML_FILE_ENDING); - } - - @VisibleForTesting - private static Optional parseConfigArgument(String pluginProtocArgument, String key) { - if (Strings.isNullOrEmpty(pluginProtocArgument)) { - return Optional.empty(); - } - - for (String argComponent : pluginProtocArgument.split(COMMA)) { - String[] args = argComponent.trim().split(EQUALS); - if (args.length == 2 && key.equals(args[0])) { - return Optional.of(args[1]); - } - } - return Optional.empty(); + return parseArgument(pluginProtocArgument, KEY_SERVICE_YAML_CONFIG, SERVICE_YAML_FILE_ENDING); } @VisibleForTesting @@ -93,10 +72,10 @@ static boolean hasMetadataFlag(String pluginProtocArgument) { return Arrays.stream(pluginProtocArgument.split(COMMA)).anyMatch(s -> s.equals(KEY_METADATA)); } - private static Optional parseFileArgument( + private static Optional parseArgument( String pluginProtocArgument, String key, String fileEnding) { if (Strings.isNullOrEmpty(pluginProtocArgument)) { - return Optional.empty(); + return Optional.empty(); } for (String argComponent : pluginProtocArgument.split(COMMA)) { String[] args = argComponent.trim().split(EQUALS); @@ -114,6 +93,6 @@ private static Optional parseFileArgument( return Optional.of(valueVal); } } - return Optional.empty(); + return Optional.empty(); } } diff --git a/src/test/java/com/google/api/generator/gapic/composer/common/TestProtoLoader.java b/src/test/java/com/google/api/generator/gapic/composer/common/TestProtoLoader.java index cd7cb34911..5762af6374 100644 --- a/src/test/java/com/google/api/generator/gapic/composer/common/TestProtoLoader.java +++ b/src/test/java/com/google/api/generator/gapic/composer/common/TestProtoLoader.java @@ -23,7 +23,6 @@ import com.google.api.generator.gapic.model.Message; import com.google.api.generator.gapic.model.ResourceName; import com.google.api.generator.gapic.model.Service; -import com.google.api.generator.gapic.model.Transport; import com.google.api.generator.gapic.protoparser.BatchingSettingsConfigParser; import com.google.api.generator.gapic.protoparser.Parser; import com.google.api.generator.gapic.protoparser.ServiceConfigParser; @@ -51,12 +50,10 @@ public class TestProtoLoader { private static final TestProtoLoader INSTANCE = - new TestProtoLoader(null, "src/test/java/com/google/api/generator/gapic/testdata/"); - private final Transport transport; + new TestProtoLoader("src/test/java/com/google/api/generator/gapic/testdata/"); private final String testFilesDirectory; - protected TestProtoLoader(Transport transport, String testFilesDirectory) { - this.transport = transport; + protected TestProtoLoader(String testFilesDirectory) { this.testFilesDirectory = testFilesDirectory; } @@ -115,7 +112,6 @@ public GapicContext parseShowcaseEcho() { .setServices(services) .setServiceConfig(config) .setHelperResourceNames(outputResourceNames) - .setTransport(transport) .build(); } @@ -136,7 +132,6 @@ public GapicContext parseShowcaseIdentity() { .setResourceNames(resourceNames) .setServices(services) .setHelperResourceNames(outputResourceNames) - .setTransport(transport) .build(); } @@ -161,7 +156,6 @@ public GapicContext parseShowcaseTesting() { .setResourceNames(resourceNames) .setServices(services) .setHelperResourceNames(outputResourceNames) - .setTransport(transport) .build(); } @@ -204,7 +198,6 @@ public GapicContext parsePubSubPublisher() { .setServices(services) .setServiceConfig(config) .setHelperResourceNames(outputResourceNames) - .setTransport(transport) .build(); } @@ -259,7 +252,6 @@ public GapicContext parseLogging() { .setServices(services) .setServiceConfig(config) .setHelperResourceNames(outputResourceNames) - .setTransport(transport) .build(); } diff --git a/src/test/java/com/google/api/generator/gapic/composer/grpc/GrpcTestProtoLoader.java b/src/test/java/com/google/api/generator/gapic/composer/grpc/GrpcTestProtoLoader.java index 5f6197ed8a..4405f8b7e8 100644 --- a/src/test/java/com/google/api/generator/gapic/composer/grpc/GrpcTestProtoLoader.java +++ b/src/test/java/com/google/api/generator/gapic/composer/grpc/GrpcTestProtoLoader.java @@ -15,13 +15,12 @@ package com.google.api.generator.gapic.composer.grpc; import com.google.api.generator.gapic.composer.common.TestProtoLoader; -import com.google.api.generator.gapic.model.Transport; public class GrpcTestProtoLoader extends TestProtoLoader { private static GrpcTestProtoLoader INSTANCE = new GrpcTestProtoLoader(); protected GrpcTestProtoLoader() { - super(Transport.GRPC, "src/test/java/com/google/api/generator/gapic/testdata/"); + super("src/test/java/com/google/api/generator/gapic/testdata/"); } public static GrpcTestProtoLoader instance() { diff --git a/src/test/java/com/google/api/generator/gapic/protoparser/HttpRuleParserTest.java b/src/test/java/com/google/api/generator/gapic/protoparser/HttpRuleParserTest.java index c2383142bb..1aed7b9f92 100644 --- a/src/test/java/com/google/api/generator/gapic/protoparser/HttpRuleParserTest.java +++ b/src/test/java/com/google/api/generator/gapic/protoparser/HttpRuleParserTest.java @@ -16,16 +16,18 @@ import static com.google.common.truth.Truth.assertThat; import static junit.framework.Assert.assertEquals; +import static junit.framework.Assert.assertFalse; import static junit.framework.Assert.assertTrue; import static org.junit.Assert.assertThrows; -import com.google.api.generator.gapic.model.HttpRuleBindings; import com.google.api.generator.gapic.model.Message; import com.google.protobuf.Descriptors.FileDescriptor; import com.google.protobuf.Descriptors.MethodDescriptor; import com.google.protobuf.Descriptors.ServiceDescriptor; import com.google.showcase.v1beta1.TestingOuterClass; +import java.util.List; import java.util.Map; +import java.util.Optional; import org.junit.Test; public class HttpRuleParserTest { @@ -40,14 +42,16 @@ public void parseHttpAnnotation_basic() { // CreateSession method. MethodDescriptor rpcMethod = testingService.getMethods().get(0); Message inputMessage = messages.get("CreateSessionRequest"); - HttpRuleBindings httpBindings = HttpRuleParser.parse(rpcMethod, inputMessage, messages); - assertTrue(httpBindings.pathParameters().isEmpty()); + Optional> httpBindingsOpt = + HttpRuleParser.parseHttpBindings(rpcMethod, inputMessage, messages); + assertFalse(httpBindingsOpt.isPresent()); // GetSession method. rpcMethod = testingService.getMethods().get(1); inputMessage = messages.get("GetSessionRequest"); - httpBindings = HttpRuleParser.parse(rpcMethod, inputMessage, messages); - assertThat(httpBindings.pathParameters()).containsExactly("name"); + httpBindingsOpt = HttpRuleParser.parseHttpBindings(rpcMethod, inputMessage, messages); + assertTrue(httpBindingsOpt.isPresent()); + assertThat(httpBindingsOpt.get()).containsExactly("name"); } @Test @@ -62,8 +66,10 @@ public void parseHttpAnnotation_multipleBindings() { MethodDescriptor rpcMethod = testingService.getMethods().get(testingService.getMethods().size() - 1); Message inputMessage = messages.get("VerifyTestRequest"); - HttpRuleBindings httpBindings = HttpRuleParser.parse(rpcMethod, inputMessage, messages); - assertThat(httpBindings.pathParameters()) + Optional> httpBindingsOpt = + HttpRuleParser.parseHttpBindings(rpcMethod, inputMessage, messages); + assertTrue(httpBindingsOpt.isPresent()); + assertThat(httpBindingsOpt.get()) .containsExactly("answer", "foo", "name", "test_to_verify.name"); } @@ -80,6 +86,7 @@ public void parseHttpAnnotation_missingFieldFromMessage() { testingService.getMethods().get(testingService.getMethods().size() - 1); Message inputMessage = messages.get("CreateSessionRequest"); assertThrows( - IllegalStateException.class, () -> HttpRuleParser.parse(rpcMethod, inputMessage, messages)); + IllegalStateException.class, + () -> HttpRuleParser.parseHttpBindings(rpcMethod, inputMessage, messages)); } } From fb74362742e067e9251a5fcd395422aa01ade625 Mon Sep 17 00:00:00 2001 From: vam-google Date: Wed, 19 May 2021 01:50:26 -0700 Subject: [PATCH 04/16] fix: fix merge --- .../common/AbstractServiceSettingsClassComposer.java | 1 - .../generator/gapic/composer/common/ClassComposer.java | 9 +++++++-- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/src/main/java/com/google/api/generator/gapic/composer/common/AbstractServiceSettingsClassComposer.java b/src/main/java/com/google/api/generator/gapic/composer/common/AbstractServiceSettingsClassComposer.java index 3484a7a9e5..fdfa9c7177 100644 --- a/src/main/java/com/google/api/generator/gapic/composer/common/AbstractServiceSettingsClassComposer.java +++ b/src/main/java/com/google/api/generator/gapic/composer/common/AbstractServiceSettingsClassComposer.java @@ -729,7 +729,6 @@ private static TypeStore createStaticTypes() { Generated.class, GoogleCredentialsProvider.class, InstantiatingExecutorProvider.class, - InstantiatingGrpcChannelProvider.class, IOException.class, Operation.class, OperationCallSettings.class, diff --git a/src/main/java/com/google/api/generator/gapic/composer/common/ClassComposer.java b/src/main/java/com/google/api/generator/gapic/composer/common/ClassComposer.java index 5d863ebf5c..d8d87eadc1 100644 --- a/src/main/java/com/google/api/generator/gapic/composer/common/ClassComposer.java +++ b/src/main/java/com/google/api/generator/gapic/composer/common/ClassComposer.java @@ -14,5 +14,10 @@ package com.google.api.generator.gapic.composer.common; -public interface ClassComposer - extends com.google.api.generator.gapic.composer.common.ClassComposer {} +import com.google.api.generator.gapic.model.GapicClass; +import com.google.api.generator.gapic.model.GapicContext; +import com.google.api.generator.gapic.model.Service; + +public interface ClassComposer { + GapicClass generate(GapicContext context, Service serivce); +} From 229da5d94cf7db060abf3ea006a20d1ade804597 Mon Sep 17 00:00:00 2001 From: Mira Leung Date: Wed, 19 May 2021 15:05:35 -0700 Subject: [PATCH 05/16] fix(mixins): Gate mixin RPC on HTTP rules, add yaml doc/http overrides [ggj] (#727) * fix(mixins): Gate mixin RPC on HTTP rules, override with doc/http in yaml * fix: comment, request params --- .../gapic/protoparser/HttpRuleParser.java | 29 +++++-- .../generator/gapic/protoparser/Parser.java | 84 +++++++++++++++---- .../apis/kms/v1/cloudkms_test_mixins_v1.yaml | 37 ++++---- .../kms/v1/KeyManagementServiceClient.java | 67 +-------------- .../v1/KeyManagementServiceClientTest.java | 54 +----------- .../kms/v1/KeyManagementServiceSettings.java | 11 --- .../google/cloud/kms/v1/gapic_metadata.json | 3 - .../v1/stub/GrpcKeyManagementServiceStub.java | 34 +------- .../kms/v1/stub/KeyManagementServiceStub.java | 5 -- .../KeyManagementServiceStubSettings.java | 23 ----- .../com/google/iam/v1/MockIAMPolicyImpl.java | 20 ----- 11 files changed, 121 insertions(+), 246 deletions(-) diff --git a/src/main/java/com/google/api/generator/gapic/protoparser/HttpRuleParser.java b/src/main/java/com/google/api/generator/gapic/protoparser/HttpRuleParser.java index 51e84cb57b..cd2ae640c9 100644 --- a/src/main/java/com/google/api/generator/gapic/protoparser/HttpRuleParser.java +++ b/src/main/java/com/google/api/generator/gapic/protoparser/HttpRuleParser.java @@ -50,15 +50,24 @@ public static Optional> parseHttpBindings( checkHttpFieldIsValid(httpRule.getBody(), inputMessage, true); } + return parseHttpRuleHelper(httpRule, Optional.of(inputMessage), messageTypes); + } + + public static Optional> parseHttpRule(HttpRule httpRule) { + return parseHttpRuleHelper(httpRule, Optional.empty(), Collections.emptyMap()); + } + + private static Optional> parseHttpRuleHelper( + HttpRule httpRule, Optional inputMessageOpt, Map messageTypes) { // Get pattern. - Set uniqueBindings = getPatternBindings(httpRule); + Set uniqueBindings = getHttpVerbPattern(httpRule); if (uniqueBindings.isEmpty()) { return Optional.empty(); } if (httpRule.getAdditionalBindingsCount() > 0) { for (HttpRule additionalRule : httpRule.getAdditionalBindingsList()) { - uniqueBindings.addAll(getPatternBindings(additionalRule)); + uniqueBindings.addAll(getHttpVerbPattern(additionalRule)); } } @@ -69,19 +78,23 @@ public static Optional> parseHttpBindings( for (String binding : bindings) { // Handle foo.bar cases by descending into the subfields. String[] descendantBindings = binding.split("\\."); - Message containingMessage = inputMessage; + Optional containingMessageOpt = inputMessageOpt; for (int i = 0; i < descendantBindings.length; i++) { String subField = descendantBindings[i]; + if (!containingMessageOpt.isPresent()) { + continue; + } + if (i < descendantBindings.length - 1) { - Field field = containingMessage.fieldMap().get(subField); - containingMessage = messageTypes.get(field.type().reference().fullName()); + Field field = containingMessageOpt.get().fieldMap().get(subField); + containingMessageOpt = Optional.of(messageTypes.get(field.type().reference().fullName())); Preconditions.checkNotNull( - containingMessage, + containingMessageOpt.get(), String.format( "No containing message found for field %s with type %s", field.name(), field.type().reference().simpleName())); } else { - checkHttpFieldIsValid(subField, containingMessage, false); + checkHttpFieldIsValid(subField, containingMessageOpt.get(), false); } } } @@ -89,7 +102,7 @@ public static Optional> parseHttpBindings( return Optional.of(bindings); } - private static Set getPatternBindings(HttpRule httpRule) { + private static Set getHttpVerbPattern(HttpRule httpRule) { String pattern = null; // Assign a temp variable to prevent the formatter from removing the import. PatternCase patternCase = httpRule.getPatternCase(); diff --git a/src/main/java/com/google/api/generator/gapic/protoparser/Parser.java b/src/main/java/com/google/api/generator/gapic/protoparser/Parser.java index cf74a492ea..41ce3c1041 100644 --- a/src/main/java/com/google/api/generator/gapic/protoparser/Parser.java +++ b/src/main/java/com/google/api/generator/gapic/protoparser/Parser.java @@ -15,6 +15,8 @@ package com.google.api.generator.gapic.protoparser; import com.google.api.ClientProto; +import com.google.api.DocumentationRule; +import com.google.api.HttpRule; import com.google.api.ResourceDescriptor; import com.google.api.ResourceProto; import com.google.api.generator.engine.ast.TypeNode; @@ -239,6 +241,33 @@ public static List parseServices( .filter(a -> MIXIN_ALLOWLIST.contains(a.getName())) .map(a -> a.getName()) .collect(Collectors.toSet()); + // Holds the methods to be mixed in. + // Key: proto_package.ServiceName.RpcName. + // Value: HTTP rules, which clobber those in the proto. + // Assumes that http.rules.selector always specifies RPC names in the above format. + Map> mixedInMethodsToHttpRules = new HashMap<>(); + Map mixedInMethodsToDocs = new HashMap<>(); + // Parse HTTP rules and documentation, which will override the proto. + if (serviceYamlProtoOpt.isPresent()) { + for (HttpRule httpRule : serviceYamlProtoOpt.get().getHttp().getRulesList()) { + Optional> httpBindingsOpt = HttpRuleParser.parseHttpRule(httpRule); + if (!httpBindingsOpt.isPresent()) { + continue; + } + for (String rpcFullNameRaw : httpRule.getSelector().split(",")) { + String rpcFullName = rpcFullNameRaw.trim(); + mixedInMethodsToHttpRules.put(rpcFullName, httpBindingsOpt.get()); + } + } + for (DocumentationRule docRule : + serviceYamlProtoOpt.get().getDocumentation().getRulesList()) { + for (String rpcFullNameRaw : docRule.getSelector().split(",")) { + String rpcFullName = rpcFullNameRaw.trim(); + mixedInMethodsToDocs.put(rpcFullName, docRule.getDescription()); + } + } + } + Set apiDefinedRpcs = new HashSet<>(); for (Service service : services) { if (blockedCodegenMixinApis.contains(service)) { @@ -252,28 +281,55 @@ public static List parseServices( if (servicesContainBlocklistedApi && !mixedInApis.isEmpty()) { for (int i = 0; i < services.size(); i++) { Service originalService = services.get(i); - List updatedMethods = new ArrayList<>(originalService.methods()); + List updatedOriginalServiceMethods = new ArrayList<>(originalService.methods()); // If mixin APIs are present, add the methods to all other services. for (Service mixinService : blockedCodegenMixinApis) { - if (!mixedInApis.contains( - String.format("%s.%s", mixinService.protoPakkage(), mixinService.name()))) { + final String mixinServiceFullName = serviceFullNameFn.apply(mixinService); + if (!mixedInApis.contains(mixinServiceFullName)) { continue; } - mixinService - .methods() + Function methodToFullProtoNameFn = + m -> String.format("%s.%s", mixinServiceFullName, m.name()); + // Filter mixed-in methods based on those listed in the HTTP rules section of + // service.yaml. + List updatedMixinMethods = + mixinService.methods().stream() + // Mixin method inclusion is based on the HTTP rules list in service.yaml. + .filter( + m -> mixedInMethodsToHttpRules.containsKey(methodToFullProtoNameFn.apply(m))) + .map( + m -> { + // HTTP rules and RPC documentation in the service.yaml file take + // precedence. + String fullMethodName = methodToFullProtoNameFn.apply(m); + List httpBindings = + mixedInMethodsToHttpRules.containsKey(fullMethodName) + ? mixedInMethodsToHttpRules.get(fullMethodName) + : m.httpBindings(); + String docs = + mixedInMethodsToDocs.containsKey(fullMethodName) + ? mixedInMethodsToDocs.get(fullMethodName) + : m.description(); + return m.toBuilder() + .setHttpBindings(httpBindings) + .setDescription(docs) + .build(); + }) + .collect(Collectors.toList()); + // Overridden RPCs defined in the protos take precedence. + updatedMixinMethods.stream() + .filter(m -> !apiDefinedRpcs.contains(m.name())) .forEach( - m -> { - // Overridden RPCs defined in the protos take precedence. - if (!apiDefinedRpcs.contains(m.name())) { - updatedMethods.add( + m -> + updatedOriginalServiceMethods.add( m.toBuilder() .setMixedInApiName(serviceFullNameFn.apply(mixinService)) - .build()); - } - }); - outputMixinServiceSet.add(mixinService); + .build())); + outputMixinServiceSet.add( + mixinService.toBuilder().setMethods(updatedMixinMethods).build()); } - services.set(i, originalService.toBuilder().setMethods(updatedMethods).build()); + services.set( + i, originalService.toBuilder().setMethods(updatedOriginalServiceMethods).build()); } } diff --git a/test/integration/apis/kms/v1/cloudkms_test_mixins_v1.yaml b/test/integration/apis/kms/v1/cloudkms_test_mixins_v1.yaml index 4190b62d0b..2828ca13f0 100644 --- a/test/integration/apis/kms/v1/cloudkms_test_mixins_v1.yaml +++ b/test/integration/apis/kms/v1/cloudkms_test_mixins_v1.yaml @@ -21,6 +21,7 @@ documentation: Gets the access control policy for a resource. Returns an empty policy if the resource exists and does not have a policy set. + # This RPC shouldn't appear in the proto even though the documentation field is set. - selector: google.iam.v1.IAMPolicy.SetIamPolicy description: |- Sets the access control policy on the specified resource. Replaces @@ -29,31 +30,37 @@ documentation: Can return `NOT_FOUND`, `INVALID_ARGUMENT`, and `PERMISSION_DENIED` errors. + # Test the overriding of comments. - selector: google.iam.v1.IAMPolicy.TestIamPermissions description: |- - Returns permissions that a caller has on the specified resource. If the - resource does not exist, this will return an empty set of - permissions, not a `NOT_FOUND` error. - - Note: This operation is designed to be used for building - permission-aware UIs and command-line tools, not for authorization - checking. This operation may "fail open" without warning. + This is a different comment for TestIamPermissions in the yaml file that should clobber the documentation in iam_policy.proto. http: rules: + - selector: google.cloud.location.Locations.GetLocation + get: "/v1/{name=locations/*}" + body: '*' + # Test different HTTP verbs. + - selector: google.cloud.location.Locations.ListLocations + get: "/v1/{filter=*/*}/locations" + body: '*' + additional_bindings: + - post: '/v1/{page_size=*}' + body: '*' - selector: google.iam.v1.IAMPolicy.GetIamPolicy get: '/v1/{resource=projects/*/locations/*/keyRings/*}:getIamPolicy' additional_bindings: - get: '/v1/{resource=projects/*/locations/*/keyRings/*/cryptoKeys/*}:getIamPolicy' - get: '/v1/{resource=projects/*/locations/*/keyRings/*/importJobs/*}:getIamPolicy' - - selector: google.iam.v1.IAMPolicy.SetIamPolicy - post: '/v1/{resource=projects/*/locations/*/keyRings/*}:setIamPolicy' - body: '*' - additional_bindings: - - post: '/v1/{resource=projects/*/locations/*/keyRings/*/cryptoKeys/*}:setIamPolicy' - body: '*' - - post: '/v1/{resource=projects/*/locations/*/keyRings/*/importJobs/*}:setIamPolicy' - body: '*' + # Test the omission of SetIamPolicy - this should no longer appear in the generated client. +# - selector: google.iam.v1.IAMPolicy.SetIamPolicy +# post: '/v1/{resource=projects/*/locations/*/keyRings/*}:setIamPolicy' +# body: '*' +# additional_bindings: +# - post: '/v1/{resource=projects/*/locations/*/keyRings/*/cryptoKeys/*}:setIamPolicy' +# body: '*' +# - post: '/v1/{resource=projects/*/locations/*/keyRings/*/importJobs/*}:setIamPolicy' +# body: '*' - selector: google.iam.v1.IAMPolicy.TestIamPermissions post: '/v1/{resource=projects/*/locations/*/keyRings/*}:testIamPermissions' body: '*' diff --git a/test/integration/goldens/kms/com/google/cloud/kms/v1/KeyManagementServiceClient.java b/test/integration/goldens/kms/com/google/cloud/kms/v1/KeyManagementServiceClient.java index 19ddbcd661..cc3e563cff 100644 --- a/test/integration/goldens/kms/com/google/cloud/kms/v1/KeyManagementServiceClient.java +++ b/test/integration/goldens/kms/com/google/cloud/kms/v1/KeyManagementServiceClient.java @@ -36,7 +36,6 @@ import com.google.common.util.concurrent.MoreExecutors; import com.google.iam.v1.GetIamPolicyRequest; import com.google.iam.v1.Policy; -import com.google.iam.v1.SetIamPolicyRequest; import com.google.iam.v1.TestIamPermissionsRequest; import com.google.iam.v1.TestIamPermissionsResponse; import com.google.protobuf.ByteString; @@ -3334,62 +3333,8 @@ public final UnaryCallable getLocationCallable() { // AUTO-GENERATED DOCUMENTATION AND METHOD. /** - * Sets the access control policy on the specified resource. Replaces any existing policy. - * - *

Sample code: - * - *

{@code
-   * try (KeyManagementServiceClient keyManagementServiceClient =
-   *     KeyManagementServiceClient.create()) {
-   *   SetIamPolicyRequest request =
-   *       SetIamPolicyRequest.newBuilder()
-   *           .setResource(KeyRingName.of("[PROJECT]", "[LOCATION]", "[KEY_RING]").toString())
-   *           .setPolicy(Policy.newBuilder().build())
-   *           .build();
-   *   Policy response = keyManagementServiceClient.setIamPolicy(request);
-   * }
-   * }
- * - * @param request The request object containing all of the parameters for the API call. - * @throws com.google.api.gax.rpc.ApiException if the remote call fails - */ - public final Policy setIamPolicy(SetIamPolicyRequest request) { - return setIamPolicyCallable().call(request); - } - - // AUTO-GENERATED DOCUMENTATION AND METHOD. - /** - * Sets the access control policy on the specified resource. Replaces any existing policy. - * - *

Sample code: - * - *

{@code
-   * try (KeyManagementServiceClient keyManagementServiceClient =
-   *     KeyManagementServiceClient.create()) {
-   *   SetIamPolicyRequest request =
-   *       SetIamPolicyRequest.newBuilder()
-   *           .setResource(KeyRingName.of("[PROJECT]", "[LOCATION]", "[KEY_RING]").toString())
-   *           .setPolicy(Policy.newBuilder().build())
-   *           .build();
-   *   ApiFuture future =
-   *       keyManagementServiceClient.setIamPolicyCallable().futureCall(request);
-   *   // Do something.
-   *   Policy response = future.get();
-   * }
-   * }
- */ - public final UnaryCallable setIamPolicyCallable() { - return stub.setIamPolicyCallable(); - } - - // AUTO-GENERATED DOCUMENTATION AND METHOD. - /** - * Returns permissions that a caller has on the specified resource. If the resource does not - * exist, this will return an empty set of permissions, not a NOT_FOUND error. - * - *

Note: This operation is designed to be used for building permission-aware UIs and - * command-line tools, not for authorization checking. This operation may "fail open" without - * warning. + * This is a different comment for TestIamPermissions in the yaml file that should clobber the + * documentation in iam_policy.proto. * *

Sample code: * @@ -3414,12 +3359,8 @@ public final TestIamPermissionsResponse testIamPermissions(TestIamPermissionsReq // AUTO-GENERATED DOCUMENTATION AND METHOD. /** - * Returns permissions that a caller has on the specified resource. If the resource does not - * exist, this will return an empty set of permissions, not a NOT_FOUND error. - * - *

Note: This operation is designed to be used for building permission-aware UIs and - * command-line tools, not for authorization checking. This operation may "fail open" without - * warning. + * This is a different comment for TestIamPermissions in the yaml file that should clobber the + * documentation in iam_policy.proto. * *

Sample code: * diff --git a/test/integration/goldens/kms/com/google/cloud/kms/v1/KeyManagementServiceClientTest.java b/test/integration/goldens/kms/com/google/cloud/kms/v1/KeyManagementServiceClientTest.java index 0d02ab2526..b1952fc8e3 100644 --- a/test/integration/goldens/kms/com/google/cloud/kms/v1/KeyManagementServiceClientTest.java +++ b/test/integration/goldens/kms/com/google/cloud/kms/v1/KeyManagementServiceClientTest.java @@ -41,7 +41,6 @@ import com.google.iam.v1.GetPolicyOptions; import com.google.iam.v1.MockIAMPolicy; import com.google.iam.v1.Policy; -import com.google.iam.v1.SetIamPolicyRequest; import com.google.iam.v1.TestIamPermissionsRequest; import com.google.iam.v1.TestIamPermissionsResponse; import com.google.protobuf.AbstractMessage; @@ -77,12 +76,12 @@ public class KeyManagementServiceClientTest { @BeforeClass public static void startStaticServer() { mockKeyManagementService = new MockKeyManagementService(); - mockLocations = new MockLocations(); mockIAMPolicy = new MockIAMPolicy(); + mockLocations = new MockLocations(); mockServiceHelper = new MockServiceHelper( UUID.randomUUID().toString(), - Arrays.asList(mockKeyManagementService, mockLocations, mockIAMPolicy)); + Arrays.asList(mockKeyManagementService, mockIAMPolicy, mockLocations)); mockServiceHelper.start(); } @@ -2374,55 +2373,6 @@ public void getLocationExceptionTest() throws Exception { } } - @Test - public void setIamPolicyTest() throws Exception { - Policy expectedResponse = - Policy.newBuilder() - .setVersion(351608024) - .addAllBindings(new ArrayList()) - .setEtag(ByteString.EMPTY) - .build(); - mockIAMPolicy.addResponse(expectedResponse); - - SetIamPolicyRequest request = - SetIamPolicyRequest.newBuilder() - .setResource(KeyRingName.of("[PROJECT]", "[LOCATION]", "[KEY_RING]").toString()) - .setPolicy(Policy.newBuilder().build()) - .build(); - - Policy actualResponse = client.setIamPolicy(request); - Assert.assertEquals(expectedResponse, actualResponse); - - List actualRequests = mockIAMPolicy.getRequests(); - Assert.assertEquals(1, actualRequests.size()); - SetIamPolicyRequest actualRequest = ((SetIamPolicyRequest) actualRequests.get(0)); - - Assert.assertEquals(request.getResource(), actualRequest.getResource()); - Assert.assertEquals(request.getPolicy(), actualRequest.getPolicy()); - Assert.assertTrue( - channelProvider.isHeaderSent( - ApiClientHeaderProvider.getDefaultApiClientHeaderKey(), - GaxGrpcProperties.getDefaultApiClientHeaderPattern())); - } - - @Test - public void setIamPolicyExceptionTest() throws Exception { - StatusRuntimeException exception = new StatusRuntimeException(io.grpc.Status.INVALID_ARGUMENT); - mockIAMPolicy.addException(exception); - - try { - SetIamPolicyRequest request = - SetIamPolicyRequest.newBuilder() - .setResource(KeyRingName.of("[PROJECT]", "[LOCATION]", "[KEY_RING]").toString()) - .setPolicy(Policy.newBuilder().build()) - .build(); - client.setIamPolicy(request); - Assert.fail("No exception raised"); - } catch (InvalidArgumentException e) { - // Expected exception. - } - } - @Test public void testIamPermissionsTest() throws Exception { TestIamPermissionsResponse expectedResponse = diff --git a/test/integration/goldens/kms/com/google/cloud/kms/v1/KeyManagementServiceSettings.java b/test/integration/goldens/kms/com/google/cloud/kms/v1/KeyManagementServiceSettings.java index bf38dcd54e..d749c91145 100644 --- a/test/integration/goldens/kms/com/google/cloud/kms/v1/KeyManagementServiceSettings.java +++ b/test/integration/goldens/kms/com/google/cloud/kms/v1/KeyManagementServiceSettings.java @@ -41,7 +41,6 @@ import com.google.cloud.location.Location; import com.google.iam.v1.GetIamPolicyRequest; import com.google.iam.v1.Policy; -import com.google.iam.v1.SetIamPolicyRequest; import com.google.iam.v1.TestIamPermissionsRequest; import com.google.iam.v1.TestIamPermissionsResponse; import java.io.IOException; @@ -233,11 +232,6 @@ public UnaryCallSettings getLocationSettings() { return ((KeyManagementServiceStubSettings) getStubSettings()).getLocationSettings(); } - /** Returns the object with the settings used for calls to setIamPolicy. */ - public UnaryCallSettings setIamPolicySettings() { - return ((KeyManagementServiceStubSettings) getStubSettings()).setIamPolicySettings(); - } - /** Returns the object with the settings used for calls to testIamPermissions. */ public UnaryCallSettings testIamPermissionsSettings() { @@ -494,11 +488,6 @@ public UnaryCallSettings.Builder getLocationSettin return getStubSettingsBuilder().getLocationSettings(); } - /** Returns the builder for the settings used for calls to setIamPolicy. */ - public UnaryCallSettings.Builder setIamPolicySettings() { - return getStubSettingsBuilder().setIamPolicySettings(); - } - /** Returns the builder for the settings used for calls to testIamPermissions. */ public UnaryCallSettings.Builder testIamPermissionsSettings() { diff --git a/test/integration/goldens/kms/com/google/cloud/kms/v1/gapic_metadata.json b/test/integration/goldens/kms/com/google/cloud/kms/v1/gapic_metadata.json index a3c2c93ed7..73abe153f4 100644 --- a/test/integration/goldens/kms/com/google/cloud/kms/v1/gapic_metadata.json +++ b/test/integration/goldens/kms/com/google/cloud/kms/v1/gapic_metadata.json @@ -79,9 +79,6 @@ "RestoreCryptoKeyVersion": { "methods": ["restoreCryptoKeyVersion", "restoreCryptoKeyVersion", "restoreCryptoKeyVersion", "restoreCryptoKeyVersionCallable"] }, - "SetIamPolicy": { - "methods": ["setIamPolicy", "setIamPolicyCallable"] - }, "TestIamPermissions": { "methods": ["testIamPermissions", "testIamPermissionsCallable"] }, diff --git a/test/integration/goldens/kms/com/google/cloud/kms/v1/stub/GrpcKeyManagementServiceStub.java b/test/integration/goldens/kms/com/google/cloud/kms/v1/stub/GrpcKeyManagementServiceStub.java index f2dcc16fa9..19065361ed 100644 --- a/test/integration/goldens/kms/com/google/cloud/kms/v1/stub/GrpcKeyManagementServiceStub.java +++ b/test/integration/goldens/kms/com/google/cloud/kms/v1/stub/GrpcKeyManagementServiceStub.java @@ -72,7 +72,6 @@ import com.google.common.collect.ImmutableMap; import com.google.iam.v1.GetIamPolicyRequest; import com.google.iam.v1.Policy; -import com.google.iam.v1.SetIamPolicyRequest; import com.google.iam.v1.TestIamPermissionsRequest; import com.google.iam.v1.TestIamPermissionsResponse; import com.google.longrunning.stub.GrpcOperationsStub; @@ -345,14 +344,6 @@ public class GrpcKeyManagementServiceStub extends KeyManagementServiceStub { .setResponseMarshaller(ProtoUtils.marshaller(Location.getDefaultInstance())) .build(); - private static final MethodDescriptor setIamPolicyMethodDescriptor = - MethodDescriptor.newBuilder() - .setType(MethodDescriptor.MethodType.UNARY) - .setFullMethodName("google.iam.v1.IAMPolicy/SetIamPolicy") - .setRequestMarshaller(ProtoUtils.marshaller(SetIamPolicyRequest.getDefaultInstance())) - .setResponseMarshaller(ProtoUtils.marshaller(Policy.getDefaultInstance())) - .build(); - private static final MethodDescriptor testIamPermissionsMethodDescriptor = MethodDescriptor.newBuilder() @@ -409,7 +400,6 @@ public class GrpcKeyManagementServiceStub extends KeyManagementServiceStub { private final UnaryCallable listLocationsPagedCallable; private final UnaryCallable getLocationCallable; - private final UnaryCallable setIamPolicyCallable; private final UnaryCallable testIamPermissionsCallable; @@ -793,7 +783,8 @@ public Map extract(GetIamPolicyRequest request) { @Override public Map extract(ListLocationsRequest request) { ImmutableMap.Builder params = ImmutableMap.builder(); - params.put("name", String.valueOf(request.getName())); + params.put("filter", String.valueOf(request.getFilter())); + params.put("page_size", String.valueOf(request.getPageSize())); return params.build(); } }) @@ -811,19 +802,6 @@ public Map extract(GetLocationRequest request) { } }) .build(); - GrpcCallSettings setIamPolicyTransportSettings = - GrpcCallSettings.newBuilder() - .setMethodDescriptor(setIamPolicyMethodDescriptor) - .setParamsExtractor( - new RequestParamsExtractor() { - @Override - public Map extract(SetIamPolicyRequest request) { - ImmutableMap.Builder params = ImmutableMap.builder(); - params.put("resource", String.valueOf(request.getResource())); - return params.build(); - } - }) - .build(); GrpcCallSettings testIamPermissionsTransportSettings = GrpcCallSettings.newBuilder() @@ -952,9 +930,6 @@ public Map extract(TestIamPermissionsRequest request) { this.getLocationCallable = callableFactory.createUnaryCallable( getLocationTransportSettings, settings.getLocationSettings(), clientContext); - this.setIamPolicyCallable = - callableFactory.createUnaryCallable( - setIamPolicyTransportSettings, settings.setIamPolicySettings(), clientContext); this.testIamPermissionsCallable = callableFactory.createUnaryCallable( testIamPermissionsTransportSettings, @@ -1136,11 +1111,6 @@ public UnaryCallable getLocationCallable() { return getLocationCallable; } - @Override - public UnaryCallable setIamPolicyCallable() { - return setIamPolicyCallable; - } - @Override public UnaryCallable testIamPermissionsCallable() { diff --git a/test/integration/goldens/kms/com/google/cloud/kms/v1/stub/KeyManagementServiceStub.java b/test/integration/goldens/kms/com/google/cloud/kms/v1/stub/KeyManagementServiceStub.java index 3c6cb33625..14915e1ae7 100644 --- a/test/integration/goldens/kms/com/google/cloud/kms/v1/stub/KeyManagementServiceStub.java +++ b/test/integration/goldens/kms/com/google/cloud/kms/v1/stub/KeyManagementServiceStub.java @@ -66,7 +66,6 @@ import com.google.cloud.location.Location; import com.google.iam.v1.GetIamPolicyRequest; import com.google.iam.v1.Policy; -import com.google.iam.v1.SetIamPolicyRequest; import com.google.iam.v1.TestIamPermissionsRequest; import com.google.iam.v1.TestIamPermissionsResponse; import javax.annotation.Generated; @@ -218,10 +217,6 @@ public UnaryCallable getLocationCallable() { throw new UnsupportedOperationException("Not implemented: getLocationCallable()"); } - public UnaryCallable setIamPolicyCallable() { - throw new UnsupportedOperationException("Not implemented: setIamPolicyCallable()"); - } - public UnaryCallable testIamPermissionsCallable() { throw new UnsupportedOperationException("Not implemented: testIamPermissionsCallable()"); diff --git a/test/integration/goldens/kms/com/google/cloud/kms/v1/stub/KeyManagementServiceStubSettings.java b/test/integration/goldens/kms/com/google/cloud/kms/v1/stub/KeyManagementServiceStubSettings.java index dc9718e802..5ebc43167f 100644 --- a/test/integration/goldens/kms/com/google/cloud/kms/v1/stub/KeyManagementServiceStubSettings.java +++ b/test/integration/goldens/kms/com/google/cloud/kms/v1/stub/KeyManagementServiceStubSettings.java @@ -90,7 +90,6 @@ import com.google.common.collect.Lists; import com.google.iam.v1.GetIamPolicyRequest; import com.google.iam.v1.Policy; -import com.google.iam.v1.SetIamPolicyRequest; import com.google.iam.v1.TestIamPermissionsRequest; import com.google.iam.v1.TestIamPermissionsResponse; import java.io.IOException; @@ -188,7 +187,6 @@ public class KeyManagementServiceStubSettings ListLocationsRequest, ListLocationsResponse, ListLocationsPagedResponse> listLocationsSettings; private final UnaryCallSettings getLocationSettings; - private final UnaryCallSettings setIamPolicySettings; private final UnaryCallSettings testIamPermissionsSettings; @@ -619,11 +617,6 @@ public UnaryCallSettings getLocationSettings() { return getLocationSettings; } - /** Returns the object with the settings used for calls to setIamPolicy. */ - public UnaryCallSettings setIamPolicySettings() { - return setIamPolicySettings; - } - /** Returns the object with the settings used for calls to testIamPermissions. */ public UnaryCallSettings testIamPermissionsSettings() { @@ -726,7 +719,6 @@ protected KeyManagementServiceStubSettings(Builder settingsBuilder) throws IOExc getIamPolicySettings = settingsBuilder.getIamPolicySettings().build(); listLocationsSettings = settingsBuilder.listLocationsSettings().build(); getLocationSettings = settingsBuilder.getLocationSettings().build(); - setIamPolicySettings = settingsBuilder.setIamPolicySettings().build(); testIamPermissionsSettings = settingsBuilder.testIamPermissionsSettings().build(); } @@ -784,7 +776,6 @@ public static class Builder ListLocationsRequest, ListLocationsResponse, ListLocationsPagedResponse> listLocationsSettings; private final UnaryCallSettings.Builder getLocationSettings; - private final UnaryCallSettings.Builder setIamPolicySettings; private final UnaryCallSettings.Builder testIamPermissionsSettings; private static final ImmutableMap> @@ -867,7 +858,6 @@ protected Builder(ClientContext clientContext) { getIamPolicySettings = UnaryCallSettings.newUnaryCallSettingsBuilder(); listLocationsSettings = PagedCallSettings.newBuilder(LIST_LOCATIONS_PAGE_STR_FACT); getLocationSettings = UnaryCallSettings.newUnaryCallSettingsBuilder(); - setIamPolicySettings = UnaryCallSettings.newUnaryCallSettingsBuilder(); testIamPermissionsSettings = UnaryCallSettings.newUnaryCallSettingsBuilder(); unaryMethodSettingsBuilders = @@ -898,7 +888,6 @@ protected Builder(ClientContext clientContext) { getIamPolicySettings, listLocationsSettings, getLocationSettings, - setIamPolicySettings, testIamPermissionsSettings); initDefaults(this); } @@ -933,7 +922,6 @@ protected Builder(KeyManagementServiceStubSettings settings) { getIamPolicySettings = settings.getIamPolicySettings.toBuilder(); listLocationsSettings = settings.listLocationsSettings.toBuilder(); getLocationSettings = settings.getLocationSettings.toBuilder(); - setIamPolicySettings = settings.setIamPolicySettings.toBuilder(); testIamPermissionsSettings = settings.testIamPermissionsSettings.toBuilder(); unaryMethodSettingsBuilders = @@ -964,7 +952,6 @@ protected Builder(KeyManagementServiceStubSettings settings) { getIamPolicySettings, listLocationsSettings, getLocationSettings, - setIamPolicySettings, testIamPermissionsSettings); } @@ -1110,11 +1097,6 @@ private static Builder initDefaults(Builder builder) { .setRetryableCodes(RETRYABLE_CODE_DEFINITIONS.get("no_retry_codes")) .setRetrySettings(RETRY_PARAM_DEFINITIONS.get("no_retry_params")); - builder - .setIamPolicySettings() - .setRetryableCodes(RETRYABLE_CODE_DEFINITIONS.get("retry_policy_1_codes")) - .setRetrySettings(RETRY_PARAM_DEFINITIONS.get("retry_policy_1_params")); - builder .testIamPermissionsSettings() .setRetryableCodes(RETRYABLE_CODE_DEFINITIONS.get("retry_policy_1_codes")) @@ -1290,11 +1272,6 @@ public UnaryCallSettings.Builder getLocationSettin return getLocationSettings; } - /** Returns the builder for the settings used for calls to setIamPolicy. */ - public UnaryCallSettings.Builder setIamPolicySettings() { - return setIamPolicySettings; - } - /** Returns the builder for the settings used for calls to testIamPermissions. */ public UnaryCallSettings.Builder testIamPermissionsSettings() { diff --git a/test/integration/goldens/kms/com/google/iam/v1/MockIAMPolicyImpl.java b/test/integration/goldens/kms/com/google/iam/v1/MockIAMPolicyImpl.java index fc661c900c..6245f271c9 100644 --- a/test/integration/goldens/kms/com/google/iam/v1/MockIAMPolicyImpl.java +++ b/test/integration/goldens/kms/com/google/iam/v1/MockIAMPolicyImpl.java @@ -58,26 +58,6 @@ public void reset() { responses = new LinkedList<>(); } - @Override - public void setIamPolicy(SetIamPolicyRequest request, StreamObserver responseObserver) { - Object response = responses.poll(); - if (response instanceof Policy) { - requests.add(request); - responseObserver.onNext(((Policy) response)); - responseObserver.onCompleted(); - } else if (response instanceof Exception) { - responseObserver.onError(((Exception) response)); - } else { - responseObserver.onError( - new IllegalArgumentException( - String.format( - "Unrecognized response type %s for method SetIamPolicy, expected %s or %s", - response == null ? "null" : response.getClass().getName(), - Policy.class.getName(), - Exception.class.getName()))); - } - } - @Override public void getIamPolicy(GetIamPolicyRequest request, StreamObserver responseObserver) { Object response = responses.poll(); From 9cc9b89246d383b0c8fc9119cce8ea6ec6ea1903 Mon Sep 17 00:00:00 2001 From: "release-please[bot]" <55107282+release-please[bot]@users.noreply.github.com> Date: Thu, 20 May 2021 13:35:46 -0700 Subject: [PATCH 06/16] chore: release 1.0.6 (#728) * chore: release 1.0.6 * Update CHANGELOG.md Co-authored-by: release-please[bot] <55107282+release-please[bot]@users.noreply.github.com> Co-authored-by: Mira Leung --- CHANGELOG.md | 7 +++++++ version.txt | 2 +- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1ca661a4d7..df4f90c1fd 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,12 @@ # Changelog +### [1.0.6](https://www.github.com/googleapis/gapic-generator-java/compare/v1.0.5...v1.0.6) (2021-05-19) + + +### Bug Fixes + +* **mixins:** Gate mixin RPC on HTTP rules, add yaml doc/http overrides ([#727](https://www.github.com/googleapis/gapic-generator-java/issues/727)) ([229da5d](https://www.github.com/googleapis/gapic-generator-java/commit/229da5d94cf7db060abf3ea006a20d1ade804597)) + ### [1.0.5](https://www.github.com/googleapis/gapic-generator-java/compare/v1.0.4...v1.0.5) (2021-05-17) diff --git a/version.txt b/version.txt index 90a27f9cea..af0b7ddbff 100644 --- a/version.txt +++ b/version.txt @@ -1 +1 @@ -1.0.5 +1.0.6 From 6e3f53303d37db063285ca279cd0f4b31ccb0986 Mon Sep 17 00:00:00 2001 From: vam-google Date: Thu, 20 May 2021 17:00:54 -0700 Subject: [PATCH 07/16] chore: DIREGAPIC #2 TransportServiceCallableFactoryComposer refactoring --- ...ctServiceCallableFactoryClassComposer.java | 91 +++++-------------- .../AbstractServiceSettingsClassComposer.java | 31 ++++--- .../gapic/composer/common/BUILD.bazel | 5 +- .../common}/TransportContext.java | 22 +++-- .../gapic/composer/grpc/GrpcContext.java | 6 +- ...pcServiceCallableFactoryClassComposer.java | 37 ++------ .../grpc/ServiceSettingsClassComposer.java | 4 + .../generator/gapic/model/GapicContext.java | 4 +- .../api/generator/gapic/model/Transport.java | 28 ++++++ .../generator/gapic/protoparser/Parser.java | 4 +- .../composer/common/TestProtoLoader.java | 23 +++-- .../composer/grpc/GrpcTestProtoLoader.java | 5 +- 12 files changed, 118 insertions(+), 142 deletions(-) rename src/main/java/com/google/api/generator/gapic/{model => composer/common}/TransportContext.java (89%) create mode 100644 src/main/java/com/google/api/generator/gapic/model/Transport.java diff --git a/src/main/java/com/google/api/generator/gapic/composer/common/AbstractServiceCallableFactoryClassComposer.java b/src/main/java/com/google/api/generator/gapic/composer/common/AbstractServiceCallableFactoryClassComposer.java index 649fb50954..280c9712b2 100644 --- a/src/main/java/com/google/api/generator/gapic/composer/common/AbstractServiceCallableFactoryClassComposer.java +++ b/src/main/java/com/google/api/generator/gapic/composer/common/AbstractServiceCallableFactoryClassComposer.java @@ -37,13 +37,11 @@ import com.google.api.generator.engine.ast.VariableExpr; import com.google.api.generator.gapic.composer.comment.StubCommentComposer; import com.google.api.generator.gapic.composer.store.TypeStore; -import com.google.api.generator.gapic.composer.utils.ClassNames; import com.google.api.generator.gapic.composer.utils.PackageChecker; import com.google.api.generator.gapic.model.GapicClass; import com.google.api.generator.gapic.model.GapicClass.Kind; import com.google.api.generator.gapic.model.GapicContext; import com.google.api.generator.gapic.model.Service; -import com.google.common.base.Preconditions; import java.util.ArrayList; import java.util.Arrays; import java.util.List; @@ -51,81 +49,41 @@ import javax.annotation.Generated; public abstract class AbstractServiceCallableFactoryClassComposer implements ClassComposer { + private final TransportContext transportContext; - private final TypeStore fixedTypeStore; - private final StubCommentComposer commentComposer; - private final ClassNames classNames; - private final Class transportCallSettingsClass; - private final Class transportCallableFactoryClass; - private final Class operationStubClass; - private final String transportCallSettingsName; + protected AbstractServiceCallableFactoryClassComposer(TransportContext transportContext) { + this.transportContext = transportContext; + } - protected AbstractServiceCallableFactoryClassComposer( - TypeStore fixedTypeStore, - StubCommentComposer commentComposer, - ClassNames classNames, - Class transportCallSettingsClass, - Class transportCallableFactoryClass, - Class operationStubClass, - String transportCallSettingsName) { - this.fixedTypeStore = fixedTypeStore; - this.commentComposer = commentComposer; - this.classNames = classNames; - this.transportCallSettingsClass = transportCallSettingsClass; - this.transportCallableFactoryClass = transportCallableFactoryClass; - this.operationStubClass = operationStubClass; - this.transportCallSettingsName = transportCallSettingsName; + protected TransportContext getTransportContext() { + return transportContext; } @Override - public GapicClass generate(GapicContext ignored, Service service) { - String className = getClassNames().getTransportServiceCallableFactoryClassName(service); + public GapicClass generate(GapicContext context, Service service) { + TypeStore typeStore = createTypes(); + String className = + getTransportContext().classNames().getTransportServiceCallableFactoryClassName(service); GapicClass.Kind kind = Kind.STUB; String pakkage = String.format("%s.stub", service.pakkage()); + StubCommentComposer commentComposer = + new StubCommentComposer(getTransportContext().transportName()); ClassDefinition classDef = ClassDefinition.builder() .setPackageString(pakkage) .setHeaderCommentStatements( - getCommentComposer().createTransportServiceCallableFactoryClassHeaderComments( + commentComposer.createTransportServiceCallableFactoryClassHeaderComments( service.name(), service.isDeprecated())) - .setAnnotations(createClassAnnotations(service, fixedTypeStore)) - .setImplementsTypes(createClassImplements(fixedTypeStore)) + .setAnnotations(createClassAnnotations(service, typeStore)) + .setImplementsTypes(createClassImplements(typeStore)) .setName(className) - .setMethods(createClassMethods(fixedTypeStore)) + .setMethods(createClassMethods(typeStore)) .setScope(ScopeNode.PUBLIC) .build(); return GapicClass.create(kind, classDef); } - protected TypeStore getFixedTypeStore() { - return fixedTypeStore; - } - - protected StubCommentComposer getCommentComposer() { - return commentComposer; - } - - protected ClassNames getClassNames() { - return classNames; - } - - protected Class getTransportCallSettingsClass() { - return transportCallSettingsClass; - } - - protected Class getTransportCallableFactoryClass() { - return transportCallableFactoryClass; - } - - protected Class getOperationStubClass() { - return operationStubClass; - } - - protected String getTransportCallSettingsName() { - return transportCallSettingsName; - } - protected List createClassAnnotations(Service service, TypeStore typeStore) { List annotations = new ArrayList<>(); if (!PackageChecker.isGaApi(service.pakkage())) { @@ -231,7 +189,6 @@ protected MethodDefinition createGenericCallableMethod( String methodName = String.format("create%sCallable", methodVariantName); String callSettingsTypeName = String.format("%sCallSettings", callSettingsVariantName); String returnTypeName = String.format("%sCallable", returnCallableKindName); - String transportCallSettingsTypeName = getTransportCallSettingsClass().getSimpleName(); boolean isOperationCallable = methodVariantName.equals("Operation"); List arguments = new ArrayList<>(); @@ -239,8 +196,8 @@ protected MethodDefinition createGenericCallableMethod( VariableExpr.builder() .setVariable( Variable.builder() - .setName(getTransportCallSettingsName()) - .setType(typeStore.get(transportCallSettingsTypeName)) + .setName(getTransportContext().transportCallSettingsName()) + .setType(getTransportContext().transportCallSettingsType()) .build()) .setIsDecl(true) .setTemplateObjects(transportCallSettingsTemplateObjects) @@ -270,23 +227,17 @@ protected MethodDefinition createGenericCallableMethod( .setVariable( Variable.builder() .setName("operationsStub") - .setType(typeStore.get(getOperationStubClass().getSimpleName())) + .setType(getTransportContext().operationsStubType()) .build()) .setIsDecl(true) .build()); } - String transportCallableFactoryTypeName = getTransportCallableFactoryClass().getSimpleName(); - TypeNode transportCallableFactoryType = typeStore.get(transportCallableFactoryTypeName); - Preconditions.checkNotNull( - transportCallableFactoryType, - String.format("Type %s not found", transportCallableFactoryTypeName)); - TypeNode returnType = typeStore.get(returnTypeName); MethodInvocationExpr returnExpr = MethodInvocationExpr.builder() .setMethodName(methodName) - .setStaticReferenceType(transportCallableFactoryType) + .setStaticReferenceType(getTransportContext().transportCallableFactoryType()) .setArguments( arguments.stream() .map(v -> v.toBuilder().setIsDecl(false).build()) @@ -306,7 +257,7 @@ protected MethodDefinition createGenericCallableMethod( .build(); } - protected static TypeStore createCommonTypes() { + private static TypeStore createTypes() { List concreteClazzes = Arrays.asList( // Gax-java classes. diff --git a/src/main/java/com/google/api/generator/gapic/composer/common/AbstractServiceSettingsClassComposer.java b/src/main/java/com/google/api/generator/gapic/composer/common/AbstractServiceSettingsClassComposer.java index fdfa9c7177..14e79caab9 100644 --- a/src/main/java/com/google/api/generator/gapic/composer/common/AbstractServiceSettingsClassComposer.java +++ b/src/main/java/com/google/api/generator/gapic/composer/common/AbstractServiceSettingsClassComposer.java @@ -60,7 +60,6 @@ import com.google.api.generator.gapic.model.Method; import com.google.api.generator.gapic.model.Method.Stream; import com.google.api.generator.gapic.model.Service; -import com.google.api.generator.gapic.model.TransportContext; import com.google.api.generator.gapic.utils.JavaStyle; import com.google.common.base.Preconditions; import com.google.longrunning.Operation; @@ -83,6 +82,16 @@ public abstract class AbstractServiceSettingsClassComposer implements ClassCompo private static final String SETTINGS_LITERAL = "Settings"; private static final TypeStore FIXED_TYPESTORE = createStaticTypes(); + private final TransportContext transportContext; + + protected AbstractServiceSettingsClassComposer(TransportContext transportContext) { + this.transportContext = transportContext; + } + + protected TransportContext getTransportContext() { + return transportContext; + } + @Override public GapicClass generate(GapicContext context, Service service) { String pakkage = service.pakkage(); @@ -108,7 +117,7 @@ public GapicClass generate(GapicContext context, Service service) { typeStore .get(ClassNames.getServiceSettingsClassName(service)) .reference())))) - .setMethods(createClassMethods(context.transportContext(), service, typeStore)) + .setMethods(createClassMethods(service, typeStore)) .setNestedClasses(Arrays.asList(createNestedBuilderClass(service, typeStore))) .build(); return GapicClass.create(kind, classDef); @@ -158,12 +167,11 @@ private static List createClassAnnotations(Service service) { return annotations; } - private static List createClassMethods( - TransportContext transportContext, Service service, TypeStore typeStore) { + private List createClassMethods(Service service, TypeStore typeStore) { List javaMethods = new ArrayList<>(); javaMethods.addAll(createSettingsGetterMethods(service, typeStore)); javaMethods.add(createCreatorMethod(service, typeStore)); - javaMethods.addAll(createDefaultGetterMethods(transportContext, service, typeStore)); + javaMethods.addAll(createDefaultGetterMethods(service, typeStore)); javaMethods.addAll(createBuilderHelperMethods(service, typeStore)); javaMethods.add(createConstructorMethod(service, typeStore)); return javaMethods; @@ -193,7 +201,8 @@ private static MethodDefinition createConstructorMethod(Service service, TypeSto } // TODO(miraleung): Consider merging this with createNestedBuilderSettingsGetterMethods. - private static List createSettingsGetterMethods(Service service, TypeStore typeStore) { + private static List createSettingsGetterMethods( + Service service, TypeStore typeStore) { TypeNode stubSettingsType = typeStore.get(ClassNames.getServiceStubSettingsClassName(service)); BiFunction methodMakerFn = (retType, javaMethodName) -> @@ -295,8 +304,7 @@ private static MethodDefinition createCreatorMethod(Service service, TypeStore t .build(); } - private static List createDefaultGetterMethods( - TransportContext transportContext, Service service, TypeStore typeStore) { + private List createDefaultGetterMethods(Service service, TypeStore typeStore) { BiFunction methodStarterFn = (mName, retType) -> MethodDefinition.builder() @@ -346,8 +354,8 @@ private static List createDefaultGetterMethods( javaMethods.add( methodMakerFn.apply( methodStarterFn.apply( - transportContext.defaultTransportProviderBuilderName(), - typeMakerFn.apply(transportContext.instantiatingChannelProviderClass())), + getTransportContext().defaultTransportProviderBuilderName(), + typeMakerFn.apply(getTransportContext().instantiatingChannelProviderClass())), SettingsCommentComposer.DEFAULT_TRANSPORT_PROVIDER_BUILDER_METHOD_COMMENT)); javaMethods.add( @@ -375,7 +383,8 @@ private static List createDefaultGetterMethods( return javaMethods; } - private static List createBuilderHelperMethods(Service service, TypeStore typeStore) { + private static List createBuilderHelperMethods( + Service service, TypeStore typeStore) { TypeNode builderType = typeStore.get(BUILDER_CLASS_NAME); MethodDefinition newBuilderMethodOne = MethodDefinition.builder() diff --git a/src/main/java/com/google/api/generator/gapic/composer/common/BUILD.bazel b/src/main/java/com/google/api/generator/gapic/composer/common/BUILD.bazel index be2ec575c3..8423f4ff78 100644 --- a/src/main/java/com/google/api/generator/gapic/composer/common/BUILD.bazel +++ b/src/main/java/com/google/api/generator/gapic/composer/common/BUILD.bazel @@ -14,6 +14,7 @@ java_library( ], deps = [ "//:service_config_java_proto", + "//src/main/java/com/google/api/generator:autovalue", "//src/main/java/com/google/api/generator/engine/ast", "//src/main/java/com/google/api/generator/engine/writer", "//src/main/java/com/google/api/generator/gapic:status_java_proto", @@ -27,10 +28,12 @@ java_library( "//src/main/java/com/google/api/generator/gapic/utils", "//src/main/java/com/google/api/generator/util", "@com_google_api_api_common//jar", - "@com_google_api_gax_java//gax:gax", + "@com_google_api_gax_java//gax", "@com_google_api_gax_java//gax:gax_testlib", "@com_google_api_gax_java//gax-grpc:gax_grpc", "@com_google_api_gax_java//gax-grpc:gax_grpc_testlib", + "@com_google_auto_value_auto_value//jar", + "@com_google_auto_value_auto_value_annotations//jar", "@com_google_code_findbugs_jsr305//jar", "@com_google_googleapis//gapic/metadata:metadata_java_proto", "@com_google_googleapis//google/api:api_java_proto", diff --git a/src/main/java/com/google/api/generator/gapic/model/TransportContext.java b/src/main/java/com/google/api/generator/gapic/composer/common/TransportContext.java similarity index 89% rename from src/main/java/com/google/api/generator/gapic/model/TransportContext.java rename to src/main/java/com/google/api/generator/gapic/composer/common/TransportContext.java index c88cfadc69..cce00dcc9e 100644 --- a/src/main/java/com/google/api/generator/gapic/model/TransportContext.java +++ b/src/main/java/com/google/api/generator/gapic/composer/common/TransportContext.java @@ -12,27 +12,24 @@ // See the License for the specific language governing permissions and // limitations under the License. -package com.google.api.generator.gapic.model; +package com.google.api.generator.gapic.composer.common; import com.google.api.generator.engine.ast.ConcreteReference; import com.google.api.generator.engine.ast.TypeNode; +import com.google.api.generator.gapic.composer.utils.ClassNames; +import com.google.api.generator.gapic.model.Transport; import com.google.auto.value.AutoValue; @AutoValue public abstract class TransportContext { - public enum Transport { - REST, - GRPC, - GRPC_REST; - - public static Transport parse(String name) { - return valueOf(name.replace('+', '_').toUpperCase()); - } - } + + public abstract ClassNames classNames(); // For AbstractServiceStubClassComposer public abstract Transport transport(); + public abstract String transportName(); + public abstract Class callSettingsClass(); public abstract TypeNode stubCallableFactoryType(); @@ -70,8 +67,13 @@ public static TransportContext.Builder builder() { @AutoValue.Builder public abstract static class Builder { + + public abstract Builder setClassNames(ClassNames value); + public abstract Builder setTransport(Transport transport); + public abstract Builder setTransportName(String value); + public abstract Builder setCallSettingsClass(Class callSettingsClass); public abstract Builder setStubCallableFactoryType(TypeNode stubCallableFactoryType); diff --git a/src/main/java/com/google/api/generator/gapic/composer/grpc/GrpcContext.java b/src/main/java/com/google/api/generator/gapic/composer/grpc/GrpcContext.java index 494e0ffd8f..13623cfb5b 100644 --- a/src/main/java/com/google/api/generator/gapic/composer/grpc/GrpcContext.java +++ b/src/main/java/com/google/api/generator/gapic/composer/grpc/GrpcContext.java @@ -19,7 +19,9 @@ import com.google.api.gax.grpc.GrpcStubCallableFactory; import com.google.api.gax.grpc.GrpcTransportChannel; import com.google.api.gax.grpc.InstantiatingGrpcChannelProvider; -import com.google.api.generator.gapic.model.TransportContext; +import com.google.api.generator.gapic.composer.utils.ClassNames; +import com.google.api.generator.gapic.model.Transport; +import com.google.api.generator.gapic.composer.common.TransportContext; import com.google.longrunning.stub.GrpcOperationsStub; import com.google.longrunning.stub.OperationsStub; import io.grpc.MethodDescriptor; @@ -27,7 +29,9 @@ public abstract class GrpcContext extends TransportContext { private static final TransportContext INSTANCE = GrpcContext.builder() + .setClassNames(new ClassNames("Grpc")) .setTransport(Transport.GRPC) + .setTransportName("gRPC") // For grpc.GrpcServiceStubClassComposer .setCallSettingsClass(GrpcCallSettings.class) .setStubCallableFactoryType(classToType(GrpcStubCallableFactory.class)) diff --git a/src/main/java/com/google/api/generator/gapic/composer/grpc/GrpcServiceCallableFactoryClassComposer.java b/src/main/java/com/google/api/generator/gapic/composer/grpc/GrpcServiceCallableFactoryClassComposer.java index edffe989e7..5698f5a443 100644 --- a/src/main/java/com/google/api/generator/gapic/composer/grpc/GrpcServiceCallableFactoryClassComposer.java +++ b/src/main/java/com/google/api/generator/gapic/composer/grpc/GrpcServiceCallableFactoryClassComposer.java @@ -14,17 +14,12 @@ package com.google.api.generator.gapic.composer.grpc; -import com.google.api.gax.grpc.GrpcCallSettings; -import com.google.api.gax.grpc.GrpcCallableFactory; -import com.google.api.gax.grpc.GrpcStubCallableFactory; +import com.google.api.generator.engine.ast.ConcreteReference; import com.google.api.generator.engine.ast.MethodDefinition; import com.google.api.generator.engine.ast.TypeNode; import com.google.api.generator.gapic.composer.common.AbstractServiceCallableFactoryClassComposer; -import com.google.api.generator.gapic.composer.comment.StubCommentComposer; import com.google.api.generator.gapic.composer.store.TypeStore; -import com.google.api.generator.gapic.composer.utils.ClassNames; import com.google.longrunning.Operation; -import com.google.longrunning.stub.OperationsStub; import java.util.ArrayList; import java.util.Arrays; import java.util.List; @@ -34,16 +29,11 @@ public class GrpcServiceCallableFactoryClassComposer extends AbstractServiceCallableFactoryClassComposer { private static final GrpcServiceCallableFactoryClassComposer INSTANCE = new GrpcServiceCallableFactoryClassComposer(); + private static final TypeNode OPERATION_TYPE = + TypeNode.withReference(ConcreteReference.withClazz(Operation.class)); protected GrpcServiceCallableFactoryClassComposer() { - super( - createTypes(), - new StubCommentComposer("gRPC"), - new ClassNames("Grpc"), - GrpcCallSettings.class, - GrpcCallableFactory.class, - OperationsStub.class, - "grpcCallSettings"); + super(GrpcContext.instance()); } public static GrpcServiceCallableFactoryClassComposer instance() { @@ -52,7 +42,7 @@ public static GrpcServiceCallableFactoryClassComposer instance() { @Override protected List createClassImplements(TypeStore typeStore) { - return Arrays.asList(typeStore.get("GrpcStubCallableFactory")); + return Arrays.asList(getTransportContext().stubCallableFactoryType()); } protected List createClassMethods(TypeStore typeStore) { @@ -120,8 +110,7 @@ protected MethodDefinition createOperationCallableMethod(TypeStore typeStore) { /*returnCallableKindName=*/ methodVariantName, /*returnCallableTemplateNames=*/ methodTemplateNames, /*methodVariantName=*/ methodVariantName, - /*grpcCallSettingsTemplateObjects=*/ Arrays.asList( - requestTemplateName, typeStore.get("Operation")), + /*grpcCallSettingsTemplateObjects=*/ Arrays.asList(requestTemplateName, OPERATION_TYPE), /*callSettingsVariantName=*/ methodVariantName, /*callSettingsTemplateObjects=*/ methodTemplateNames.stream() .map(n -> (Object) n) @@ -187,18 +176,4 @@ private MethodDefinition createClientStreamingCallableMethod(TypeStore typeStore .map(n -> (Object) n) .collect(Collectors.toList())); } - - protected static TypeStore createTypes() { - TypeStore typeStore = createCommonTypes(); - typeStore.putAll( - Arrays.asList( - // gax-java gRPC classes. - GrpcCallSettings.class, - GrpcCallableFactory.class, - GrpcStubCallableFactory.class, - Operation.class)); - - typeStore.put("com.google.longrunning.stub", "OperationsStub"); - return typeStore; - } } diff --git a/src/main/java/com/google/api/generator/gapic/composer/grpc/ServiceSettingsClassComposer.java b/src/main/java/com/google/api/generator/gapic/composer/grpc/ServiceSettingsClassComposer.java index 6ac112f2ec..9d4c9bc294 100644 --- a/src/main/java/com/google/api/generator/gapic/composer/grpc/ServiceSettingsClassComposer.java +++ b/src/main/java/com/google/api/generator/gapic/composer/grpc/ServiceSettingsClassComposer.java @@ -20,6 +20,10 @@ public class ServiceSettingsClassComposer extends AbstractServiceSettingsClassCo private static final ServiceSettingsClassComposer INSTANCE = new ServiceSettingsClassComposer(); + protected ServiceSettingsClassComposer() { + super(GrpcContext.instance()); + } + public static ServiceSettingsClassComposer instance() { return INSTANCE; } diff --git a/src/main/java/com/google/api/generator/gapic/model/GapicContext.java b/src/main/java/com/google/api/generator/gapic/model/GapicContext.java index 0cc3186e51..8767d06a8f 100644 --- a/src/main/java/com/google/api/generator/gapic/model/GapicContext.java +++ b/src/main/java/com/google/api/generator/gapic/model/GapicContext.java @@ -75,7 +75,7 @@ static GapicMetadata defaultGapicMetadata() { public abstract Builder toBuilder(); - public abstract TransportContext transportContext(); + public abstract Transport transport(); public static Builder builder() { return new AutoValue_GapicContext.Builder() @@ -108,7 +108,7 @@ public Builder setHelperResourceNames(Set helperResourceNames) { public abstract Builder setGapicMetadataEnabled(boolean gapicMetadataEnabled); - public abstract Builder setTransportContext(TransportContext transportContext); + public abstract Builder setTransport(Transport transport); public abstract GapicContext build(); } diff --git a/src/main/java/com/google/api/generator/gapic/model/Transport.java b/src/main/java/com/google/api/generator/gapic/model/Transport.java new file mode 100644 index 0000000000..3390bbb1e1 --- /dev/null +++ b/src/main/java/com/google/api/generator/gapic/model/Transport.java @@ -0,0 +1,28 @@ +/* + * Copyright 2021 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. + */ +package com.google.api.generator.gapic.model; + +public enum Transport { + REST, + GRPC, + // Never used in the context as is, must be split into two contexts (REST and GRPC respectively) + // instead. + GRPC_REST; + + public static Transport parse(String name) { + return valueOf(name.replace('+', '_').toUpperCase()); + } +} diff --git a/src/main/java/com/google/api/generator/gapic/protoparser/Parser.java b/src/main/java/com/google/api/generator/gapic/protoparser/Parser.java index 37f4627b52..1e612936be 100644 --- a/src/main/java/com/google/api/generator/gapic/protoparser/Parser.java +++ b/src/main/java/com/google/api/generator/gapic/protoparser/Parser.java @@ -18,7 +18,6 @@ import com.google.api.ResourceDescriptor; import com.google.api.ResourceProto; import com.google.api.generator.engine.ast.TypeNode; -import com.google.api.generator.gapic.composer.grpc.GrpcContext; import com.google.api.generator.gapic.model.Field; import com.google.api.generator.gapic.model.GapicBatchingSettings; import com.google.api.generator.gapic.model.GapicContext; @@ -32,6 +31,7 @@ import com.google.api.generator.gapic.model.ResourceReference; import com.google.api.generator.gapic.model.Service; import com.google.api.generator.gapic.model.SourceCodeInfoLocation; +import com.google.api.generator.gapic.model.Transport; import com.google.api.generator.gapic.utils.ResourceNameConstants; import com.google.common.annotations.VisibleForTesting; import com.google.common.base.Preconditions; @@ -184,7 +184,7 @@ public static GapicContext parse(CodeGeneratorRequest request) { .setServiceConfig(serviceConfigOpt.isPresent() ? serviceConfigOpt.get() : null) .setGapicMetadataEnabled(willGenerateMetadata) .setServiceYamlProto(serviceYamlProtoOpt.isPresent() ? serviceYamlProtoOpt.get() : null) - .setTransportContext(GrpcContext.instance()) + .setTransport(Transport.GRPC) .build(); } diff --git a/src/test/java/com/google/api/generator/gapic/composer/common/TestProtoLoader.java b/src/test/java/com/google/api/generator/gapic/composer/common/TestProtoLoader.java index 681bcb9bef..5cd4ade9da 100644 --- a/src/test/java/com/google/api/generator/gapic/composer/common/TestProtoLoader.java +++ b/src/test/java/com/google/api/generator/gapic/composer/common/TestProtoLoader.java @@ -17,14 +17,13 @@ import static junit.framework.Assert.assertEquals; import static junit.framework.Assert.assertTrue; -import com.google.api.generator.gapic.composer.grpc.GrpcContext; import com.google.api.generator.gapic.model.GapicBatchingSettings; import com.google.api.generator.gapic.model.GapicContext; import com.google.api.generator.gapic.model.GapicServiceConfig; import com.google.api.generator.gapic.model.Message; import com.google.api.generator.gapic.model.ResourceName; import com.google.api.generator.gapic.model.Service; -import com.google.api.generator.gapic.model.TransportContext; +import com.google.api.generator.gapic.model.Transport; import com.google.api.generator.gapic.protoparser.BatchingSettingsConfigParser; import com.google.api.generator.gapic.protoparser.Parser; import com.google.api.generator.gapic.protoparser.ServiceConfigParser; @@ -53,13 +52,13 @@ public class TestProtoLoader { private static final TestProtoLoader INSTANCE = new TestProtoLoader( - GrpcContext.instance(), "src/test/java/com/google/api/generator/gapic/testdata/"); + Transport.GRPC, "src/test/java/com/google/api/generator/gapic/testdata/"); private final String testFilesDirectory; - private final TransportContext transportContext; + private final Transport transport; - protected TestProtoLoader(TransportContext transportContext, String testFilesDirectory) { + protected TestProtoLoader(Transport transport, String testFilesDirectory) { this.testFilesDirectory = testFilesDirectory; - this.transportContext = transportContext; + this.transport = transport; } public static TestProtoLoader instance() { @@ -90,7 +89,7 @@ public GapicContext parseDeprecatedService() { .setServices(services) .setServiceConfig(config) .setHelperResourceNames(outputResourceNames) - .setTransportContext(transportContext) + .setTransport(transport) .build(); } @@ -118,7 +117,7 @@ public GapicContext parseShowcaseEcho() { .setServices(services) .setServiceConfig(config) .setHelperResourceNames(outputResourceNames) - .setTransportContext(transportContext) + .setTransport(transport) .build(); } @@ -139,7 +138,7 @@ public GapicContext parseShowcaseIdentity() { .setResourceNames(resourceNames) .setServices(services) .setHelperResourceNames(outputResourceNames) - .setTransportContext(transportContext) + .setTransport(transport) .build(); } @@ -164,7 +163,7 @@ public GapicContext parseShowcaseTesting() { .setResourceNames(resourceNames) .setServices(services) .setHelperResourceNames(outputResourceNames) - .setTransportContext(transportContext) + .setTransport(transport) .build(); } @@ -207,7 +206,7 @@ public GapicContext parsePubSubPublisher() { .setServices(services) .setServiceConfig(config) .setHelperResourceNames(outputResourceNames) - .setTransportContext(transportContext) + .setTransport(transport) .build(); } @@ -262,7 +261,7 @@ public GapicContext parseLogging() { .setServices(services) .setServiceConfig(config) .setHelperResourceNames(outputResourceNames) - .setTransportContext(transportContext) + .setTransport(transport) .build(); } diff --git a/src/test/java/com/google/api/generator/gapic/composer/grpc/GrpcTestProtoLoader.java b/src/test/java/com/google/api/generator/gapic/composer/grpc/GrpcTestProtoLoader.java index f9c261ce60..ecc9206e40 100644 --- a/src/test/java/com/google/api/generator/gapic/composer/grpc/GrpcTestProtoLoader.java +++ b/src/test/java/com/google/api/generator/gapic/composer/grpc/GrpcTestProtoLoader.java @@ -15,12 +15,13 @@ package com.google.api.generator.gapic.composer.grpc; import com.google.api.generator.gapic.composer.common.TestProtoLoader; +import com.google.api.generator.gapic.model.Transport; public class GrpcTestProtoLoader extends TestProtoLoader { - private static GrpcTestProtoLoader INSTANCE = new GrpcTestProtoLoader(); + private static final GrpcTestProtoLoader INSTANCE = new GrpcTestProtoLoader(); protected GrpcTestProtoLoader() { - super(GrpcContext.instance(), "src/test/java/com/google/api/generator/gapic/testdata/"); + super(Transport.GRPC, "src/test/java/com/google/api/generator/gapic/testdata/"); } public static GrpcTestProtoLoader instance() { From beef8da3a80d1599c42b5db7e79120e43141fe92 Mon Sep 17 00:00:00 2001 From: vam-google Date: Thu, 20 May 2021 19:41:32 -0700 Subject: [PATCH 08/16] chore: DIREGAPIC #2 ServiceClientTestClassComposer refactoring --- ...bstractServiceClientTestClassComposer.java | 595 +---------------- .../grpc/ServiceClientTestClassComposer.java | 606 +++++++++++++++++- 2 files changed, 609 insertions(+), 592 deletions(-) diff --git a/src/main/java/com/google/api/generator/gapic/composer/common/AbstractServiceClientTestClassComposer.java b/src/main/java/com/google/api/generator/gapic/composer/common/AbstractServiceClientTestClassComposer.java index a1c3e9789f..17c6730112 100644 --- a/src/main/java/com/google/api/generator/gapic/composer/common/AbstractServiceClientTestClassComposer.java +++ b/src/main/java/com/google/api/generator/gapic/composer/common/AbstractServiceClientTestClassComposer.java @@ -96,15 +96,18 @@ public abstract class AbstractServiceClientTestClassComposer implements ClassCom private static final String MOCK_SERVICE_VAR_NAME_PATTERN = "mock%s"; private static final String PAGED_RESPONSE_TYPE_NAME_PATTERN = "%sPagedResponse"; - private final TypeStore fixedTypeStore; - private final ClassNames classNames; - private final AnnotationNode testAnnotation; - - protected AbstractServiceClientTestClassComposer( - TypeStore fixedTypeStore, ClassNames classNames) { - this.fixedTypeStore = fixedTypeStore; - this.classNames = classNames; - this.testAnnotation = AnnotationNode.withType(fixedTypeStore.get("Test")); + protected static final TypeStore FIXED_TYPESTORE = createStaticTypes(); + protected static final AnnotationNode TEST_ANNOTATION = + AnnotationNode.withType(FIXED_TYPESTORE.get("Test")); + + private final TransportContext transportContext; + + protected AbstractServiceClientTestClassComposer(TransportContext transportContext) { + this.transportContext = transportContext; + } + + public TransportContext getTransportContext() { + return transportContext; } @Override @@ -133,22 +136,10 @@ public GapicClass generate(GapicContext context, Service service) { return GapicClass.create(kind, classDef); } - protected TypeStore getFixedTypeStore() { - return fixedTypeStore; - } - - protected ClassNames getClassNames() { - return classNames; - } - - protected AnnotationNode getTestAnnotation() { - return testAnnotation; - } - private List createClassAnnotations() { return Arrays.asList( AnnotationNode.builder() - .setType(getFixedTypeStore().get("Generated")) + .setType(FIXED_TYPESTORE.get("Generated")) .setDescription("by gapic-generator-java") .build()); } @@ -397,7 +388,7 @@ private MethodDefinition createRpcTestMethod( VariableExpr resultOperationVarExpr = VariableExpr.withVariable( Variable.builder() - .setType(getFixedTypeStore().get("Operation")) + .setType(FIXED_TYPESTORE.get("Operation")) .setName("resultOperation") .build()); methodExprs.add( @@ -528,7 +519,7 @@ private MethodDefinition createRpcTestMethod( .build(); Expr resourcesValExpr = MethodInvocationExpr.builder() - .setStaticReferenceType(getFixedTypeStore().get("Lists")) + .setStaticReferenceType(FIXED_TYPESTORE.get("Lists")) .setMethodName("newArrayList") .setArguments(iterateAllExpr) .setReturnType(resourcesVarExpr.type()) @@ -550,7 +541,7 @@ private MethodDefinition createRpcTestMethod( // Assert the size is equivalent. methodExprs.add( MethodInvocationExpr.builder() - .setStaticReferenceType(getFixedTypeStore().get("Assert")) + .setStaticReferenceType(FIXED_TYPESTORE.get("Assert")) .setMethodName("assertEquals") .setArguments( ValueExpr.withValue( @@ -595,14 +586,14 @@ private MethodDefinition createRpcTestMethod( methodExprs.add( MethodInvocationExpr.builder() - .setStaticReferenceType(getFixedTypeStore().get("Assert")) + .setStaticReferenceType(FIXED_TYPESTORE.get("Assert")) .setMethodName("assertEquals") .setArguments(expectedPagedResponseExpr, actualPagedResponseExpr) .build()); } else if (!returnsVoid) { methodExprs.add( MethodInvocationExpr.builder() - .setStaticReferenceType(getFixedTypeStore().get("Assert")) + .setStaticReferenceType(FIXED_TYPESTORE.get("Assert")) .setMethodName("assertEquals") .setArguments(expectedResponseVarExpr, actualResponseVarExpr) .build()); @@ -632,7 +623,7 @@ private MethodDefinition createRpcTestMethod( JavaStyle.toLowerCamelCase(method.name()), variantIndex > 0 ? variantIndex + 1 : ""); return MethodDefinition.builder() - .setAnnotations(Arrays.asList(getTestAnnotation())) + .setAnnotations(Arrays.asList(TEST_ANNOTATION)) .setScope(ScopeNode.PUBLIC) .setReturnType(TypeNode.VOID) .setName(testMethodName) @@ -650,271 +641,12 @@ protected abstract List constructRpcTestCheckerLogic( Message requestMessage, List argExprs); - private MethodDefinition createStreamingRpcTestMethod( + protected abstract MethodDefinition createStreamingRpcTestMethod( Service service, Method method, Map classMemberVarExprs, Map resourceNames, - Map messageTypes) { - TypeNode methodOutputType = method.hasLro() ? method.lro().responseType() : method.outputType(); - List methodExprs = new ArrayList<>(); - VariableExpr expectedResponseVarExpr = - VariableExpr.withVariable( - Variable.builder().setType(methodOutputType).setName("expectedResponse").build()); - Expr expectedResponseValExpr = null; - if (messageTypes.containsKey(methodOutputType.reference().fullName())) { - expectedResponseValExpr = - DefaultValueComposer.createSimpleMessageBuilderExpr( - messageTypes.get(methodOutputType.reference().fullName()), - resourceNames, - messageTypes); - } else { - // Wrap this in a field so we don't have to split the helper into lots of different methods, - // or duplicate it for VariableExpr. - expectedResponseValExpr = - DefaultValueComposer.createDefaultValue( - Field.builder() - .setType(methodOutputType) - .setIsMessage(true) - .setName("expectedResponse") - .build()); - } - methodExprs.add( - AssignmentExpr.builder() - .setVariableExpr(expectedResponseVarExpr.toBuilder().setIsDecl(true).build()) - .setValueExpr(expectedResponseValExpr) - .build()); - - String mockServiceVarName = getMockServiceVarName(service); - if (method.hasLro()) { - VariableExpr resultOperationVarExpr = - VariableExpr.withVariable( - Variable.builder() - .setType(getFixedTypeStore().get("Operation")) - .setName("resultOperation") - .build()); - methodExprs.add( - AssignmentExpr.builder() - .setVariableExpr(resultOperationVarExpr.toBuilder().setIsDecl(true).build()) - .setValueExpr( - DefaultValueComposer.createSimpleOperationBuilderExpr( - String.format("%sTest", JavaStyle.toLowerCamelCase(method.name())), - expectedResponseVarExpr)) - .build()); - methodExprs.add( - MethodInvocationExpr.builder() - .setExprReferenceExpr(classMemberVarExprs.get(mockServiceVarName)) - .setMethodName("addResponse") - .setArguments(resultOperationVarExpr) - .build()); - } else { - methodExprs.add( - MethodInvocationExpr.builder() - .setExprReferenceExpr(classMemberVarExprs.get(mockServiceVarName)) - .setMethodName("addResponse") - .setArguments(expectedResponseVarExpr) - .build()); - } - - // Construct the request or method arguments. - VariableExpr requestVarExpr = - VariableExpr.withVariable( - Variable.builder().setType(method.inputType()).setName("request").build()); - Message requestMessage = messageTypes.get(method.inputType().reference().fullName()); - Preconditions.checkNotNull(requestMessage); - Expr valExpr = - DefaultValueComposer.createSimpleMessageBuilderExpr( - requestMessage, resourceNames, messageTypes); - methodExprs.add( - AssignmentExpr.builder() - .setVariableExpr(requestVarExpr.toBuilder().setIsDecl(true).build()) - .setValueExpr(valExpr) - .build()); - - List methodStatements = new ArrayList<>(); - methodStatements.addAll( - methodExprs.stream().map(e -> ExprStatement.withExpr(e)).collect(Collectors.toList())); - methodExprs.clear(); - methodStatements.add(EMPTY_LINE_STATEMENT); - - // Construct the mock stream observer. - VariableExpr responseObserverVarExpr = - VariableExpr.withVariable( - Variable.builder() - .setType( - TypeNode.withReference( - getFixedTypeStore() - .get("MockStreamObserver") - .reference() - .copyAndSetGenerics(Arrays.asList(method.outputType().reference())))) - .setName("responseObserver") - .build()); - - methodStatements.add( - ExprStatement.withExpr( - AssignmentExpr.builder() - .setVariableExpr(responseObserverVarExpr.toBuilder().setIsDecl(true).build()) - .setValueExpr( - NewObjectExpr.builder() - .setType(getFixedTypeStore().get("MockStreamObserver")) - .setIsGeneric(true) - .build()) - .build())); - methodStatements.add(EMPTY_LINE_STATEMENT); - - // Build the callable variable and assign it. - VariableExpr callableVarExpr = - VariableExpr.withVariable( - Variable.builder().setType(getCallableType(method)).setName("callable").build()); - Expr streamingCallExpr = - MethodInvocationExpr.builder() - .setExprReferenceExpr(classMemberVarExprs.get("client")) - .setMethodName(String.format("%sCallable", JavaStyle.toLowerCamelCase(method.name()))) - .setReturnType(callableVarExpr.type()) - .build(); - methodExprs.add( - AssignmentExpr.builder() - .setVariableExpr(callableVarExpr.toBuilder().setIsDecl(true).build()) - .setValueExpr(streamingCallExpr) - .build()); - - // Call the streaming-variant callable method. - if (method.stream().equals(Method.Stream.SERVER)) { - methodExprs.add( - MethodInvocationExpr.builder() - .setExprReferenceExpr(callableVarExpr) - .setMethodName("serverStreamingCall") - .setArguments(requestVarExpr, responseObserverVarExpr) - .build()); - } else { - VariableExpr requestObserverVarExpr = - VariableExpr.withVariable( - Variable.builder() - .setType( - TypeNode.withReference( - getFixedTypeStore() - .get("ApiStreamObserver") - .reference() - .copyAndSetGenerics(Arrays.asList(method.inputType().reference())))) - .setName("requestObserver") - .build()); - List callableMethodArgs = new ArrayList<>(); - if (!method.stream().equals(Method.Stream.BIDI) - && !method.stream().equals(Method.Stream.CLIENT)) { - callableMethodArgs.add(requestVarExpr); - } - callableMethodArgs.add(responseObserverVarExpr); - methodExprs.add( - AssignmentExpr.builder() - .setVariableExpr(requestObserverVarExpr.toBuilder().setIsDecl(true).build()) - .setValueExpr( - MethodInvocationExpr.builder() - .setExprReferenceExpr(callableVarExpr) - .setMethodName(getCallableMethodName(method)) - .setArguments(callableMethodArgs) - .setReturnType(requestObserverVarExpr.type()) - .build()) - .build()); - - methodStatements.addAll( - methodExprs.stream().map(e -> ExprStatement.withExpr(e)).collect(Collectors.toList())); - methodExprs.clear(); - methodStatements.add(EMPTY_LINE_STATEMENT); - - methodExprs.add( - MethodInvocationExpr.builder() - .setExprReferenceExpr(requestObserverVarExpr) - .setMethodName("onNext") - .setArguments(requestVarExpr) - .build()); - methodExprs.add( - MethodInvocationExpr.builder() - .setExprReferenceExpr(requestObserverVarExpr) - .setMethodName("onCompleted") - .build()); - } - methodStatements.addAll( - methodExprs.stream().map(e -> ExprStatement.withExpr(e)).collect(Collectors.toList())); - methodExprs.clear(); - methodStatements.add(EMPTY_LINE_STATEMENT); - - // Check the actual responses. - VariableExpr actualResponsesVarExpr = - VariableExpr.withVariable( - Variable.builder() - .setType( - TypeNode.withReference( - ConcreteReference.builder() - .setClazz(List.class) - .setGenerics(Arrays.asList(method.outputType().reference())) - .build())) - .setName("actualResponses") - .build()); - - Expr getFutureResponseExpr = - MethodInvocationExpr.builder() - .setExprReferenceExpr(responseObserverVarExpr) - .setMethodName("future") - .build(); - getFutureResponseExpr = - MethodInvocationExpr.builder() - .setExprReferenceExpr(getFutureResponseExpr) - .setMethodName("get") - .setReturnType(actualResponsesVarExpr.type()) - .build(); - methodExprs.add( - AssignmentExpr.builder() - .setVariableExpr(actualResponsesVarExpr.toBuilder().setIsDecl(true).build()) - .setValueExpr(getFutureResponseExpr) - .build()); - - // Assert the size is equivalent. - methodExprs.add( - MethodInvocationExpr.builder() - .setStaticReferenceType(getFixedTypeStore().get("Assert")) - .setMethodName("assertEquals") - .setArguments( - ValueExpr.withValue( - PrimitiveValue.builder().setType(TypeNode.INT).setValue("1").build()), - MethodInvocationExpr.builder() - .setExprReferenceExpr(actualResponsesVarExpr) - .setMethodName("size") - .setReturnType(TypeNode.INT) - .build()) - .build()); - - // Assert the responses are equivalent. - Expr zeroExpr = - ValueExpr.withValue(PrimitiveValue.builder().setType(TypeNode.INT).setValue("0").build()); - Expr actualResponseExpr = - MethodInvocationExpr.builder() - .setExprReferenceExpr(actualResponsesVarExpr) - .setMethodName("get") - .setArguments(zeroExpr) - .build(); - - methodExprs.add( - MethodInvocationExpr.builder() - .setStaticReferenceType(getFixedTypeStore().get("Assert")) - .setMethodName("assertEquals") - .setArguments(expectedResponseVarExpr, actualResponseExpr) - .build()); - - methodStatements.addAll( - methodExprs.stream().map(e -> ExprStatement.withExpr(e)).collect(Collectors.toList())); - methodExprs.clear(); - methodStatements.add(EMPTY_LINE_STATEMENT); - - String testMethodName = String.format("%sTest", JavaStyle.toLowerCamelCase(method.name())); - return MethodDefinition.builder() - .setAnnotations(Arrays.asList(getTestAnnotation())) - .setScope(ScopeNode.PUBLIC) - .setReturnType(TypeNode.VOID) - .setName(testMethodName) - .setThrowsExceptions(Arrays.asList(TypeNode.withExceptionClazz(Exception.class))) - .setBody(methodStatements) - .build(); - } + Map messageTypes); /** * Creates a test method to exercise exceptions for a given RPC, e.g. createAssetTest. @@ -937,189 +669,11 @@ protected abstract MethodDefinition createRpcExceptionTestMethod( Map resourceNames, Map messageTypes); - protected List createStreamingRpcExceptionTestStatements( + protected abstract List createStreamingRpcExceptionTestStatements( Method method, Map classMemberVarExprs, Map resourceNames, - Map messageTypes) { - // Build the request variable and assign it. - VariableExpr requestVarExpr = - VariableExpr.withVariable( - Variable.builder().setType(method.inputType()).setName("request").build()); - Message requestMessage = messageTypes.get(method.inputType().reference().fullName()); - Preconditions.checkNotNull(requestMessage); - Expr valExpr = - DefaultValueComposer.createSimpleMessageBuilderExpr( - requestMessage, resourceNames, messageTypes); - - List statements = new ArrayList<>(); - statements.add( - ExprStatement.withExpr( - AssignmentExpr.builder() - .setVariableExpr(requestVarExpr.toBuilder().setIsDecl(true).build()) - .setValueExpr(valExpr) - .build())); - statements.add(EMPTY_LINE_STATEMENT); - - // Build the responseObserver variable. - VariableExpr responseObserverVarExpr = - VariableExpr.withVariable( - Variable.builder() - .setType( - TypeNode.withReference( - getFixedTypeStore() - .get("MockStreamObserver") - .reference() - .copyAndSetGenerics(Arrays.asList(method.outputType().reference())))) - .setName("responseObserver") - .build()); - - statements.add( - ExprStatement.withExpr( - AssignmentExpr.builder() - .setVariableExpr(responseObserverVarExpr.toBuilder().setIsDecl(true).build()) - .setValueExpr( - NewObjectExpr.builder() - .setType(getFixedTypeStore().get("MockStreamObserver")) - .setIsGeneric(true) - .build()) - .build())); - statements.add(EMPTY_LINE_STATEMENT); - - // Build the callable variable and assign it. - VariableExpr callableVarExpr = - VariableExpr.withVariable( - Variable.builder().setType(getCallableType(method)).setName("callable").build()); - Expr streamingCallExpr = - MethodInvocationExpr.builder() - .setExprReferenceExpr(classMemberVarExprs.get("client")) - .setMethodName(String.format("%sCallable", JavaStyle.toLowerCamelCase(method.name()))) - .setReturnType(callableVarExpr.type()) - .build(); - - List exprs = new ArrayList<>(); - exprs.add( - AssignmentExpr.builder() - .setVariableExpr(callableVarExpr.toBuilder().setIsDecl(true).build()) - .setValueExpr(streamingCallExpr) - .build()); - - if (method.stream().equals(Method.Stream.SERVER)) { - exprs.add( - MethodInvocationExpr.builder() - .setExprReferenceExpr(callableVarExpr) - .setMethodName("serverStreamingCall") - .setArguments(requestVarExpr, responseObserverVarExpr) - .build()); - } else { - // Call the streaming-variant callable method. - VariableExpr requestObserverVarExpr = - VariableExpr.withVariable( - Variable.builder() - .setType( - TypeNode.withReference( - getFixedTypeStore() - .get("ApiStreamObserver") - .reference() - .copyAndSetGenerics(Arrays.asList(method.inputType().reference())))) - .setName("requestObserver") - .build()); - - List callableMethodArgs = new ArrayList<>(); - if (!method.stream().equals(Method.Stream.BIDI) - && !method.stream().equals(Method.Stream.CLIENT)) { - callableMethodArgs.add(requestVarExpr); - } - callableMethodArgs.add(responseObserverVarExpr); - exprs.add( - AssignmentExpr.builder() - .setVariableExpr(requestObserverVarExpr.toBuilder().setIsDecl(true).build()) - .setValueExpr( - MethodInvocationExpr.builder() - .setExprReferenceExpr(callableVarExpr) - .setMethodName(getCallableMethodName(method)) - .setArguments(callableMethodArgs) - .setReturnType(requestObserverVarExpr.type()) - .build()) - .build()); - - statements.addAll( - exprs.stream().map(e -> ExprStatement.withExpr(e)).collect(Collectors.toList())); - exprs.clear(); - statements.add(EMPTY_LINE_STATEMENT); - - exprs.add( - MethodInvocationExpr.builder() - .setExprReferenceExpr(requestObserverVarExpr) - .setMethodName("onNext") - .setArguments(requestVarExpr) - .build()); - } - statements.addAll( - exprs.stream().map(e -> ExprStatement.withExpr(e)).collect(Collectors.toList())); - exprs.clear(); - statements.add(EMPTY_LINE_STATEMENT); - - List tryBodyExprs = new ArrayList<>(); - // TODO(v2): This variable is unused in the generated test, it can be deleted. - VariableExpr actualResponsesVarExpr = - VariableExpr.withVariable( - Variable.builder() - .setType( - TypeNode.withReference( - ConcreteReference.builder() - .setClazz(List.class) - .setGenerics(Arrays.asList(method.outputType().reference())) - .build())) - .setName("actualResponses") - .build()); - - Expr getFutureResponseExpr = - MethodInvocationExpr.builder() - .setExprReferenceExpr(responseObserverVarExpr) - .setMethodName("future") - .build(); - getFutureResponseExpr = - MethodInvocationExpr.builder() - .setExprReferenceExpr(getFutureResponseExpr) - .setMethodName("get") - .setReturnType(actualResponsesVarExpr.type()) - .build(); - tryBodyExprs.add( - AssignmentExpr.builder() - .setVariableExpr(actualResponsesVarExpr.toBuilder().setIsDecl(true).build()) - .setValueExpr(getFutureResponseExpr) - .build()); - // Assert a failure if no exception was raised. - tryBodyExprs.add( - MethodInvocationExpr.builder() - .setStaticReferenceType(getFixedTypeStore().get("Assert")) - .setMethodName("fail") - .setArguments(ValueExpr.withValue(StringObjectValue.withValue("No exception thrown"))) - .build()); - - VariableExpr catchExceptionVarExpr = - VariableExpr.builder() - .setVariable( - Variable.builder() - .setType(TypeNode.withExceptionClazz(ExecutionException.class)) - .setName("e") - .build()) - .build(); - - TryCatchStatement tryCatchBlock = - TryCatchStatement.builder() - .setTryBody( - tryBodyExprs.stream() - .map(e -> ExprStatement.withExpr(e)) - .collect(Collectors.toList())) - .setCatchVariableExpr(catchExceptionVarExpr.toBuilder().setIsDecl(true).build()) - .setCatchBody(createRpcLroExceptionTestCatchBody(catchExceptionVarExpr, true)) - .build(); - - statements.add(tryCatchBlock); - return statements; - } + Map messageTypes); protected List createRpcExceptionTestStatements( Method method, @@ -1200,7 +754,7 @@ protected List createRpcExceptionTestStatements( // Assert a failure if no exception was raised. tryBodyExprs.add( MethodInvocationExpr.builder() - .setStaticReferenceType(getFixedTypeStore().get("Assert")) + .setStaticReferenceType(FIXED_TYPESTORE.get("Assert")) .setMethodName("fail") .setArguments(ValueExpr.withValue(StringObjectValue.withValue("No exception raised"))) .build()); @@ -1218,104 +772,15 @@ protected List createRpcExceptionTestStatements( return Arrays.asList(EMPTY_LINE_STATEMENT, tryCatchBlock); } - private List createRpcLroExceptionTestCatchBody( - VariableExpr exceptionExpr, boolean isStreaming) { - List catchBodyExprs = new ArrayList<>(); - - Expr testExpectedValueExpr = - VariableExpr.builder() - .setVariable(Variable.builder().setType(TypeNode.CLASS_OBJECT).setName("class").build()) - .setStaticReferenceType(getFixedTypeStore().get("InvalidArgumentException")) - .build(); - Expr getCauseExpr = - MethodInvocationExpr.builder() - .setExprReferenceExpr(exceptionExpr) - .setMethodName("getCause") - .setReturnType(TypeNode.withReference(ConcreteReference.withClazz(Throwable.class))) - .build(); - Expr testActualValueExpr = - MethodInvocationExpr.builder() - .setExprReferenceExpr(getCauseExpr) - .setMethodName("getClass") - .build(); - - if (isStreaming) { - InstanceofExpr checkInstanceExpr = - InstanceofExpr.builder() - .setExpr(getCauseExpr) - .setCheckType(getFixedTypeStore().get("InvalidArgumentException")) - .build(); - catchBodyExprs.add( - MethodInvocationExpr.builder() - .setStaticReferenceType(getFixedTypeStore().get("Assert")) - .setMethodName("assertTrue") - .setArguments(checkInstanceExpr) - .build()); - } else { - // Constructs `Assert.assertEquals(InvalidArgumentException.class, e.getCaus().getClass());`. - catchBodyExprs.add( - MethodInvocationExpr.builder() - .setStaticReferenceType(getFixedTypeStore().get("Assert")) - .setMethodName("assertEquals") - .setArguments(testExpectedValueExpr, testActualValueExpr) - .build()); - } - - // Construct the apiException variable. - VariableExpr apiExceptionVarExpr = - VariableExpr.withVariable( - Variable.builder() - .setType(getFixedTypeStore().get("InvalidArgumentException")) - .setName("apiException") - .build()); - Expr castedCauseExpr = - CastExpr.builder() - .setType(getFixedTypeStore().get("InvalidArgumentException")) - .setExpr(getCauseExpr) - .build(); - catchBodyExprs.add( - AssignmentExpr.builder() - .setVariableExpr(apiExceptionVarExpr.toBuilder().setIsDecl(true).build()) - .setValueExpr(castedCauseExpr) - .build()); - - // Construct the last assert statement. - testExpectedValueExpr = - EnumRefExpr.builder() - .setType( - TypeNode.withReference( - ConcreteReference.builder() - .setClazz(StatusCode.Code.class) - .setIsStaticImport(false) - .build())) - .setName("INVALID_ARGUMENT") - .build(); - testActualValueExpr = - MethodInvocationExpr.builder() - .setExprReferenceExpr(apiExceptionVarExpr) - .setMethodName("getStatusCode") - .build(); - testActualValueExpr = - MethodInvocationExpr.builder() - .setExprReferenceExpr(testActualValueExpr) - .setMethodName("getCode") - .build(); - catchBodyExprs.add( - MethodInvocationExpr.builder() - .setStaticReferenceType(getFixedTypeStore().get("Assert")) - .setMethodName("assertEquals") - .setArguments(testExpectedValueExpr, testActualValueExpr) - .build()); - - return catchBodyExprs.stream().map(e -> ExprStatement.withExpr(e)).collect(Collectors.toList()); - } + protected abstract List createRpcLroExceptionTestCatchBody( + VariableExpr exceptionExpr, boolean isStreaming); /* ========================================= * Type creator methods. * ========================================= */ - protected static TypeStore createCommonTypes() { + private static TypeStore createStaticTypes() { List concreteClazzes = Arrays.asList( AbstractMessage.class, @@ -1352,7 +817,7 @@ private void addDynamicTypes(GapicContext context, Service service, TypeStore ty ClassNames.getMockServiceClassName(service), ClassNames.getServiceClientClassName(service), ClassNames.getServiceSettingsClassName(service), - getClassNames().getTransportServiceStubClassName(service))); + getTransportContext().classNames().getTransportServiceStubClassName(service))); // Pagination types. typeStore.putAll( service.pakkage(), @@ -1451,7 +916,7 @@ private static TypeNode getCallSettingsTypeHelper( ConcreteReference.builder().setClazz(callSettingsClazz).setGenerics(generics).build()); } - private static TypeNode getCallableType(Method protoMethod) { + protected static TypeNode getCallableType(Method protoMethod) { Preconditions.checkState( !protoMethod.stream().equals(Method.Stream.NONE), "No callable type exists for non-streaming methods."); @@ -1490,7 +955,7 @@ private static TypeNode getPagedResponseType(Method method, Service service) { .build()); } - private static String getCallableMethodName(Method protoMethod) { + protected static String getCallableMethodName(Method protoMethod) { Preconditions.checkState( !protoMethod.stream().equals(Method.Stream.NONE), "No callable type exists for non-streaming methods."); diff --git a/src/main/java/com/google/api/generator/gapic/composer/grpc/ServiceClientTestClassComposer.java b/src/main/java/com/google/api/generator/gapic/composer/grpc/ServiceClientTestClassComposer.java index 45301abcfe..98eb1e37db 100644 --- a/src/main/java/com/google/api/generator/gapic/composer/grpc/ServiceClientTestClassComposer.java +++ b/src/main/java/com/google/api/generator/gapic/composer/grpc/ServiceClientTestClassComposer.java @@ -19,6 +19,7 @@ import com.google.api.gax.grpc.testing.MockGrpcService; import com.google.api.gax.grpc.testing.MockServiceHelper; import com.google.api.gax.grpc.testing.MockStreamObserver; +import com.google.api.gax.rpc.StatusCode; import com.google.api.generator.engine.ast.AnnotationNode; import com.google.api.generator.engine.ast.AssignmentExpr; import com.google.api.generator.engine.ast.CastExpr; @@ -26,17 +27,21 @@ import com.google.api.generator.engine.ast.EnumRefExpr; import com.google.api.generator.engine.ast.Expr; import com.google.api.generator.engine.ast.ExprStatement; +import com.google.api.generator.engine.ast.InstanceofExpr; import com.google.api.generator.engine.ast.MethodDefinition; import com.google.api.generator.engine.ast.MethodInvocationExpr; import com.google.api.generator.engine.ast.NewObjectExpr; import com.google.api.generator.engine.ast.PrimitiveValue; import com.google.api.generator.engine.ast.ScopeNode; import com.google.api.generator.engine.ast.Statement; +import com.google.api.generator.engine.ast.StringObjectValue; +import com.google.api.generator.engine.ast.TryCatchStatement; import com.google.api.generator.engine.ast.TypeNode; import com.google.api.generator.engine.ast.ValueExpr; import com.google.api.generator.engine.ast.Variable; import com.google.api.generator.engine.ast.VariableExpr; import com.google.api.generator.gapic.composer.common.AbstractServiceClientTestClassComposer; +import com.google.api.generator.gapic.composer.defaultvalue.DefaultValueComposer; import com.google.api.generator.gapic.composer.store.TypeStore; import com.google.api.generator.gapic.composer.utils.ClassNames; import com.google.api.generator.gapic.model.Field; @@ -55,6 +60,7 @@ import java.util.LinkedHashMap; import java.util.List; import java.util.Map; +import java.util.concurrent.ExecutionException; import java.util.function.BiFunction; import java.util.function.Function; import java.util.stream.Collectors; @@ -63,6 +69,8 @@ public class ServiceClientTestClassComposer extends AbstractServiceClientTestCla private static final String SERVICE_HELPER_VAR_NAME = "mockServiceHelper"; private static final String CHANNEL_PROVIDER_VAR_NAME = "channelProvider"; + protected static final TypeStore FIXED_GRPC_TYPESTORE = createStaticTypes(); + private static final TypeNode LIST_TYPE = TypeNode.withReference(ConcreteReference.withClazz(List.class)); private static final TypeNode MAP_TYPE = @@ -77,7 +85,7 @@ public class ServiceClientTestClassComposer extends AbstractServiceClientTestCla ConcreteReference.builder().setClazz(io.grpc.Status.class).setUseFullName(true).build()); protected ServiceClientTestClassComposer() { - super(createTypes(), new ClassNames("Grpc")); + super(GrpcContext.instance()); } private static final ServiceClientTestClassComposer INSTANCE = @@ -87,18 +95,17 @@ public static AbstractServiceClientTestClassComposer instance() { return INSTANCE; } - protected static TypeStore createTypes() { - TypeStore typeStore = createCommonTypes(); - typeStore.putAll( + private static TypeStore createStaticTypes() { + List concreteClazzes = Arrays.asList( GaxGrpcProperties.class, LocalChannelProvider.class, MockGrpcService.class, MockServiceHelper.class, MockStreamObserver.class, - StatusRuntimeException.class)); + StatusRuntimeException.class); - return typeStore; + return new TypeStore(concreteClazzes); } @Override @@ -115,9 +122,9 @@ protected Map createClassMemberVarExprs( getMockServiceVarName(mixinService), typeStore.get(ClassNames.getMockServiceClassName(mixinService))); } - fields.put(SERVICE_HELPER_VAR_NAME, getFixedTypeStore().get("MockServiceHelper")); + fields.put(SERVICE_HELPER_VAR_NAME, FIXED_GRPC_TYPESTORE.get("MockServiceHelper")); fields.put(CLIENT_VAR_NAME, typeStore.get(ClassNames.getServiceClientClassName(service))); - fields.put(CHANNEL_PROVIDER_VAR_NAME, getFixedTypeStore().get("LocalChannelProvider")); + fields.put(CHANNEL_PROVIDER_VAR_NAME, FIXED_GRPC_TYPESTORE.get("LocalChannelProvider")); return fields.entrySet().stream() .collect(Collectors.toMap(e -> e.getKey(), e -> varExprFn.apply(e.getKey(), e.getValue()))); } @@ -150,7 +157,7 @@ protected MethodDefinition createStartStaticServerMethod( MethodInvocationExpr firstArg = MethodInvocationExpr.builder() - .setStaticReferenceType(getFixedTypeStore().get("UUID")) + .setStaticReferenceType(FIXED_TYPESTORE.get("UUID")) .setMethodName("randomUUID") .build(); firstArg = @@ -161,8 +168,8 @@ protected MethodDefinition createStartStaticServerMethod( MethodInvocationExpr secondArg = MethodInvocationExpr.builder() - .setStaticReferenceType(getFixedTypeStore().get("Arrays")) - .setGenerics(Arrays.asList(getFixedTypeStore().get("MockGrpcService").reference())) + .setStaticReferenceType(FIXED_TYPESTORE.get("Arrays")) + .setGenerics(Arrays.asList(FIXED_GRPC_TYPESTORE.get("MockGrpcService").reference())) .setMethodName("asList") .setArguments(mockServiceVarExprs) .build(); @@ -187,7 +194,7 @@ protected MethodDefinition createStartStaticServerMethod( return MethodDefinition.builder() .setAnnotations( - Arrays.asList(AnnotationNode.withType(getFixedTypeStore().get("BeforeClass")))) + Arrays.asList(AnnotationNode.withType(FIXED_TYPESTORE.get("BeforeClass")))) .setScope(ScopeNode.PUBLIC) .setIsStatic(true) .setReturnType(TypeNode.VOID) @@ -202,7 +209,7 @@ protected MethodDefinition createStopServerMethod( Service service, Map classMemberVarExprs) { return MethodDefinition.builder() .setAnnotations( - Arrays.asList(AnnotationNode.withType(getFixedTypeStore().get("AfterClass")))) + Arrays.asList(AnnotationNode.withType(FIXED_TYPESTORE.get("AfterClass")))) .setScope(ScopeNode.PUBLIC) .setIsStatic(true) .setReturnType(TypeNode.VOID) @@ -269,7 +276,7 @@ protected MethodDefinition createSetUpMethod( .apply( "setCredentialsProvider", MethodInvocationExpr.builder() - .setStaticReferenceType(getFixedTypeStore().get("NoCredentialsProvider")) + .setStaticReferenceType(FIXED_TYPESTORE.get("NoCredentialsProvider")) .setMethodName("create") .build()); settingsBuilderExpr = @@ -299,11 +306,11 @@ protected MethodDefinition createSetUpMethod( .build(); return MethodDefinition.builder() - .setAnnotations(Arrays.asList(AnnotationNode.withType(getFixedTypeStore().get("Before")))) + .setAnnotations(Arrays.asList(AnnotationNode.withType(FIXED_TYPESTORE.get("Before")))) .setScope(ScopeNode.PUBLIC) .setReturnType(TypeNode.VOID) .setName("setUp") - .setThrowsExceptions(Arrays.asList(getFixedTypeStore().get("IOException"))) + .setThrowsExceptions(Arrays.asList(FIXED_TYPESTORE.get("IOException"))) .setBody( Arrays.asList( resetServiceHelperExpr, @@ -320,7 +327,7 @@ protected MethodDefinition createSetUpMethod( protected MethodDefinition createTearDownMethod( Service service, Map classMemberVarExprs) { return MethodDefinition.builder() - .setAnnotations(Arrays.asList(AnnotationNode.withType(getFixedTypeStore().get("After")))) + .setAnnotations(Arrays.asList(AnnotationNode.withType(FIXED_TYPESTORE.get("After")))) .setScope(ScopeNode.PUBLIC) .setReturnType(TypeNode.VOID) .setName("tearDown") @@ -374,7 +381,7 @@ protected List constructRpcTestCheckerLogic( methodExprs.add( MethodInvocationExpr.builder() - .setStaticReferenceType(getFixedTypeStore().get("Assert")) + .setStaticReferenceType(FIXED_TYPESTORE.get("Assert")) .setMethodName("assertEquals") .setArguments( ValueExpr.withValue( @@ -395,7 +402,7 @@ protected List constructRpcTestCheckerLogic( .setArguments( ValueExpr.withValue( PrimitiveValue.builder().setType(TypeNode.INT).setValue("0").build())) - .setReturnType(getFixedTypeStore().get("AbstractMessage")) + .setReturnType(FIXED_TYPESTORE.get("AbstractMessage")) .build(); getFirstRequestExpr = CastExpr.builder().setType(method.inputType()).setExpr(getFirstRequestExpr).build(); @@ -444,7 +451,7 @@ protected List constructRpcTestCheckerLogic( } methodExprs.add( MethodInvocationExpr.builder() - .setStaticReferenceType(getFixedTypeStore().get("Assert")) + .setStaticReferenceType(FIXED_TYPESTORE.get("Assert")) .setMethodName("assertEquals") .setArguments(assertEqualsArguments) .build()); @@ -476,7 +483,7 @@ protected List constructRpcTestCheckerLogic( } methodExprs.add( MethodInvocationExpr.builder() - .setStaticReferenceType(getFixedTypeStore().get("Assert")) + .setStaticReferenceType(FIXED_TYPESTORE.get("Assert")) .setMethodName("assertEquals") .setArguments(expectedFieldExpr, actualFieldExpr) .build()); @@ -486,12 +493,12 @@ protected List constructRpcTestCheckerLogic( // Assert header equality. Expr headerKeyExpr = MethodInvocationExpr.builder() - .setStaticReferenceType(getFixedTypeStore().get("ApiClientHeaderProvider")) + .setStaticReferenceType(FIXED_TYPESTORE.get("ApiClientHeaderProvider")) .setMethodName("getDefaultApiClientHeaderKey") .build(); Expr headerPatternExpr = MethodInvocationExpr.builder() - .setStaticReferenceType(getFixedTypeStore().get("GaxGrpcProperties")) + .setStaticReferenceType(FIXED_GRPC_TYPESTORE.get("GaxGrpcProperties")) .setMethodName("getDefaultApiClientHeaderPattern") .build(); Expr headerSentExpr = @@ -502,7 +509,7 @@ protected List constructRpcTestCheckerLogic( .build(); methodExprs.add( MethodInvocationExpr.builder() - .setStaticReferenceType(getFixedTypeStore().get("Assert")) + .setStaticReferenceType(FIXED_TYPESTORE.get("Assert")) .setMethodName("assertTrue") .setArguments(headerSentExpr) .build()); @@ -513,6 +520,273 @@ protected List constructRpcTestCheckerLogic( return methodStatements; } + @Override + protected MethodDefinition createStreamingRpcTestMethod( + Service service, + Method method, + Map classMemberVarExprs, + Map resourceNames, + Map messageTypes) { + TypeNode methodOutputType = method.hasLro() ? method.lro().responseType() : method.outputType(); + List methodExprs = new ArrayList<>(); + VariableExpr expectedResponseVarExpr = + VariableExpr.withVariable( + Variable.builder().setType(methodOutputType).setName("expectedResponse").build()); + Expr expectedResponseValExpr = null; + if (messageTypes.containsKey(methodOutputType.reference().fullName())) { + expectedResponseValExpr = + DefaultValueComposer.createSimpleMessageBuilderExpr( + messageTypes.get(methodOutputType.reference().fullName()), + resourceNames, + messageTypes); + } else { + // Wrap this in a field so we don't have to split the helper into lots of different methods, + // or duplicate it for VariableExpr. + expectedResponseValExpr = + DefaultValueComposer.createDefaultValue( + Field.builder() + .setType(methodOutputType) + .setIsMessage(true) + .setName("expectedResponse") + .build()); + } + methodExprs.add( + AssignmentExpr.builder() + .setVariableExpr(expectedResponseVarExpr.toBuilder().setIsDecl(true).build()) + .setValueExpr(expectedResponseValExpr) + .build()); + + String mockServiceVarName = getMockServiceVarName(service); + if (method.hasLro()) { + VariableExpr resultOperationVarExpr = + VariableExpr.withVariable( + Variable.builder() + .setType(FIXED_GRPC_TYPESTORE.get("Operation")) + .setName("resultOperation") + .build()); + methodExprs.add( + AssignmentExpr.builder() + .setVariableExpr(resultOperationVarExpr.toBuilder().setIsDecl(true).build()) + .setValueExpr( + DefaultValueComposer.createSimpleOperationBuilderExpr( + String.format("%sTest", JavaStyle.toLowerCamelCase(method.name())), + expectedResponseVarExpr)) + .build()); + methodExprs.add( + MethodInvocationExpr.builder() + .setExprReferenceExpr(classMemberVarExprs.get(mockServiceVarName)) + .setMethodName("addResponse") + .setArguments(resultOperationVarExpr) + .build()); + } else { + methodExprs.add( + MethodInvocationExpr.builder() + .setExprReferenceExpr(classMemberVarExprs.get(mockServiceVarName)) + .setMethodName("addResponse") + .setArguments(expectedResponseVarExpr) + .build()); + } + + // Construct the request or method arguments. + VariableExpr requestVarExpr = + VariableExpr.withVariable( + Variable.builder().setType(method.inputType()).setName("request").build()); + Message requestMessage = messageTypes.get(method.inputType().reference().fullName()); + Preconditions.checkNotNull(requestMessage); + Expr valExpr = + DefaultValueComposer.createSimpleMessageBuilderExpr( + requestMessage, resourceNames, messageTypes); + methodExprs.add( + AssignmentExpr.builder() + .setVariableExpr(requestVarExpr.toBuilder().setIsDecl(true).build()) + .setValueExpr(valExpr) + .build()); + + List methodStatements = new ArrayList<>(); + methodStatements.addAll( + methodExprs.stream().map(e -> ExprStatement.withExpr(e)).collect(Collectors.toList())); + methodExprs.clear(); + methodStatements.add(EMPTY_LINE_STATEMENT); + + // Construct the mock stream observer. + VariableExpr responseObserverVarExpr = + VariableExpr.withVariable( + Variable.builder() + .setType( + TypeNode.withReference( + FIXED_GRPC_TYPESTORE + .get("MockStreamObserver") + .reference() + .copyAndSetGenerics(Arrays.asList(method.outputType().reference())))) + .setName("responseObserver") + .build()); + + methodStatements.add( + ExprStatement.withExpr( + AssignmentExpr.builder() + .setVariableExpr(responseObserverVarExpr.toBuilder().setIsDecl(true).build()) + .setValueExpr( + NewObjectExpr.builder() + .setType(FIXED_GRPC_TYPESTORE.get("MockStreamObserver")) + .setIsGeneric(true) + .build()) + .build())); + methodStatements.add(EMPTY_LINE_STATEMENT); + + // Build the callable variable and assign it. + VariableExpr callableVarExpr = + VariableExpr.withVariable( + Variable.builder().setType(getCallableType(method)).setName("callable").build()); + Expr streamingCallExpr = + MethodInvocationExpr.builder() + .setExprReferenceExpr(classMemberVarExprs.get("client")) + .setMethodName(String.format("%sCallable", JavaStyle.toLowerCamelCase(method.name()))) + .setReturnType(callableVarExpr.type()) + .build(); + methodExprs.add( + AssignmentExpr.builder() + .setVariableExpr(callableVarExpr.toBuilder().setIsDecl(true).build()) + .setValueExpr(streamingCallExpr) + .build()); + + // Call the streaming-variant callable method. + if (method.stream().equals(Method.Stream.SERVER)) { + methodExprs.add( + MethodInvocationExpr.builder() + .setExprReferenceExpr(callableVarExpr) + .setMethodName("serverStreamingCall") + .setArguments(requestVarExpr, responseObserverVarExpr) + .build()); + } else { + VariableExpr requestObserverVarExpr = + VariableExpr.withVariable( + Variable.builder() + .setType( + TypeNode.withReference( + FIXED_TYPESTORE + .get("ApiStreamObserver") + .reference() + .copyAndSetGenerics(Arrays.asList(method.inputType().reference())))) + .setName("requestObserver") + .build()); + List callableMethodArgs = new ArrayList<>(); + if (!method.stream().equals(Method.Stream.BIDI) + && !method.stream().equals(Method.Stream.CLIENT)) { + callableMethodArgs.add(requestVarExpr); + } + callableMethodArgs.add(responseObserverVarExpr); + methodExprs.add( + AssignmentExpr.builder() + .setVariableExpr(requestObserverVarExpr.toBuilder().setIsDecl(true).build()) + .setValueExpr( + MethodInvocationExpr.builder() + .setExprReferenceExpr(callableVarExpr) + .setMethodName(getCallableMethodName(method)) + .setArguments(callableMethodArgs) + .setReturnType(requestObserverVarExpr.type()) + .build()) + .build()); + + methodStatements.addAll( + methodExprs.stream().map(e -> ExprStatement.withExpr(e)).collect(Collectors.toList())); + methodExprs.clear(); + methodStatements.add(EMPTY_LINE_STATEMENT); + + methodExprs.add( + MethodInvocationExpr.builder() + .setExprReferenceExpr(requestObserverVarExpr) + .setMethodName("onNext") + .setArguments(requestVarExpr) + .build()); + methodExprs.add( + MethodInvocationExpr.builder() + .setExprReferenceExpr(requestObserverVarExpr) + .setMethodName("onCompleted") + .build()); + } + methodStatements.addAll( + methodExprs.stream().map(e -> ExprStatement.withExpr(e)).collect(Collectors.toList())); + methodExprs.clear(); + methodStatements.add(EMPTY_LINE_STATEMENT); + + // Check the actual responses. + VariableExpr actualResponsesVarExpr = + VariableExpr.withVariable( + Variable.builder() + .setType( + TypeNode.withReference( + ConcreteReference.builder() + .setClazz(List.class) + .setGenerics(Arrays.asList(method.outputType().reference())) + .build())) + .setName("actualResponses") + .build()); + + Expr getFutureResponseExpr = + MethodInvocationExpr.builder() + .setExprReferenceExpr(responseObserverVarExpr) + .setMethodName("future") + .build(); + getFutureResponseExpr = + MethodInvocationExpr.builder() + .setExprReferenceExpr(getFutureResponseExpr) + .setMethodName("get") + .setReturnType(actualResponsesVarExpr.type()) + .build(); + methodExprs.add( + AssignmentExpr.builder() + .setVariableExpr(actualResponsesVarExpr.toBuilder().setIsDecl(true).build()) + .setValueExpr(getFutureResponseExpr) + .build()); + + // Assert the size is equivalent. + methodExprs.add( + MethodInvocationExpr.builder() + .setStaticReferenceType(FIXED_TYPESTORE.get("Assert")) + .setMethodName("assertEquals") + .setArguments( + ValueExpr.withValue( + PrimitiveValue.builder().setType(TypeNode.INT).setValue("1").build()), + MethodInvocationExpr.builder() + .setExprReferenceExpr(actualResponsesVarExpr) + .setMethodName("size") + .setReturnType(TypeNode.INT) + .build()) + .build()); + + // Assert the responses are equivalent. + Expr zeroExpr = + ValueExpr.withValue(PrimitiveValue.builder().setType(TypeNode.INT).setValue("0").build()); + Expr actualResponseExpr = + MethodInvocationExpr.builder() + .setExprReferenceExpr(actualResponsesVarExpr) + .setMethodName("get") + .setArguments(zeroExpr) + .build(); + + methodExprs.add( + MethodInvocationExpr.builder() + .setStaticReferenceType(FIXED_TYPESTORE.get("Assert")) + .setMethodName("assertEquals") + .setArguments(expectedResponseVarExpr, actualResponseExpr) + .build()); + + methodStatements.addAll( + methodExprs.stream().map(e -> ExprStatement.withExpr(e)).collect(Collectors.toList())); + methodExprs.clear(); + methodStatements.add(EMPTY_LINE_STATEMENT); + + String testMethodName = String.format("%sTest", JavaStyle.toLowerCamelCase(method.name())); + return MethodDefinition.builder() + .setAnnotations(Arrays.asList(TEST_ANNOTATION)) + .setScope(ScopeNode.PUBLIC) + .setReturnType(TypeNode.VOID) + .setName(testMethodName) + .setThrowsExceptions(Arrays.asList(TypeNode.withExceptionClazz(Exception.class))) + .setBody(methodStatements) + .build(); + } + @Override protected MethodDefinition createRpcExceptionTestMethod( Method method, @@ -525,7 +799,7 @@ protected MethodDefinition createRpcExceptionTestMethod( VariableExpr exceptionVarExpr = VariableExpr.withVariable( Variable.builder() - .setType(getFixedTypeStore().get("StatusRuntimeException")) + .setType(FIXED_GRPC_TYPESTORE.get("StatusRuntimeException")) .setName("exception") .build()); @@ -535,7 +809,7 @@ protected MethodDefinition createRpcExceptionTestMethod( .setVariableExpr(exceptionVarExpr.toBuilder().setIsDecl(true).build()) .setValueExpr( NewObjectExpr.builder() - .setType(getFixedTypeStore().get("StatusRuntimeException")) + .setType(FIXED_GRPC_TYPESTORE.get("StatusRuntimeException")) .setArguments( EnumRefExpr.builder() .setType(GRPC_STATUS_TYPE) @@ -571,7 +845,7 @@ protected MethodDefinition createRpcExceptionTestMethod( } return MethodDefinition.builder() - .setAnnotations(Arrays.asList(getTestAnnotation())) + .setAnnotations(Arrays.asList(TEST_ANNOTATION)) .setScope(ScopeNode.PUBLIC) .setReturnType(TypeNode.VOID) .setName(exceptionTestMethodName) @@ -579,4 +853,282 @@ protected MethodDefinition createRpcExceptionTestMethod( .setBody(methodBody) .build(); } + + @Override + protected List createStreamingRpcExceptionTestStatements( + Method method, + Map classMemberVarExprs, + Map resourceNames, + Map messageTypes) { + // Build the request variable and assign it. + VariableExpr requestVarExpr = + VariableExpr.withVariable( + Variable.builder().setType(method.inputType()).setName("request").build()); + Message requestMessage = messageTypes.get(method.inputType().reference().fullName()); + Preconditions.checkNotNull(requestMessage); + Expr valExpr = + DefaultValueComposer.createSimpleMessageBuilderExpr( + requestMessage, resourceNames, messageTypes); + + List statements = new ArrayList<>(); + statements.add( + ExprStatement.withExpr( + AssignmentExpr.builder() + .setVariableExpr(requestVarExpr.toBuilder().setIsDecl(true).build()) + .setValueExpr(valExpr) + .build())); + statements.add(EMPTY_LINE_STATEMENT); + + // Build the responseObserver variable. + VariableExpr responseObserverVarExpr = + VariableExpr.withVariable( + Variable.builder() + .setType( + TypeNode.withReference( + FIXED_GRPC_TYPESTORE + .get("MockStreamObserver") + .reference() + .copyAndSetGenerics(Arrays.asList(method.outputType().reference())))) + .setName("responseObserver") + .build()); + + statements.add( + ExprStatement.withExpr( + AssignmentExpr.builder() + .setVariableExpr(responseObserverVarExpr.toBuilder().setIsDecl(true).build()) + .setValueExpr( + NewObjectExpr.builder() + .setType(FIXED_GRPC_TYPESTORE.get("MockStreamObserver")) + .setIsGeneric(true) + .build()) + .build())); + statements.add(EMPTY_LINE_STATEMENT); + + // Build the callable variable and assign it. + VariableExpr callableVarExpr = + VariableExpr.withVariable( + Variable.builder().setType(getCallableType(method)).setName("callable").build()); + Expr streamingCallExpr = + MethodInvocationExpr.builder() + .setExprReferenceExpr(classMemberVarExprs.get("client")) + .setMethodName(String.format("%sCallable", JavaStyle.toLowerCamelCase(method.name()))) + .setReturnType(callableVarExpr.type()) + .build(); + + List exprs = new ArrayList<>(); + exprs.add( + AssignmentExpr.builder() + .setVariableExpr(callableVarExpr.toBuilder().setIsDecl(true).build()) + .setValueExpr(streamingCallExpr) + .build()); + + if (method.stream().equals(Method.Stream.SERVER)) { + exprs.add( + MethodInvocationExpr.builder() + .setExprReferenceExpr(callableVarExpr) + .setMethodName("serverStreamingCall") + .setArguments(requestVarExpr, responseObserverVarExpr) + .build()); + } else { + // Call the streaming-variant callable method. + VariableExpr requestObserverVarExpr = + VariableExpr.withVariable( + Variable.builder() + .setType( + TypeNode.withReference( + FIXED_TYPESTORE + .get("ApiStreamObserver") + .reference() + .copyAndSetGenerics(Arrays.asList(method.inputType().reference())))) + .setName("requestObserver") + .build()); + + List callableMethodArgs = new ArrayList<>(); + if (!method.stream().equals(Method.Stream.BIDI) + && !method.stream().equals(Method.Stream.CLIENT)) { + callableMethodArgs.add(requestVarExpr); + } + callableMethodArgs.add(responseObserverVarExpr); + exprs.add( + AssignmentExpr.builder() + .setVariableExpr(requestObserverVarExpr.toBuilder().setIsDecl(true).build()) + .setValueExpr( + MethodInvocationExpr.builder() + .setExprReferenceExpr(callableVarExpr) + .setMethodName(getCallableMethodName(method)) + .setArguments(callableMethodArgs) + .setReturnType(requestObserverVarExpr.type()) + .build()) + .build()); + + statements.addAll( + exprs.stream().map(e -> ExprStatement.withExpr(e)).collect(Collectors.toList())); + exprs.clear(); + statements.add(EMPTY_LINE_STATEMENT); + + exprs.add( + MethodInvocationExpr.builder() + .setExprReferenceExpr(requestObserverVarExpr) + .setMethodName("onNext") + .setArguments(requestVarExpr) + .build()); + } + statements.addAll( + exprs.stream().map(e -> ExprStatement.withExpr(e)).collect(Collectors.toList())); + exprs.clear(); + statements.add(EMPTY_LINE_STATEMENT); + + List tryBodyExprs = new ArrayList<>(); + // TODO(v2): This variable is unused in the generated test, it can be deleted. + VariableExpr actualResponsesVarExpr = + VariableExpr.withVariable( + Variable.builder() + .setType( + TypeNode.withReference( + ConcreteReference.builder() + .setClazz(List.class) + .setGenerics(Arrays.asList(method.outputType().reference())) + .build())) + .setName("actualResponses") + .build()); + + Expr getFutureResponseExpr = + MethodInvocationExpr.builder() + .setExprReferenceExpr(responseObserverVarExpr) + .setMethodName("future") + .build(); + getFutureResponseExpr = + MethodInvocationExpr.builder() + .setExprReferenceExpr(getFutureResponseExpr) + .setMethodName("get") + .setReturnType(actualResponsesVarExpr.type()) + .build(); + tryBodyExprs.add( + AssignmentExpr.builder() + .setVariableExpr(actualResponsesVarExpr.toBuilder().setIsDecl(true).build()) + .setValueExpr(getFutureResponseExpr) + .build()); + // Assert a failure if no exception was raised. + tryBodyExprs.add( + MethodInvocationExpr.builder() + .setStaticReferenceType(FIXED_TYPESTORE.get("Assert")) + .setMethodName("fail") + .setArguments(ValueExpr.withValue(StringObjectValue.withValue("No exception thrown"))) + .build()); + + VariableExpr catchExceptionVarExpr = + VariableExpr.builder() + .setVariable( + Variable.builder() + .setType(TypeNode.withExceptionClazz(ExecutionException.class)) + .setName("e") + .build()) + .build(); + + TryCatchStatement tryCatchBlock = + TryCatchStatement.builder() + .setTryBody( + tryBodyExprs.stream() + .map(e -> ExprStatement.withExpr(e)) + .collect(Collectors.toList())) + .setCatchVariableExpr(catchExceptionVarExpr.toBuilder().setIsDecl(true).build()) + .setCatchBody(createRpcLroExceptionTestCatchBody(catchExceptionVarExpr, true)) + .build(); + + statements.add(tryCatchBlock); + return statements; + } + + @Override + protected List createRpcLroExceptionTestCatchBody( + VariableExpr exceptionExpr, boolean isStreaming) { + List catchBodyExprs = new ArrayList<>(); + + Expr testExpectedValueExpr = + VariableExpr.builder() + .setVariable(Variable.builder().setType(TypeNode.CLASS_OBJECT).setName("class").build()) + .setStaticReferenceType(FIXED_TYPESTORE.get("InvalidArgumentException")) + .build(); + Expr getCauseExpr = + MethodInvocationExpr.builder() + .setExprReferenceExpr(exceptionExpr) + .setMethodName("getCause") + .setReturnType(TypeNode.withReference(ConcreteReference.withClazz(Throwable.class))) + .build(); + Expr testActualValueExpr = + MethodInvocationExpr.builder() + .setExprReferenceExpr(getCauseExpr) + .setMethodName("getClass") + .build(); + + if (isStreaming) { + InstanceofExpr checkInstanceExpr = + InstanceofExpr.builder() + .setExpr(getCauseExpr) + .setCheckType(FIXED_TYPESTORE.get("InvalidArgumentException")) + .build(); + catchBodyExprs.add( + MethodInvocationExpr.builder() + .setStaticReferenceType(FIXED_TYPESTORE.get("Assert")) + .setMethodName("assertTrue") + .setArguments(checkInstanceExpr) + .build()); + } else { + // Constructs `Assert.assertEquals(InvalidArgumentException.class, e.getCaus().getClass());`. + catchBodyExprs.add( + MethodInvocationExpr.builder() + .setStaticReferenceType(FIXED_TYPESTORE.get("Assert")) + .setMethodName("assertEquals") + .setArguments(testExpectedValueExpr, testActualValueExpr) + .build()); + } + + // Construct the apiException variable. + VariableExpr apiExceptionVarExpr = + VariableExpr.withVariable( + Variable.builder() + .setType(FIXED_TYPESTORE.get("InvalidArgumentException")) + .setName("apiException") + .build()); + Expr castedCauseExpr = + CastExpr.builder() + .setType(FIXED_TYPESTORE.get("InvalidArgumentException")) + .setExpr(getCauseExpr) + .build(); + catchBodyExprs.add( + AssignmentExpr.builder() + .setVariableExpr(apiExceptionVarExpr.toBuilder().setIsDecl(true).build()) + .setValueExpr(castedCauseExpr) + .build()); + + // Construct the last assert statement. + testExpectedValueExpr = + EnumRefExpr.builder() + .setType( + TypeNode.withReference( + ConcreteReference.builder() + .setClazz(StatusCode.Code.class) + .setIsStaticImport(false) + .build())) + .setName("INVALID_ARGUMENT") + .build(); + testActualValueExpr = + MethodInvocationExpr.builder() + .setExprReferenceExpr(apiExceptionVarExpr) + .setMethodName("getStatusCode") + .build(); + testActualValueExpr = + MethodInvocationExpr.builder() + .setExprReferenceExpr(testActualValueExpr) + .setMethodName("getCode") + .build(); + catchBodyExprs.add( + MethodInvocationExpr.builder() + .setStaticReferenceType(FIXED_TYPESTORE.get("Assert")) + .setMethodName("assertEquals") + .setArguments(testExpectedValueExpr, testActualValueExpr) + .build()); + + return catchBodyExprs.stream().map(e -> ExprStatement.withExpr(e)).collect(Collectors.toList()); + } } From 324526522553262d68afca6267df7c797cf694cb Mon Sep 17 00:00:00 2001 From: vam-google Date: Thu, 20 May 2021 20:24:58 -0700 Subject: [PATCH 09/16] chore: DIREGAPIC #2 ServiceStubClassComposer refactoring --- .../AbstractServiceStubClassComposer.java | 178 ++++++------------ .../composer/common/TransportContext.java | 2 + .../grpc/GrpcServiceStubClassComposer.java | 60 ++++-- 3 files changed, 99 insertions(+), 141 deletions(-) diff --git a/src/main/java/com/google/api/generator/gapic/composer/common/AbstractServiceStubClassComposer.java b/src/main/java/com/google/api/generator/gapic/composer/common/AbstractServiceStubClassComposer.java index 4146ae6343..4b6e8555b1 100644 --- a/src/main/java/com/google/api/generator/gapic/composer/common/AbstractServiceStubClassComposer.java +++ b/src/main/java/com/google/api/generator/gapic/composer/common/AbstractServiceStubClassComposer.java @@ -30,7 +30,6 @@ import com.google.api.generator.engine.ast.CommentStatement; import com.google.api.generator.engine.ast.ConcreteReference; import com.google.api.generator.engine.ast.EmptyLineStatement; -import com.google.api.generator.engine.ast.EnumRefExpr; import com.google.api.generator.engine.ast.Expr; import com.google.api.generator.engine.ast.ExprStatement; import com.google.api.generator.engine.ast.JavaDocComment; @@ -47,7 +46,6 @@ import com.google.api.generator.engine.ast.VariableExpr; import com.google.api.generator.gapic.composer.comment.StubCommentComposer; import com.google.api.generator.gapic.composer.store.TypeStore; -import com.google.api.generator.gapic.composer.utils.ClassNames; import com.google.api.generator.gapic.composer.utils.PackageChecker; import com.google.api.generator.gapic.model.GapicClass; import com.google.api.generator.gapic.model.GapicClass.Kind; @@ -58,8 +56,6 @@ import com.google.common.base.Preconditions; import com.google.common.collect.ImmutableMap; import com.google.longrunning.Operation; -import io.grpc.MethodDescriptor; -import io.grpc.protobuf.ProtoUtils; import java.io.IOException; import java.util.ArrayList; import java.util.Arrays; @@ -88,32 +84,19 @@ public abstract class AbstractServiceStubClassComposer implements ClassComposer private static final String OPERATIONS_STUB_MEMBER_NAME = "operationsStub"; private static final String PAGED_CALLABLE_NAME = "PagedCallable"; - private final TypeStore fixedTypeStore; - private final StubCommentComposer commentComposer; - private final ClassNames classNames; - private final Class callSettingsClass; - private final Class stubCallableFactoryClass; - private final Class methodDescriptorClass; - private final Class operationsStubClass; - - protected AbstractServiceStubClassComposer( - TypeStore fixedTypeStore, - StubCommentComposer commentComposer, - ClassNames classNames, - Class callSettingsClass, - Class stubCallableFactoryClass, - Class methodDescriptorClass, - Class operationsStubClass) { - this.fixedTypeStore = fixedTypeStore; - this.commentComposer = commentComposer; - this.classNames = classNames; - this.callSettingsClass = callSettingsClass; - this.stubCallableFactoryClass = stubCallableFactoryClass; - this.methodDescriptorClass = methodDescriptorClass; - this.operationsStubClass = operationsStubClass; + protected static final TypeStore FIXED_TYPESTORE = createStaticTypes(); + + private final TransportContext transportContext; + + protected AbstractServiceStubClassComposer(TransportContext transportContext) { + this.transportContext = transportContext; + } + + public TransportContext getTransportContext() { + return transportContext; } - protected static TypeStore createCommonStaticTypes() { + private static TypeStore createStaticTypes() { List concreteClazzes = Arrays.asList( BackgroundResource.class, @@ -126,10 +109,8 @@ protected static TypeStore createCommonStaticTypes() { ImmutableMap.class, InterruptedException.class, IOException.class, - MethodDescriptor.class, Operation.class, OperationCallable.class, - ProtoUtils.class, RequestParamsExtractor.class, ServerStreamingCallable.class, TimeUnit.class, @@ -141,11 +122,12 @@ protected static TypeStore createCommonStaticTypes() { public GapicClass generate(GapicContext context, Service service) { String pakkage = service.pakkage() + ".stub"; TypeStore typeStore = createDynamicTypes(service, pakkage); - String className = getClassNames().getTransportServiceStubClassName(service); + String className = getTransportContext().classNames().getTransportServiceStubClassName(service); GapicClass.Kind kind = Kind.STUB; Map protoMethodNameToDescriptorVarExprs = - createProtoMethodNameToDescriptorClassMembers(service, getMethodDescriptorClass()); + createProtoMethodNameToDescriptorClassMembers( + service, getTransportContext().methodDescriptorClass()); Map callableClassMemberVarExprs = createCallableClassMembers(service, typeStore); @@ -156,15 +138,15 @@ public GapicClass generate(GapicContext context, Service service) { VariableExpr.withVariable( Variable.builder() .setName(BACKGROUND_RESOURCES_MEMBER_NAME) - .setType(getFixedTypeStore().get("BackgroundResource")) + .setType(FIXED_TYPESTORE.get("BackgroundResource")) .build())); - if (getOperationsStubClass() != null) { + if (getTransportContext().transportOperationsStubType() != null) { classMemberVarExprs.put( OPERATIONS_STUB_MEMBER_NAME, VariableExpr.withVariable( Variable.builder() .setName(OPERATIONS_STUB_MEMBER_NAME) - .setType(getFixedTypeStore().get(getOperationsStubClass().getSimpleName())) + .setType(getTransportContext().transportOperationsStubType()) .build())); } classMemberVarExprs.put( @@ -172,7 +154,7 @@ public GapicClass generate(GapicContext context, Service service) { VariableExpr.withVariable( Variable.builder() .setName(CALLABLE_FACTORY_MEMBER_NAME) - .setType(getFixedTypeStore().get(getStubCallableFactoryClass().getSimpleName())) + .setType(getTransportContext().stubCallableFactoryType()) .build())); List classStatements = @@ -182,16 +164,20 @@ public GapicClass generate(GapicContext context, Service service) { callableClassMemberVarExprs, classMemberVarExprs); + StubCommentComposer commentComposer = + new StubCommentComposer(getTransportContext().transportName()); + ClassDefinition classDef = ClassDefinition.builder() .setPackageString(pakkage) .setHeaderCommentStatements( - getCommentComposer().createTransportServiceStubClassHeaderComments( + commentComposer.createTransportServiceStubClassHeaderComments( service.name(), service.isDeprecated())) .setAnnotations(createClassAnnotations(service)) .setScope(ScopeNode.PUBLIC) .setName(className) - .setExtendsType(typeStore.get(getClassNames().getServiceStubClassName(service))) + .setExtendsType( + typeStore.get(getTransportContext().classNames().getServiceStubClassName(service))) .setStatements(classStatements) .setMethods( createClassMethods( @@ -220,34 +206,6 @@ protected List createGetMethodDescriptorsMethod( return Arrays.asList(); } - protected TypeStore getFixedTypeStore() { - return fixedTypeStore; - } - - protected StubCommentComposer getCommentComposer() { - return commentComposer; - } - - protected ClassNames getClassNames() { - return classNames; - } - - protected Class getCallSettingsClass() { - return callSettingsClass; - } - - protected Class getStubCallableFactoryClass() { - return stubCallableFactoryClass; - } - - protected Class getMethodDescriptorClass() { - return methodDescriptorClass; - } - - protected Class getOperationsStubClass() { - return operationsStubClass; - } - protected List createClassStatements( Service service, Map protoMethodNameToDescriptorVarExprs, @@ -379,7 +337,7 @@ private Map createCallableClassMembers( protected List createClassAnnotations(Service service) { List annotations = new ArrayList<>(); if (!PackageChecker.isGaApi(service.pakkage())) { - annotations.add(AnnotationNode.withType(getFixedTypeStore().get("BetaApi"))); + annotations.add(AnnotationNode.withType(FIXED_TYPESTORE.get("BetaApi"))); } if (service.isDeprecated()) { @@ -388,7 +346,7 @@ protected List createClassAnnotations(Service service) { annotations.add( AnnotationNode.builder() - .setType(getFixedTypeStore().get("Generated")) + .setType(FIXED_TYPESTORE.get("Generated")) .setDescription("by gapic-generator-java") .build()); return annotations; @@ -421,7 +379,7 @@ protected List createClassMethods( private List createStaticCreatorMethods(Service service, TypeStore typeStore) { TypeNode creatorMethodReturnType = - typeStore.get(getClassNames().getTransportServiceStubClassName(service)); + typeStore.get(getTransportContext().classNames().getTransportServiceStubClassName(service)); Function, MethodDefinition.Builder> creatorMethodStarterFn = argList -> MethodDefinition.builder() @@ -443,12 +401,12 @@ private List createStaticCreatorMethods(Service service, TypeS NewObjectExpr.builder().setType(creatorMethodReturnType).setArguments(argList).build(); TypeNode stubSettingsType = - typeStore.get(getClassNames().getServiceStubSettingsClassName(service)); + typeStore.get(getTransportContext().classNames().getServiceStubSettingsClassName(service)); VariableExpr settingsVarExpr = VariableExpr.withVariable( Variable.builder().setName("settings").setType(stubSettingsType).build()); - TypeNode clientContextType = getFixedTypeStore().get("ClientContext"); + TypeNode clientContextType = FIXED_TYPESTORE.get("ClientContext"); VariableExpr clientContextVarExpr = VariableExpr.withVariable( Variable.builder().setName("clientContext").setType(clientContextType).build()); @@ -457,7 +415,7 @@ private List createStaticCreatorMethods(Service service, TypeS VariableExpr.withVariable( Variable.builder() .setName("callableFactory") - .setType(getFixedTypeStore().get(getStubCallableFactoryClass().getSimpleName())) + .setType(getTransportContext().stubCallableFactoryType()) .build()); MethodInvocationExpr clientContextCreateMethodExpr = @@ -506,12 +464,12 @@ protected List createConstructorMethods( Map callableClassMemberVarExprs, Map protoMethodNameToDescriptorVarExprs) { TypeNode stubSettingsType = - typeStore.get(getClassNames().getServiceStubSettingsClassName(service)); + typeStore.get(getTransportContext().classNames().getServiceStubSettingsClassName(service)); VariableExpr settingsVarExpr = VariableExpr.withVariable( Variable.builder().setName("settings").setType(stubSettingsType).build()); - TypeNode clientContextType = getFixedTypeStore().get("ClientContext"); + TypeNode clientContextType = FIXED_TYPESTORE.get("ClientContext"); VariableExpr clientContextVarExpr = VariableExpr.withVariable( Variable.builder().setName("clientContext").setType(clientContextType).build()); @@ -520,11 +478,11 @@ protected List createConstructorMethods( VariableExpr.withVariable( Variable.builder() .setName("callableFactory") - .setType(getFixedTypeStore().get(getStubCallableFactoryClass().getSimpleName())) + .setType(getTransportContext().stubCallableFactoryType()) .build()); TypeNode thisClassType = - typeStore.get(getClassNames().getTransportServiceStubClassName(service)); + typeStore.get(getTransportContext().classNames().getTransportServiceStubClassName(service)); TypeNode ioExceptionType = TypeNode.withReference(ConcreteReference.withClazz(IOException.class)); @@ -556,7 +514,8 @@ protected List createConstructorMethods( NewObjectExpr.builder() .setType( typeStore.get( - getClassNames() + getTransportContext() + .classNames() .getTransportServiceCallableFactoryClassName(service))) .build()) .build()))); @@ -564,22 +523,20 @@ protected List createConstructorMethods( Expr thisExpr = ValueExpr.withValue( ThisObjectValue.withType( - typeStore.get(getClassNames().getTransportServiceStubClassName(service)))); + typeStore.get(getTransportContext().classNames().getTransportServiceStubClassName(service)))); // Body of the second constructor method. List secondCtorStatements = new ArrayList<>(); List secondCtorExprs = new ArrayList<>(); secondCtorExprs.add( AssignmentExpr.builder() .setVariableExpr( - classMemberVarExprs - .get("callableFactory") - .toBuilder() + classMemberVarExprs.get("callableFactory").toBuilder() .setExprReferenceExpr(thisExpr) .build()) .setValueExpr(callableFactoryVarExpr) .build()); VariableExpr operationsStubClassVarExpr = classMemberVarExprs.get(OPERATIONS_STUB_MEMBER_NAME); - if (getOperationsStubClass() != null) { + if (getTransportContext().transportOperationsStubType() != null) { secondCtorExprs.add( AssignmentExpr.builder() .setVariableExpr( @@ -587,7 +544,7 @@ protected List createConstructorMethods( .setValueExpr( MethodInvocationExpr.builder() .setStaticReferenceType( - getFixedTypeStore().get(getOperationsStubClass().getSimpleName())) + getTransportContext().transportOperationsStubType()) .setMethodName("create") .setArguments(Arrays.asList(clientContextVarExpr, callableFactoryVarExpr)) .setReturnType(operationsStubClassVarExpr.type()) @@ -615,7 +572,7 @@ protected List createConstructorMethods( .setType( TypeNode.withReference( ConcreteReference.builder() - .setClazz(getCallSettingsClass()) + .setClazz(getTransportContext().callSettingsClass()) .setGenerics( Arrays.asList( m.inputType().reference(), @@ -671,7 +628,7 @@ protected List createConstructorMethods( backgroundResourcesVarExpr.toBuilder().setExprReferenceExpr(thisExpr).build()) .setValueExpr( NewObjectExpr.builder() - .setType(getFixedTypeStore().get("BackgroundResourceAggregation")) + .setType(FIXED_TYPESTORE.get("BackgroundResourceAggregation")) .setArguments(Arrays.asList(getBackgroundResourcesMethodExpr)) .build()) .build()); @@ -853,7 +810,7 @@ private List createStubOverrideMethods( VariableExpr.withVariable( Variable.builder() .setName("unit") - .setType(getFixedTypeStore().get("TimeUnit")) + .setType(FIXED_TYPESTORE.get("TimeUnit")) .build())); javaMethods.add( methodMakerStarterFn @@ -863,7 +820,7 @@ private List createStubOverrideMethods( awaitTerminationArgs.stream() .map(v -> v.toBuilder().setIsDecl(true).build()) .collect(Collectors.toList())) - .setThrowsExceptions(Arrays.asList(getFixedTypeStore().get("InterruptedException"))) + .setThrowsExceptions(Arrays.asList(FIXED_TYPESTORE.get("InterruptedException"))) .setReturnExpr( MethodInvocationExpr.builder() .setExprReferenceExpr(backgroundResourcesVarExpr) @@ -883,10 +840,10 @@ private TypeStore createDynamicTypes(Service service, String stubPakkage) { typeStore.putAll( stubPakkage, Arrays.asList( - getClassNames().getTransportServiceStubClassName(service), - getClassNames().getServiceStubSettingsClassName(service), - getClassNames().getServiceStubClassName(service), - getClassNames().getTransportServiceCallableFactoryClassName(service))); + getTransportContext().classNames().getTransportServiceStubClassName(service), + getTransportContext().classNames().getServiceStubSettingsClassName(service), + getTransportContext().classNames().getServiceStubClassName(service), + getTransportContext().classNames().getTransportServiceCallableFactoryClassName(service))); // Pagination types. typeStore.putAll( service.pakkage(), @@ -895,21 +852,21 @@ private TypeStore createDynamicTypes(Service service, String stubPakkage) { .map(m -> String.format(PAGED_RESPONSE_TYPE_NAME_PATTERN, m.name())) .collect(Collectors.toList()), true, - getClassNames().getServiceClientClassName(service)); + getTransportContext().classNames().getServiceClientClassName(service)); return typeStore; } - private TypeNode getCallableType(Method protoMethod) { - TypeNode callableType = getFixedTypeStore().get("UnaryCallable"); + private static TypeNode getCallableType(Method protoMethod) { + TypeNode callableType = FIXED_TYPESTORE.get("UnaryCallable"); switch (protoMethod.stream()) { case CLIENT: - callableType = getFixedTypeStore().get("ClientStreamingCallable"); + callableType = FIXED_TYPESTORE.get("ClientStreamingCallable"); break; case SERVER: - callableType = getFixedTypeStore().get("ServerStreamingCallable"); + callableType = FIXED_TYPESTORE.get("ServerStreamingCallable"); break; case BIDI: - callableType = getFixedTypeStore().get("BidiStreamingCallable"); + callableType = FIXED_TYPESTORE.get("BidiStreamingCallable"); break; case NONE: // Fall through @@ -925,31 +882,6 @@ private TypeNode getCallableType(Method protoMethod) { protoMethod.inputType().reference(), protoMethod.outputType().reference()))); } - protected EnumRefExpr getMethodDescriptorMethodTypeExpr(Method protoMethod) { - String enumName = ""; - switch (protoMethod.stream()) { - case CLIENT: - enumName = "CLIENT_STREAMING"; - break; - case SERVER: - enumName = "SERVER_STREAMING"; - break; - case BIDI: - enumName = "BIDI_STREAMING"; - break; - case NONE: - // Fall through. - default: - enumName = "UNARY"; - } - return EnumRefExpr.builder() - .setName(enumName) - .setType( - TypeNode.withReference( - ConcreteReference.builder().setClazz(MethodDescriptor.MethodType.class).build())) - .build(); - } - private CommentStatement createProtectedCtorComment(Service service) { return CommentStatement.withComment( JavaDocComment.withComment( @@ -957,7 +889,7 @@ private CommentStatement createProtectedCtorComment(Service service) { "Constructs an instance of %s, using the given settings. This is protected so that" + " it is easy to make a subclass, but otherwise, the static factory methods" + " should be preferred.", - getClassNames().getTransportServiceStubClassName(service)))); + getTransportContext().classNames().getTransportServiceStubClassName(service)))); } protected String getProtoRpcFullMethodName(Service protoService, Method protoMethod) { diff --git a/src/main/java/com/google/api/generator/gapic/composer/common/TransportContext.java b/src/main/java/com/google/api/generator/gapic/composer/common/TransportContext.java index cce00dcc9e..4058fbafbf 100644 --- a/src/main/java/com/google/api/generator/gapic/composer/common/TransportContext.java +++ b/src/main/java/com/google/api/generator/gapic/composer/common/TransportContext.java @@ -19,6 +19,7 @@ import com.google.api.generator.gapic.composer.utils.ClassNames; import com.google.api.generator.gapic.model.Transport; import com.google.auto.value.AutoValue; +import javax.annotation.Nullable; @AutoValue public abstract class TransportContext { @@ -36,6 +37,7 @@ public abstract class TransportContext { public abstract Class methodDescriptorClass(); + @Nullable public abstract TypeNode transportOperationsStubType(); // For AbstractServiceSettingsClassComposer diff --git a/src/main/java/com/google/api/generator/gapic/composer/grpc/GrpcServiceStubClassComposer.java b/src/main/java/com/google/api/generator/gapic/composer/grpc/GrpcServiceStubClassComposer.java index 41eeca7644..e7b30ebcbe 100644 --- a/src/main/java/com/google/api/generator/gapic/composer/grpc/GrpcServiceStubClassComposer.java +++ b/src/main/java/com/google/api/generator/gapic/composer/grpc/GrpcServiceStubClassComposer.java @@ -20,6 +20,7 @@ import com.google.api.generator.engine.ast.AnonymousClassExpr; import com.google.api.generator.engine.ast.AssignmentExpr; import com.google.api.generator.engine.ast.ConcreteReference; +import com.google.api.generator.engine.ast.EnumRefExpr; import com.google.api.generator.engine.ast.Expr; import com.google.api.generator.engine.ast.ExprStatement; import com.google.api.generator.engine.ast.MethodDefinition; @@ -42,6 +43,7 @@ import com.google.common.collect.ImmutableMap; import com.google.longrunning.stub.GrpcOperationsStub; import io.grpc.MethodDescriptor; +import io.grpc.protobuf.ProtoUtils; import java.util.ArrayList; import java.util.Arrays; import java.util.HashSet; @@ -62,15 +64,10 @@ public class GrpcServiceStubClassComposer extends AbstractServiceStubClassCompos private static final Set REROUTE_TO_GRPC_INTERFACE_IAM_METHOD_ALLOWLIST = new HashSet<>(Arrays.asList("SetIamPolicy", "GetIamPolicy", "TestIamPermissions")); + private static final TypeStore FIXED_GRPC_TYPE_STORE = createStaticTypes(); + protected GrpcServiceStubClassComposer() { - super( - createStaticTypes(), - new StubCommentComposer("gRPC"), - new ClassNames("Grpc"), - GrpcCallSettings.class, - GrpcStubCallableFactory.class, - MethodDescriptor.class, - GrpcOperationsStub.class); + super(GrpcContext.instance()); } public static GrpcServiceStubClassComposer instance() { @@ -78,11 +75,14 @@ public static GrpcServiceStubClassComposer instance() { } private static TypeStore createStaticTypes() { - TypeStore typeStore = createCommonStaticTypes(); - typeStore.putAll( + List concreteClazzes = Arrays.asList( - GrpcCallSettings.class, GrpcOperationsStub.class, GrpcStubCallableFactory.class)); - return typeStore; + GrpcCallSettings.class, + GrpcOperationsStub.class, + GrpcStubCallableFactory.class, + MethodDescriptor.class, + ProtoUtils.class); + return new TypeStore(concreteClazzes); } @Override @@ -91,7 +91,7 @@ protected Statement createMethodDescriptorVariableDecl( MethodInvocationExpr methodDescriptorMaker = MethodInvocationExpr.builder() .setMethodName("newBuilder") - .setStaticReferenceType(getFixedTypeStore().get("MethodDescriptor")) + .setStaticReferenceType(FIXED_GRPC_TYPE_STORE.get("MethodDescriptor")) .setGenerics(methodDescriptorVarExpr.variable().type().reference().generics()) .build(); @@ -120,7 +120,7 @@ protected Statement createMethodDescriptorVariableDecl( Function protoUtilsMarshallerFn = m -> MethodInvocationExpr.builder() - .setStaticReferenceType(getFixedTypeStore().get("ProtoUtils")) + .setStaticReferenceType(FIXED_GRPC_TYPE_STORE.get("ProtoUtils")) .setMethodName("marshaller") .setArguments(Arrays.asList(m)) .build(); @@ -155,8 +155,7 @@ protected Statement createMethodDescriptorVariableDecl( return ExprStatement.withExpr( AssignmentExpr.builder() .setVariableExpr( - methodDescriptorVarExpr - .toBuilder() + methodDescriptorVarExpr.toBuilder() .setIsDecl(true) .setScope(ScopeNode.PRIVATE) .setIsStatic(true) @@ -166,6 +165,31 @@ protected Statement createMethodDescriptorVariableDecl( .build()); } + protected EnumRefExpr getMethodDescriptorMethodTypeExpr(Method protoMethod) { + String enumName = ""; + switch (protoMethod.stream()) { + case CLIENT: + enumName = "CLIENT_STREAMING"; + break; + case SERVER: + enumName = "SERVER_STREAMING"; + break; + case BIDI: + enumName = "BIDI_STREAMING"; + break; + case NONE: + // Fall through. + default: + enumName = "UNARY"; + } + return EnumRefExpr.builder() + .setName(enumName) + .setType( + TypeNode.withReference( + ConcreteReference.builder().setClazz(MethodDescriptor.MethodType.class).build())) + .build(); + } + @Override protected List createOperationsStubGetterMethod( VariableExpr operationsStubVarExpr) { @@ -183,7 +207,7 @@ protected Expr createTransportSettingsInitExpr( Method method, VariableExpr transportSettingsVarExpr, VariableExpr methodDescriptorVarExpr) { MethodInvocationExpr callSettingsBuilderExpr = MethodInvocationExpr.builder() - .setStaticReferenceType(getFixedTypeStore().get(getCallSettingsClass().getSimpleName())) + .setStaticReferenceType(getTransportContext().transportCallSettingsType()) .setGenerics(transportSettingsVarExpr.type().reference().generics()) .setMethodName("newBuilder") .build(); @@ -253,7 +277,7 @@ private AnonymousClassExpr createRequestParamsExtractorAnonClass(Method method) .setVariableExpr(paramsVarExpr.toBuilder().setIsDecl(true).build()) .setValueExpr( MethodInvocationExpr.builder() - .setStaticReferenceType(getFixedTypeStore().get("ImmutableMap")) + .setStaticReferenceType(FIXED_TYPESTORE.get("ImmutableMap")) .setMethodName("builder") .setReturnType(paramsVarType) .build()) From 23737f12657a16a587290507c16f6e0587ed60ed Mon Sep 17 00:00:00 2001 From: vam-google Date: Fri, 21 May 2021 01:40:21 -0700 Subject: [PATCH 10/16] chore: DIREGAPIC #2 ServiceStubSettingsClassComposer refactoring --- ...tractServiceStubSettingsClassComposer.java | 147 +++++++++--------- .../grpc/ServiceClientTestClassComposer.java | 6 +- .../ServiceStubSettingsClassComposer.java | 30 ++-- .../gapic/composer/store/TypeStore.java | 8 - 4 files changed, 87 insertions(+), 104 deletions(-) diff --git a/src/main/java/com/google/api/generator/gapic/composer/common/AbstractServiceStubSettingsClassComposer.java b/src/main/java/com/google/api/generator/gapic/composer/common/AbstractServiceStubSettingsClassComposer.java index 801861c179..616b3095f0 100644 --- a/src/main/java/com/google/api/generator/gapic/composer/common/AbstractServiceStubSettingsClassComposer.java +++ b/src/main/java/com/google/api/generator/gapic/composer/common/AbstractServiceStubSettingsClassComposer.java @@ -136,30 +136,25 @@ public abstract class AbstractServiceStubSettingsClassComposer implements ClassC private static final String DOT = "."; + protected static final TypeStore FIXED_TYPESTORE = createStaticTypes(); + private static final VariableExpr DEFAULT_SERVICE_SCOPES_VAR_EXPR = createDefaultServiceScopesVarExpr(); private static final VariableExpr NESTED_UNARY_METHOD_SETTINGS_BUILDERS_VAR_EXPR = createNestedUnaryMethodSettingsBuildersVarExpr(); private static final VariableExpr NESTED_RETRYABLE_CODE_DEFINITIONS_VAR_EXPR = createNestedRetryableCodeDefinitionsVarExpr(); + private static final VariableExpr NESTED_RETRY_PARAM_DEFINITIONS_VAR_EXPR = + createNestedRetryParamDefinitionsVarExpr(); + + private final TransportContext transportContext; + + protected AbstractServiceStubSettingsClassComposer(TransportContext transportContext) { + this.transportContext = transportContext; + } - private final VariableExpr nestedRetryParamDefinitionsVarExpr; - - private final ClassNames classNames; - private final TypeStore fixedTypeStore; - private final Class transportChannelClass; - private final String transportGetterName; - - protected AbstractServiceStubSettingsClassComposer( - TypeStore fixedTypeStore, - ClassNames classNames, - Class transportChannelClass, - String transportGetterName) { - this.fixedTypeStore = fixedTypeStore; - this.classNames = classNames; - this.transportChannelClass = transportChannelClass; - this.nestedRetryParamDefinitionsVarExpr = createNestedRetryParamDefinitionsVarExpr(); - this.transportGetterName = transportGetterName; + public TransportContext getTransportContext() { + return transportContext; } @Override @@ -207,27 +202,27 @@ protected abstract MethodDefinition createDefaultApiClientHeaderProviderBuilderM Service service, TypeStore typeStore); public abstract MethodDefinition createDefaultTransportChannelProviderMethod(); - - protected TypeStore getFixedTypeStore() { - return fixedTypeStore; - } - - protected ClassNames getClassNames() { - return classNames; - } - - protected Class getTransportChannelClass() { - return transportChannelClass; - } - - protected String getTransportGetterName() { - return transportGetterName; - } + // + // protected TypeStore getFixedTypeStore() { + // return fixedTypeStore; + // } + // + // protected ClassNames getClassNames() { + // return classNames; + // } + // + // protected Class getTransportChannelClass() { + // return transportChannelClass; + // } + // + // protected String getTransportGetterName() { + // return transportGetterName; + // } private List createClassAnnotations(Service service) { List annotations = new ArrayList<>(); if (!PackageChecker.isGaApi(service.pakkage())) { - annotations.add(AnnotationNode.withType(getFixedTypeStore().get("BetaApi"))); + annotations.add(AnnotationNode.withType(FIXED_TYPESTORE.get("BetaApi"))); } if (service.isDeprecated()) { @@ -236,7 +231,7 @@ private List createClassAnnotations(Service service) { annotations.add( AnnotationNode.builder() - .setType(getFixedTypeStore().get("Generated")) + .setType(FIXED_TYPESTORE.get("Generated")) .setDescription("by gapic-generator-java") .build()); return annotations; @@ -272,7 +267,7 @@ private static List createClassHeaderComments( private TypeNode createExtendsType(Service service, TypeStore typeStore) { TypeNode thisClassType = typeStore.get(ClassNames.getServiceStubSettingsClassName(service)); return TypeNode.withReference( - getFixedTypeStore() + FIXED_TYPESTORE .get("StubSettings") .reference() .copyAndSetGenerics(Arrays.asList(thisClassType.reference()))); @@ -314,7 +309,7 @@ private static Map createMethodSettingsClassMemberVarExprs return varExprs; } - private List createClassStatements( + private static List createClassStatements( Service service, GapicServiceConfig serviceConfig, Map methodSettingsMemberVarExprs, @@ -335,7 +330,7 @@ private List createClassStatements( .build(); MethodInvocationExpr listBuilderExpr = MethodInvocationExpr.builder() - .setStaticReferenceType(getFixedTypeStore().get("ImmutableList")) + .setStaticReferenceType(FIXED_TYPESTORE.get("ImmutableList")) .setGenerics(Arrays.asList(ConcreteReference.withClazz(String.class))) .setMethodName("builder") .build(); @@ -399,7 +394,7 @@ private List createClassStatements( return statements; } - private List createPagingStaticAssignExprs( + private static List createPagingStaticAssignExprs( Service service, GapicServiceConfig serviceConfig, Map messageTypes, @@ -646,7 +641,7 @@ private static Expr createPagedListDescriptorAssignExpr( .build(); } - private Expr createPagedListResponseFactoryAssignExpr( + private static Expr createPagedListResponseFactoryAssignExpr( VariableExpr pageStrDescVarExpr, Method method, TypeNode repeatedResponseType, @@ -683,7 +678,7 @@ private Expr createPagedListResponseFactoryAssignExpr( VariableExpr contextVarExpr = VariableExpr.withVariable( Variable.builder() - .setType(getFixedTypeStore().get("ApiCallContext")) + .setType(FIXED_TYPESTORE.get("ApiCallContext")) .setName("context") .build()); VariableExpr futureResponseVarExpr = @@ -716,7 +711,7 @@ private Expr createPagedListResponseFactoryAssignExpr( .setVariableExpr(pageContextVarExpr.toBuilder().setIsDecl(true).build()) .setValueExpr( MethodInvocationExpr.builder() - .setStaticReferenceType(getFixedTypeStore().get("PageContext")) + .setStaticReferenceType(FIXED_TYPESTORE.get("PageContext")) .setMethodName("create") .setArguments( callableVarExpr, pageStrDescVarExpr, requestVarExpr, contextVarExpr) @@ -831,8 +826,8 @@ private MethodDefinition createCreateStubMethod(Service service, TypeStore typeS Expr tRansportNameExpr = MethodInvocationExpr.builder() .setStaticReferenceType( - getFixedTypeStore().get(getTransportChannelClass().getSimpleName())) - .setMethodName(getTransportGetterName()) + getTransportContext().transportChannelType()) + .setMethodName(getTransportContext().transportGetterName()) .build(); Expr getTransportNameExpr = @@ -854,7 +849,7 @@ private MethodDefinition createCreateStubMethod(Service service, TypeStore typeS Expr createExpr = MethodInvocationExpr.builder() .setStaticReferenceType( - typeStore.get(getClassNames().getTransportServiceStubClassName(service))) + typeStore.get(getTransportContext().classNames().getTransportServiceStubClassName(service))) .setMethodName("create") .setArguments( ValueExpr.withValue( @@ -887,7 +882,7 @@ private MethodDefinition createCreateStubMethod(Service service, TypeStore typeS TypeNode returnType = typeStore.get(ClassNames.getServiceStubClassName(service)); AnnotationNode annotation = AnnotationNode.builder() - .setType(getFixedTypeStore().get("BetaApi")) + .setType(FIXED_TYPESTORE.get("BetaApi")) .setDescription( "A restructuring of stub classes is planned, so this may break in the future") .build(); @@ -920,8 +915,7 @@ private List createDefaultHelperAndGetterMethods( .setName("defaultExecutorProviderBuilder") .setReturnExpr( MethodInvocationExpr.builder() - .setStaticReferenceType( - getFixedTypeStore().get("InstantiatingExecutorProvider")) + .setStaticReferenceType(FIXED_TYPESTORE.get("InstantiatingExecutorProvider")) .setMethodName("newBuilder") .setReturnType(returnType) .build()) @@ -964,7 +958,7 @@ private List createDefaultHelperAndGetterMethods( ConcreteReference.withClazz(GoogleCredentialsProvider.Builder.class)); MethodInvocationExpr credsProviderBuilderExpr = MethodInvocationExpr.builder() - .setStaticReferenceType(getFixedTypeStore().get("GoogleCredentialsProvider")) + .setStaticReferenceType(FIXED_TYPESTORE.get("GoogleCredentialsProvider")) .setMethodName("newBuilder") .build(); credsProviderBuilderExpr = @@ -992,7 +986,7 @@ private List createDefaultHelperAndGetterMethods( return javaMethods; } - private List createBuilderHelperMethods(Service service, TypeStore typeStore) { + private static List createBuilderHelperMethods(Service service, TypeStore typeStore) { List javaMethods = new ArrayList<>(); // Create the newBuilder() method. final TypeNode builderReturnType = typeStore.get(NESTED_BUILDER_CLASS_NAME); @@ -1017,7 +1011,7 @@ private List createBuilderHelperMethods(Service service, TypeS VariableExpr clientContextVarExpr = VariableExpr.withVariable( Variable.builder() - .setType(getFixedTypeStore().get("ClientContext")) + .setType(FIXED_TYPESTORE.get("ClientContext")) .setName("clientContext") .build()); javaMethods.add( @@ -1048,7 +1042,7 @@ private List createBuilderHelperMethods(Service service, TypeS return javaMethods; } - private MethodDefinition createClassConstructor( + private static MethodDefinition createClassConstructor( Service service, Map methodSettingsMemberVarExprs, TypeStore typeStore) { @@ -1062,7 +1056,7 @@ private MethodDefinition createClassConstructor( Expr superCtorExpr = ReferenceConstructorExpr.superBuilder() - .setType(getFixedTypeStore().get("StubSettings")) + .setType(FIXED_TYPESTORE.get("StubSettings")) .setArguments(settingsBuilderVarExpr) .build(); @@ -1099,7 +1093,7 @@ private MethodDefinition createClassConstructor( .build(); } - private ClassDefinition createNestedBuilderClass( + private static ClassDefinition createNestedBuilderClass( Service service, @Nullable GapicServiceConfig serviceConfig, TypeStore typeStore) { // TODO(miraleung): Robustify this against a null serviceConfig. String thisClassName = ClassNames.getServiceStubSettingsClassName(service); @@ -1149,7 +1143,7 @@ private ClassDefinition createNestedBuilderClass( .build(); } - private List createNestedClassStatements( + private static List createNestedClassStatements( Service service, GapicServiceConfig serviceConfig, Map nestedMethodSettingsMemberVarExprs) { @@ -1190,16 +1184,16 @@ private List createNestedClassStatements( // Declare the RETRY_PARAM_DEFINITIONS field. statements.add( - exprStatementFn.apply(varStaticDeclFn.apply(nestedRetryParamDefinitionsVarExpr))); + exprStatementFn.apply(varStaticDeclFn.apply(NESTED_RETRY_PARAM_DEFINITIONS_VAR_EXPR))); statements.add( RetrySettingsComposer.createRetryParamDefinitionsBlock( - service, serviceConfig, nestedRetryParamDefinitionsVarExpr)); + service, serviceConfig, NESTED_RETRY_PARAM_DEFINITIONS_VAR_EXPR)); return statements; } - private List createNestedClassMethods( + private static List createNestedClassMethods( Service service, GapicServiceConfig serviceConfig, TypeNode superType, @@ -1221,7 +1215,7 @@ private List createNestedClassMethods( return nestedClassMethods; } - private MethodDefinition createNestedClassInitDefaultsMethod( + private static MethodDefinition createNestedClassInitDefaultsMethod( Service service, @Nullable GapicServiceConfig serviceConfig, TypeStore typeStore) { // TODO(miraleung): Robustify this against a null serviceConfig. TypeNode builderType = typeStore.get(NESTED_BUILDER_CLASS_NAME); @@ -1261,7 +1255,7 @@ private MethodDefinition createNestedClassInitDefaultsMethod( method, builderVarExpr, NESTED_RETRYABLE_CODE_DEFINITIONS_VAR_EXPR, - nestedRetryParamDefinitionsVarExpr))); + NESTED_RETRY_PARAM_DEFINITIONS_VAR_EXPR))); bodyStatements.add(EMPTY_LINE_STATEMENT); } for (Method method : service.methods()) { @@ -1276,7 +1270,7 @@ private MethodDefinition createNestedClassInitDefaultsMethod( method, builderVarExpr, NESTED_RETRYABLE_CODE_DEFINITIONS_VAR_EXPR, - nestedRetryParamDefinitionsVarExpr))); + NESTED_RETRY_PARAM_DEFINITIONS_VAR_EXPR))); bodyStatements.add(EMPTY_LINE_STATEMENT); } @@ -1291,7 +1285,7 @@ private MethodDefinition createNestedClassInitDefaultsMethod( .build(); } - private List createNestedClassConstructorMethods( + private static List createNestedClassConstructorMethods( Service service, GapicServiceConfig serviceConfig, Map nestedMethodSettingsMemberVarExprs, @@ -1312,7 +1306,7 @@ private List createNestedClassConstructorMethods( .setType(builderType) .setArguments( CastExpr.builder() - .setType(getFixedTypeStore().get("ClientContext")) + .setType(FIXED_TYPESTORE.get("ClientContext")) .setExpr(ValueExpr.createNullExpr()) .build()) .build()))) @@ -1322,7 +1316,7 @@ private List createNestedClassConstructorMethods( VariableExpr clientContextVarExpr = VariableExpr.withVariable( Variable.builder() - .setType(getFixedTypeStore().get("ClientContext")) + .setType(FIXED_TYPESTORE.get("ClientContext")) .setName("clientContext") .build()); Reference pagedSettingsBuilderRef = @@ -1391,7 +1385,7 @@ private List createNestedClassConstructorMethods( } Expr newBatchingSettingsExpr = MethodInvocationExpr.builder() - .setStaticReferenceType(getFixedTypeStore().get("BatchingSettings")) + .setStaticReferenceType(FIXED_TYPESTORE.get("BatchingSettings")) .setMethodName("newBuilder") .build(); newBatchingSettingsExpr = @@ -1410,7 +1404,7 @@ private List createNestedClassConstructorMethods( .setArguments( VariableExpr.withVariable( Variable.builder() - .setType(getFixedTypeStore().get("BatchingDescriptor")) + .setType(FIXED_TYPESTORE.get("BatchingDescriptor")) .setName(batchingDescVarName) .build())) .build(); @@ -1435,7 +1429,7 @@ private List createNestedClassConstructorMethods( VariableExpr argVar = VariableExpr.withVariable( Variable.builder() - .setType(getFixedTypeStore().get("PagedListResponseFactory")) + .setType(FIXED_TYPESTORE.get("PagedListResponseFactory")) .setName(memberVarName) .build()); Expr builderExpr = @@ -1459,7 +1453,7 @@ private List createNestedClassConstructorMethods( .setVariableExpr(NESTED_UNARY_METHOD_SETTINGS_BUILDERS_VAR_EXPR) .setValueExpr( MethodInvocationExpr.builder() - .setStaticReferenceType(getFixedTypeStore().get("ImmutableList")) + .setStaticReferenceType(FIXED_TYPESTORE.get("ImmutableList")) .setGenerics( NESTED_UNARY_METHOD_SETTINGS_BUILDERS_VAR_EXPR .type() @@ -1546,7 +1540,7 @@ private List createNestedClassConstructorMethods( return ctorMethods; } - private MethodDefinition createNestedClassCreateDefaultMethod(TypeStore typeStore) { + private static MethodDefinition createNestedClassCreateDefaultMethod(TypeStore typeStore) { List bodyStatements = new ArrayList<>(); // Initialize the builder: Builder builder = new Builder((ClientContext) null); @@ -1563,7 +1557,7 @@ private MethodDefinition createNestedClassCreateDefaultMethod(TypeStore typeStor .setType(builderType) .setArguments( CastExpr.builder() - .setType(getFixedTypeStore().get("ClientContext")) + .setType(FIXED_TYPESTORE.get("ClientContext")) .setExpr(ValueExpr.createNullExpr()) .build()) .build()) @@ -1687,7 +1681,7 @@ private static MethodDefinition createNestedClassUnaryMethodSettingsBuilderGette .build(); } - private List createNestedClassSettingsBuilderGetterMethods( + private static List createNestedClassSettingsBuilderGetterMethods( Map nestedMethodSettingsMemberVarExprs, Set nestedDeprecatedSettingVarNames) { Reference operationCallSettingsBuilderRef = @@ -1699,7 +1693,7 @@ private List createNestedClassSettingsBuilderGetterMethods( .equals(operationCallSettingsBuilderRef); AnnotationNode lroBetaAnnotation = AnnotationNode.builder() - .setType(getFixedTypeStore().get("BetaApi")) + .setType(FIXED_TYPESTORE.get("BetaApi")) .setDescription( "The surface for use by generated code is not stable yet and may change in the" + " future.") @@ -1758,7 +1752,7 @@ private static MethodDefinition createNestedClassBuildMethod( .build(); } - protected static TypeStore createCommonStaticTypes() { + private static TypeStore createStaticTypes() { List concreteClazzes = Arrays.asList( ApiCallContext.class, @@ -1816,7 +1810,7 @@ private TypeStore createDynamicTypes(Service service, String pakkage) { pakkage, Arrays.asList( thisClassName, - getClassNames().getTransportServiceStubClassName(service), + getTransportContext().classNames().getTransportServiceStubClassName(service), ClassNames.getServiceStubSettingsClassName(service), ClassNames.getServiceStubClassName(service))); @@ -1889,14 +1883,13 @@ private static VariableExpr createNestedRetryableCodeDefinitionsVarExpr() { .build()); } - private VariableExpr createNestedRetryParamDefinitionsVarExpr() { + private static VariableExpr createNestedRetryParamDefinitionsVarExpr() { TypeNode varType = TypeNode.withReference( ConcreteReference.builder() .setClazz(ImmutableMap.class) .setGenerics( - Arrays.asList(TypeNode.STRING, getFixedTypeStore().get("RetrySettings")) - .stream() + Arrays.asList(TypeNode.STRING, FIXED_TYPESTORE.get("RetrySettings")).stream() .map(t -> t.reference()) .collect(Collectors.toList())) .build()); diff --git a/src/main/java/com/google/api/generator/gapic/composer/grpc/ServiceClientTestClassComposer.java b/src/main/java/com/google/api/generator/gapic/composer/grpc/ServiceClientTestClassComposer.java index 98eb1e37db..af78d3c16f 100644 --- a/src/main/java/com/google/api/generator/gapic/composer/grpc/ServiceClientTestClassComposer.java +++ b/src/main/java/com/google/api/generator/gapic/composer/grpc/ServiceClientTestClassComposer.java @@ -69,6 +69,9 @@ public class ServiceClientTestClassComposer extends AbstractServiceClientTestCla private static final String SERVICE_HELPER_VAR_NAME = "mockServiceHelper"; private static final String CHANNEL_PROVIDER_VAR_NAME = "channelProvider"; + private static final ServiceClientTestClassComposer INSTANCE = + new ServiceClientTestClassComposer(); + protected static final TypeStore FIXED_GRPC_TYPESTORE = createStaticTypes(); private static final TypeNode LIST_TYPE = @@ -88,9 +91,6 @@ protected ServiceClientTestClassComposer() { super(GrpcContext.instance()); } - private static final ServiceClientTestClassComposer INSTANCE = - new ServiceClientTestClassComposer(); - public static AbstractServiceClientTestClassComposer instance() { return INSTANCE; } diff --git a/src/main/java/com/google/api/generator/gapic/composer/grpc/ServiceStubSettingsClassComposer.java b/src/main/java/com/google/api/generator/gapic/composer/grpc/ServiceStubSettingsClassComposer.java index 92801ea752..9d96aba607 100644 --- a/src/main/java/com/google/api/generator/gapic/composer/grpc/ServiceStubSettingsClassComposer.java +++ b/src/main/java/com/google/api/generator/gapic/composer/grpc/ServiceStubSettingsClassComposer.java @@ -34,31 +34,29 @@ import com.google.api.generator.gapic.composer.utils.ClassNames; import com.google.api.generator.gapic.model.Service; import java.util.Arrays; +import java.util.List; public class ServiceStubSettingsClassComposer extends AbstractServiceStubSettingsClassComposer { private static final ServiceStubSettingsClassComposer INSTANCE = new ServiceStubSettingsClassComposer(); + protected static final TypeStore FIXED_GRPC_TYPESTORE = createStaticTypes(); + public static ServiceStubSettingsClassComposer instance() { return INSTANCE; } protected ServiceStubSettingsClassComposer() { - super( - createStaticTypes(), - new ClassNames("Grpc"), - GrpcTransportChannel.class, - "getGrpcTransportName"); + super(GrpcContext.instance()); } private static TypeStore createStaticTypes() { - TypeStore typeStore = createCommonStaticTypes(); - typeStore.putAll( + List concreteClazzes = Arrays.asList( GaxGrpcProperties.class, GrpcTransportChannel.class, - InstantiatingGrpcChannelProvider.class)); - return typeStore; + InstantiatingGrpcChannelProvider.class); + return new TypeStore(concreteClazzes); } @Override @@ -70,7 +68,7 @@ protected MethodDefinition createDefaultTransportTransportProviderBuilderMethod( MethodInvocationExpr transportChannelProviderBuilderExpr = MethodInvocationExpr.builder() .setStaticReferenceType( - getFixedTypeStore().get(InstantiatingGrpcChannelProvider.class.getSimpleName())) + FIXED_GRPC_TYPESTORE.get(InstantiatingGrpcChannelProvider.class.getSimpleName())) .setMethodName("newBuilder") .build(); transportChannelProviderBuilderExpr = @@ -104,13 +102,13 @@ protected MethodDefinition createDefaultApiClientHeaderProviderBuilderMethod( TypeNode.withReference(ConcreteReference.withClazz(ApiClientHeaderProvider.Builder.class)); MethodInvocationExpr returnExpr = MethodInvocationExpr.builder() - .setStaticReferenceType(getFixedTypeStore().get("ApiClientHeaderProvider")) + .setStaticReferenceType(FIXED_TYPESTORE.get("ApiClientHeaderProvider")) .setMethodName("newBuilder") .build(); MethodInvocationExpr versionArgExpr = MethodInvocationExpr.builder() - .setStaticReferenceType(getFixedTypeStore().get("GaxProperties")) + .setStaticReferenceType(FIXED_TYPESTORE.get("GaxProperties")) .setMethodName("getLibraryVersion") .setArguments( VariableExpr.builder() @@ -134,12 +132,12 @@ protected MethodDefinition createDefaultApiClientHeaderProviderBuilderMethod( .setArguments( MethodInvocationExpr.builder() .setStaticReferenceType( - getFixedTypeStore().get(GaxGrpcProperties.class.getSimpleName())) + FIXED_GRPC_TYPESTORE.get(GaxGrpcProperties.class.getSimpleName())) .setMethodName("getGrpcTokenName") .build(), MethodInvocationExpr.builder() .setStaticReferenceType( - getFixedTypeStore().get(GaxGrpcProperties.class.getSimpleName())) + FIXED_GRPC_TYPESTORE.get(GaxGrpcProperties.class.getSimpleName())) .setMethodName("getGrpcVersion") .build()) .setReturnType(returnType) @@ -147,7 +145,7 @@ protected MethodDefinition createDefaultApiClientHeaderProviderBuilderMethod( AnnotationNode annotation = AnnotationNode.builder() - .setType(getFixedTypeStore().get("BetaApi")) + .setType(FIXED_TYPESTORE.get("BetaApi")) .setDescription( "The surface for customizing headers is not stable yet and may change in the" + " future.") @@ -164,7 +162,7 @@ protected MethodDefinition createDefaultApiClientHeaderProviderBuilderMethod( @Override public MethodDefinition createDefaultTransportChannelProviderMethod() { - TypeNode returnType = getFixedTypeStore().get("TransportChannelProvider"); + TypeNode returnType = FIXED_TYPESTORE.get("TransportChannelProvider"); MethodInvocationExpr transportProviderBuilderExpr = MethodInvocationExpr.builder().setMethodName("defaultGrpcTransportProviderBuilder").build(); transportProviderBuilderExpr = diff --git a/src/main/java/com/google/api/generator/gapic/composer/store/TypeStore.java b/src/main/java/com/google/api/generator/gapic/composer/store/TypeStore.java index 1a6c2e1c13..061c42a67c 100644 --- a/src/main/java/com/google/api/generator/gapic/composer/store/TypeStore.java +++ b/src/main/java/com/google/api/generator/gapic/composer/store/TypeStore.java @@ -29,10 +29,6 @@ public class TypeStore { public TypeStore() {} public TypeStore(List concreteClasses) { - putConcreteClassses(concreteClasses); - } - - private void putConcreteClassses(List concreteClasses) { store.putAll( concreteClasses.stream() .collect( @@ -71,10 +67,6 @@ public void put( .build())); } - public void putAll(List concreteClasses) { - putConcreteClassses(concreteClasses); - } - public void putAll( String pakkage, List typeNames, From 61dffe23e93b25c00a6af577dc9ab1f10ef3c1dd Mon Sep 17 00:00:00 2001 From: vam-google Date: Fri, 21 May 2021 17:34:51 -0700 Subject: [PATCH 11/16] Address PR feedback, remove some unesed methdos to increase coverage. --- .../AbstractServiceClientTestClassComposer.java | 16 ---------------- ...AbstractServiceStubSettingsClassComposer.java | 16 ---------------- .../api/generator/gapic/model/Transport.java | 5 +++++ 3 files changed, 5 insertions(+), 32 deletions(-) diff --git a/src/main/java/com/google/api/generator/gapic/composer/common/AbstractServiceClientTestClassComposer.java b/src/main/java/com/google/api/generator/gapic/composer/common/AbstractServiceClientTestClassComposer.java index 17c6730112..7f45e974b3 100644 --- a/src/main/java/com/google/api/generator/gapic/composer/common/AbstractServiceClientTestClassComposer.java +++ b/src/main/java/com/google/api/generator/gapic/composer/common/AbstractServiceClientTestClassComposer.java @@ -842,14 +842,6 @@ private void addDynamicTypes(GapicContext context, Service service, TypeStore ty } } - private static TypeNode getOperationCallSettingsType(Method protoMethod) { - return getOperationCallSettingsTypeHelper(protoMethod, false); - } - - private static TypeNode getOperationCallSettingsBuilderType(Method protoMethod) { - return getOperationCallSettingsTypeHelper(protoMethod, true); - } - private static TypeNode getOperationCallSettingsTypeHelper( Method protoMethod, boolean isBuilder) { Preconditions.checkState( @@ -868,14 +860,6 @@ private static TypeNode getOperationCallSettingsTypeHelper( .build()); } - private static TypeNode getCallSettingsType(Method protoMethod, TypeStore typeStore) { - return getCallSettingsTypeHelper(protoMethod, typeStore, false); - } - - private static TypeNode getCallSettingsBuilderType(Method protoMethod, TypeStore typeStore) { - return getCallSettingsTypeHelper(protoMethod, typeStore, true); - } - private static TypeNode getCallSettingsTypeHelper( Method protoMethod, TypeStore typeStore, boolean isBuilder) { Class callSettingsClazz = isBuilder ? UnaryCallSettings.Builder.class : UnaryCallSettings.class; diff --git a/src/main/java/com/google/api/generator/gapic/composer/common/AbstractServiceStubSettingsClassComposer.java b/src/main/java/com/google/api/generator/gapic/composer/common/AbstractServiceStubSettingsClassComposer.java index 616b3095f0..fb2d350011 100644 --- a/src/main/java/com/google/api/generator/gapic/composer/common/AbstractServiceStubSettingsClassComposer.java +++ b/src/main/java/com/google/api/generator/gapic/composer/common/AbstractServiceStubSettingsClassComposer.java @@ -202,22 +202,6 @@ protected abstract MethodDefinition createDefaultApiClientHeaderProviderBuilderM Service service, TypeStore typeStore); public abstract MethodDefinition createDefaultTransportChannelProviderMethod(); - // - // protected TypeStore getFixedTypeStore() { - // return fixedTypeStore; - // } - // - // protected ClassNames getClassNames() { - // return classNames; - // } - // - // protected Class getTransportChannelClass() { - // return transportChannelClass; - // } - // - // protected String getTransportGetterName() { - // return transportGetterName; - // } private List createClassAnnotations(Service service) { List annotations = new ArrayList<>(); diff --git a/src/main/java/com/google/api/generator/gapic/model/Transport.java b/src/main/java/com/google/api/generator/gapic/model/Transport.java index 3390bbb1e1..07674eaaa8 100644 --- a/src/main/java/com/google/api/generator/gapic/model/Transport.java +++ b/src/main/java/com/google/api/generator/gapic/model/Transport.java @@ -22,6 +22,11 @@ public enum Transport { // instead. GRPC_REST; + /** + * Parse command line transport argument in the format `grpc+rest`. + * @param name name of the transport. Valid inputs are "grpc", "rest", "grpc+rest" + * @return the {@code Transport} enum matching the command line argument + */ public static Transport parse(String name) { return valueOf(name.replace('+', '_').toUpperCase()); } From c6c9ba67042baa9fd9f133d456677246944b7e2d Mon Sep 17 00:00:00 2001 From: vam-google Date: Fri, 21 May 2021 17:39:11 -0700 Subject: [PATCH 12/16] reformat code --- .../java/com/google/api/generator/gapic/model/Transport.java | 1 + 1 file changed, 1 insertion(+) diff --git a/src/main/java/com/google/api/generator/gapic/model/Transport.java b/src/main/java/com/google/api/generator/gapic/model/Transport.java index 07674eaaa8..e8e6326384 100644 --- a/src/main/java/com/google/api/generator/gapic/model/Transport.java +++ b/src/main/java/com/google/api/generator/gapic/model/Transport.java @@ -24,6 +24,7 @@ public enum Transport { /** * Parse command line transport argument in the format `grpc+rest`. + * * @param name name of the transport. Valid inputs are "grpc", "rest", "grpc+rest" * @return the {@code Transport} enum matching the command line argument */ From 7746993f5de2fb981b0ab62f40298121aec3c931 Mon Sep 17 00:00:00 2001 From: vam-google Date: Fri, 21 May 2021 17:42:32 -0700 Subject: [PATCH 13/16] reformat code --- .../api/generator/gapic/model/Transport.java | 29 +++++++++---------- 1 file changed, 14 insertions(+), 15 deletions(-) diff --git a/src/main/java/com/google/api/generator/gapic/model/Transport.java b/src/main/java/com/google/api/generator/gapic/model/Transport.java index e8e6326384..aeb7b9361c 100644 --- a/src/main/java/com/google/api/generator/gapic/model/Transport.java +++ b/src/main/java/com/google/api/generator/gapic/model/Transport.java @@ -1,18 +1,17 @@ -/* - * Copyright 2021 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. - */ +// Copyright 2021 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 +// +// http://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. + package com.google.api.generator.gapic.model; public enum Transport { From 224fdf53d001d9755e9f613102ec6d88c7638b3e Mon Sep 17 00:00:00 2001 From: vam-google Date: Fri, 21 May 2021 18:02:46 -0700 Subject: [PATCH 14/16] chore: upgrade java unit tests to "medium" (hopefuly will fix failure for java8 tests) --- .../com/google/api/generator/gapic/composer/grpc/BUILD.bazel | 1 + 1 file changed, 1 insertion(+) diff --git a/src/test/java/com/google/api/generator/gapic/composer/grpc/BUILD.bazel b/src/test/java/com/google/api/generator/gapic/composer/grpc/BUILD.bazel index 4ac8e2b387..8c0cabe5a1 100644 --- a/src/test/java/com/google/api/generator/gapic/composer/grpc/BUILD.bazel +++ b/src/test/java/com/google/api/generator/gapic/composer/grpc/BUILD.bazel @@ -69,6 +69,7 @@ java_proto_library( [java_test( name = test_name, + size = "medium", srcs = [ "{0}.java".format(test_name), ] + COMMON_SRCS, From aa21f2dc45678d5979671bb031279185d7d96d20 Mon Sep 17 00:00:00 2001 From: vam-google Date: Fri, 21 May 2021 18:18:35 -0700 Subject: [PATCH 15/16] add verbose error output for tests --- .github/workflows/ci.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index 33b7738029..ba9def0fea 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -46,7 +46,7 @@ jobs: echo "The old one will disappear after 7 days." - name: Unit Tests - run: bazel --batch test $(bazel query "//src/test/..." | grep "Test$") --noshow_progress + run: bazel --batch test $(bazel query "//src/test/..." | grep "Test$") --noshow_progress --test_output=errors - name: Integration Tests run: bazel --batch test //test/integration:asset //test/integration:credentials //test/integration:iam //test/integration:kms //test/integration:logging //test/integration:redis //test/integration:library --noshow_progress From 8e3545900718fb701cff608d0b3240c35c81384b Mon Sep 17 00:00:00 2001 From: vam-google Date: Fri, 21 May 2021 19:39:56 -0700 Subject: [PATCH 16/16] Fix test class generation fields ordering --- dependencies.properties | 2 +- .../grpc/ServiceClientTestClassComposer.java | 15 ++++++++++----- .../composer/grpc/goldens/EchoClientTest.golden | 2 +- .../grpc/goldens/LoggingClientTest.golden | 2 +- .../grpc/goldens/SubscriberClientTest.golden | 2 +- .../grpc/goldens/TestingClientTest.golden | 2 +- 6 files changed, 15 insertions(+), 10 deletions(-) diff --git a/dependencies.properties b/dependencies.properties index 2a2383286a..841111924b 100644 --- a/dependencies.properties +++ b/dependencies.properties @@ -15,7 +15,7 @@ version.com_google_gax_java=1.62.0 version.io_grpc_java=1.30.2 # Common deps. -maven.com_google_guava_guava=com.google.guava:guava:26.0-jre +maven.com_google_guava_guava=com.google.guava:guava:30.1-android maven.com_google_code_findbugs_jsr305=com.google.code.findbugs:jsr305:3.0.0 maven.com_google_auto_value_auto_value=com.google.auto.value:auto-value:1.7.2 maven.com_google_auto_value_auto_value_annotations=com.google.auto.value:auto-value-annotations:1.7.2 diff --git a/src/main/java/com/google/api/generator/gapic/composer/grpc/ServiceClientTestClassComposer.java b/src/main/java/com/google/api/generator/gapic/composer/grpc/ServiceClientTestClassComposer.java index af78d3c16f..8d06bd29a9 100644 --- a/src/main/java/com/google/api/generator/gapic/composer/grpc/ServiceClientTestClassComposer.java +++ b/src/main/java/com/google/api/generator/gapic/composer/grpc/ServiceClientTestClassComposer.java @@ -53,6 +53,7 @@ import com.google.api.generator.gapic.model.Service; import com.google.api.generator.gapic.utils.JavaStyle; import com.google.common.base.Preconditions; +import com.google.common.collect.ImmutableMap; import com.google.protobuf.AbstractMessage; import io.grpc.StatusRuntimeException; import java.util.ArrayList; @@ -125,8 +126,14 @@ protected Map createClassMemberVarExprs( fields.put(SERVICE_HELPER_VAR_NAME, FIXED_GRPC_TYPESTORE.get("MockServiceHelper")); fields.put(CLIENT_VAR_NAME, typeStore.get(ClassNames.getServiceClientClassName(service))); fields.put(CHANNEL_PROVIDER_VAR_NAME, FIXED_GRPC_TYPESTORE.get("LocalChannelProvider")); + return fields.entrySet().stream() - .collect(Collectors.toMap(e -> e.getKey(), e -> varExprFn.apply(e.getKey(), e.getValue()))); + .collect( + Collectors.toMap( + Map.Entry::getKey, + e -> varExprFn.apply(e.getKey(), e.getValue()), + (u, v) -> {throw new IllegalStateException();}, + LinkedHashMap::new)); } @Override @@ -193,8 +200,7 @@ protected MethodDefinition createStartStaticServerMethod( varInitExprs.add(startServiceHelperExpr); return MethodDefinition.builder() - .setAnnotations( - Arrays.asList(AnnotationNode.withType(FIXED_TYPESTORE.get("BeforeClass")))) + .setAnnotations(Arrays.asList(AnnotationNode.withType(FIXED_TYPESTORE.get("BeforeClass")))) .setScope(ScopeNode.PUBLIC) .setIsStatic(true) .setReturnType(TypeNode.VOID) @@ -208,8 +214,7 @@ protected MethodDefinition createStartStaticServerMethod( protected MethodDefinition createStopServerMethod( Service service, Map classMemberVarExprs) { return MethodDefinition.builder() - .setAnnotations( - Arrays.asList(AnnotationNode.withType(FIXED_TYPESTORE.get("AfterClass")))) + .setAnnotations(Arrays.asList(AnnotationNode.withType(FIXED_TYPESTORE.get("AfterClass")))) .setScope(ScopeNode.PUBLIC) .setIsStatic(true) .setReturnType(TypeNode.VOID) diff --git a/src/test/java/com/google/api/generator/gapic/composer/grpc/goldens/EchoClientTest.golden b/src/test/java/com/google/api/generator/gapic/composer/grpc/goldens/EchoClientTest.golden index fe7682e159..ba815b973f 100644 --- a/src/test/java/com/google/api/generator/gapic/composer/grpc/goldens/EchoClientTest.golden +++ b/src/test/java/com/google/api/generator/gapic/composer/grpc/goldens/EchoClientTest.golden @@ -40,8 +40,8 @@ import org.junit.Test; @Generated("by gapic-generator-java") public class EchoClientTest { - private static MockServiceHelper mockServiceHelper; private static MockEcho mockEcho; + private static MockServiceHelper mockServiceHelper; private EchoClient client; private LocalChannelProvider channelProvider; diff --git a/src/test/java/com/google/api/generator/gapic/composer/grpc/goldens/LoggingClientTest.golden b/src/test/java/com/google/api/generator/gapic/composer/grpc/goldens/LoggingClientTest.golden index da4e0e0674..afa0414c65 100644 --- a/src/test/java/com/google/api/generator/gapic/composer/grpc/goldens/LoggingClientTest.golden +++ b/src/test/java/com/google/api/generator/gapic/composer/grpc/goldens/LoggingClientTest.golden @@ -43,8 +43,8 @@ import org.junit.Test; @Generated("by gapic-generator-java") public class LoggingServiceV2ClientTest { - private static MockServiceHelper mockServiceHelper; private static MockLoggingServiceV2 mockLoggingServiceV2; + private static MockServiceHelper mockServiceHelper; private LoggingServiceV2Client client; private LocalChannelProvider channelProvider; diff --git a/src/test/java/com/google/api/generator/gapic/composer/grpc/goldens/SubscriberClientTest.golden b/src/test/java/com/google/api/generator/gapic/composer/grpc/goldens/SubscriberClientTest.golden index 6871486078..941e4d1ea6 100644 --- a/src/test/java/com/google/api/generator/gapic/composer/grpc/goldens/SubscriberClientTest.golden +++ b/src/test/java/com/google/api/generator/gapic/composer/grpc/goldens/SubscriberClientTest.golden @@ -36,8 +36,8 @@ import org.junit.Test; @Generated("by gapic-generator-java") public class SubscriberClientTest { - private static MockServiceHelper mockServiceHelper; private static MockSubscriber mockSubscriber; + private static MockServiceHelper mockServiceHelper; private SubscriberClient client; private LocalChannelProvider channelProvider; diff --git a/src/test/java/com/google/api/generator/gapic/composer/grpc/goldens/TestingClientTest.golden b/src/test/java/com/google/api/generator/gapic/composer/grpc/goldens/TestingClientTest.golden index f0dc05e18a..bb9c3e90b7 100644 --- a/src/test/java/com/google/api/generator/gapic/composer/grpc/goldens/TestingClientTest.golden +++ b/src/test/java/com/google/api/generator/gapic/composer/grpc/goldens/TestingClientTest.golden @@ -31,9 +31,9 @@ import org.junit.Test; @Generated("by gapic-generator-java") public class TestingClientTest { + private static MockTesting mockTesting; private static MockServiceHelper mockServiceHelper; private TestingClient client; - private static MockTesting mockTesting; private LocalChannelProvider channelProvider; @BeforeClass