From 35cc21c3ea5cbd5fd9efcc609f8a1757a7adab2b Mon Sep 17 00:00:00 2001 From: Gabriel Gonzalez Date: Mon, 23 Aug 2021 04:53:10 -0400 Subject: [PATCH 1/9] DIREGAPIC LRO implementation without annotations (#826) * fix ServiceStub Goldens * fix Stub golden * fix Stub golden * fix CallableFactory golden * fix java format * add annotation placement comments * only add machinery to methods that return operation * add grpc file that contained method that was edited on abstract class * update HttpJsonComplianceStub.golden * java format --- WORKSPACE | 2 +- .../AbstractServiceStubClassComposer.java | 16 +- .../grpc/GrpcServiceStubClassComposer.java | 6 +- ...onServiceCallableFactoryClassComposer.java | 131 +++++++- .../HttpJsonServiceStubClassComposer.java | 297 +++++++++++++++++- .../HttpJsonComplianceCallableFactory.golden | 13 +- .../HttpJsonAddressesCallableFactory.java | 12 +- .../v1/stub/HttpJsonAddressesStub.java | 49 +++ ...tpJsonRegionOperationsCallableFactory.java | 12 +- .../v1/stub/HttpJsonRegionOperationsStub.java | 26 ++ 10 files changed, 550 insertions(+), 14 deletions(-) diff --git a/WORKSPACE b/WORKSPACE index 7468b3246d..1b8335256f 100644 --- a/WORKSPACE +++ b/WORKSPACE @@ -32,7 +32,7 @@ jvm_maven_import_external( # gapic-generator-java dependencies to match the order in googleapis repository, # which in its turn, prioritizes actual generated clients runtime dependencies # over the generator dependencies. -_gax_java_version = "1.65.1" +_gax_java_version = "2.2.0" http_archive( name = "com_google_api_gax_java", 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 034c94c949..524f8f6361 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 @@ -52,6 +52,7 @@ 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.Message; import com.google.api.generator.gapic.model.Method; import com.google.api.generator.gapic.model.Service; import com.google.api.generator.gapic.utils.JavaStyle; @@ -159,12 +160,14 @@ public GapicClass generate(GapicContext context, Service service) { .setType(getTransportContext().stubCallableFactoryType()) .build())); + Map messageTypes = context.messages(); List classStatements = createClassStatements( service, protoMethodNameToDescriptorVarExprs, callableClassMemberVarExprs, - classMemberVarExprs); + classMemberVarExprs, + messageTypes); StubCommentComposer commentComposer = new StubCommentComposer(getTransportContext().transportName()); @@ -193,7 +196,7 @@ public GapicClass generate(GapicContext context, Service service) { } protected abstract Statement createMethodDescriptorVariableDecl( - Service service, Method protoMethod, VariableExpr methodDescriptorVarExpr); + Service service, Method protoMethod, VariableExpr methodDescriptorVarExpr, Map messageTypes); protected abstract List createOperationsStubGetterMethod( VariableExpr operationsStubVarExpr); @@ -212,10 +215,11 @@ protected List createClassStatements( Service service, Map protoMethodNameToDescriptorVarExprs, Map callableClassMemberVarExprs, - Map classMemberVarExprs) { + Map classMemberVarExprs, + Map messageTypes) { List classStatements = new ArrayList<>(); for (Statement statement : - createMethodDescriptorVariableDecls(service, protoMethodNameToDescriptorVarExprs)) { + createMethodDescriptorVariableDecls(service, protoMethodNameToDescriptorVarExprs, messageTypes)) { classStatements.add(statement); classStatements.add(EMPTY_LINE_STATEMENT); } @@ -228,12 +232,12 @@ protected List createClassStatements( } protected List createMethodDescriptorVariableDecls( - Service service, Map protoMethodNameToDescriptorVarExprs) { + Service service, Map protoMethodNameToDescriptorVarExprs, Map messageTypes) { return service.methods().stream() .map( m -> createMethodDescriptorVariableDecl( - service, m, protoMethodNameToDescriptorVarExprs.get(m.name()))) + service, m, protoMethodNameToDescriptorVarExprs.get(m.name()), messageTypes)) .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 f079aba780..3fc25a95b2 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 @@ -34,6 +34,7 @@ import com.google.api.generator.gapic.composer.common.AbstractServiceStubClassComposer; import com.google.api.generator.gapic.composer.store.TypeStore; import com.google.api.generator.gapic.model.HttpBindings.HttpBinding; +import com.google.api.generator.gapic.model.Message; import com.google.api.generator.gapic.model.Method; import com.google.api.generator.gapic.model.Service; import com.google.api.generator.gapic.utils.JavaStyle; @@ -85,7 +86,10 @@ private static TypeStore createStaticTypes() { @Override protected Statement createMethodDescriptorVariableDecl( - Service service, Method protoMethod, VariableExpr methodDescriptorVarExpr) { + Service service, + Method protoMethod, + VariableExpr methodDescriptorVarExpr, + Map messageTypes) { MethodInvocationExpr methodDescriptorMaker = MethodInvocationExpr.builder() .setMethodName("newBuilder") diff --git a/src/main/java/com/google/api/generator/gapic/composer/rest/HttpJsonServiceCallableFactoryClassComposer.java b/src/main/java/com/google/api/generator/gapic/composer/rest/HttpJsonServiceCallableFactoryClassComposer.java index f9c4045cb9..191c1d15fa 100644 --- a/src/main/java/com/google/api/generator/gapic/composer/rest/HttpJsonServiceCallableFactoryClassComposer.java +++ b/src/main/java/com/google/api/generator/gapic/composer/rest/HttpJsonServiceCallableFactoryClassComposer.java @@ -16,14 +16,27 @@ import com.google.api.gax.core.BackgroundResource; import com.google.api.gax.httpjson.ApiMessage; +import com.google.api.gax.httpjson.HttpJsonCallableFactory; +import com.google.api.gax.httpjson.HttpJsonOperationSnapshotCallable; +import com.google.api.gax.rpc.OperationCallable; +import com.google.api.gax.rpc.UnaryCallable; 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.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.Statement; import com.google.api.generator.engine.ast.TypeNode; -import com.google.api.generator.engine.ast.ValueExpr; +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.AbstractServiceCallableFactoryClassComposer; import com.google.api.generator.gapic.composer.store.TypeStore; import com.google.api.generator.gapic.model.Service; +import com.google.longrunning.Operation; +import java.util.ArrayList; import java.util.Arrays; import java.util.List; import java.util.stream.Collectors; @@ -90,6 +103,7 @@ protected MethodDefinition createOperationCallableMethod(TypeStore typeStore) { "The surface for long-running operations is not stable yet and may change in the" + " future."); + // Generate generic method without the body MethodDefinition method = createGenericCallableMethod( typeStore, @@ -104,6 +118,119 @@ protected MethodDefinition createOperationCallableMethod(TypeStore typeStore) { .map(n -> (Object) n) .collect(Collectors.toList()), Arrays.asList(betaAnnotation)); - return method.toBuilder().setReturnExpr(ValueExpr.createNullExpr()).build(); + + List createOperationCallableBody = new ArrayList(2); + + List arguments = method.arguments(); + Variable httpJsonCallSettingsVar = arguments.get(0).variable(); + Variable callSettingsVar = arguments.get(1).variable(); + Variable clientContextVar = arguments.get(2).variable(); + Variable operationsStub = arguments.get(3).variable(); + // Generate innerCallable + VariableExpr innerCallableVarExpr = + VariableExpr.builder() + .setVariable( + Variable.builder() + .setName("innerCallable") + .setType( + TypeNode.withReference(ConcreteReference.withClazz(UnaryCallable.class))) + .build()) + .setTemplateObjects(Arrays.asList(requestTemplateName, methodVariantName)) + .build(); + MethodInvocationExpr getInitialCallSettingsExpr = + MethodInvocationExpr.builder() + .setExprReferenceExpr(VariableExpr.withVariable(callSettingsVar)) + .setMethodName("getInitialCallSettings") + .build(); + MethodInvocationExpr createBaseUnaryCallableExpr = + MethodInvocationExpr.builder() + .setStaticReferenceType( + TypeNode.withReference(ConcreteReference.withClazz(HttpJsonCallableFactory.class))) + .setMethodName("createBaseUnaryCallable") + .setArguments( + VariableExpr.withVariable(httpJsonCallSettingsVar), + getInitialCallSettingsExpr, + VariableExpr.withVariable(clientContextVar)) + .setReturnType(TypeNode.withReference(ConcreteReference.withClazz(UnaryCallable.class))) + .build(); + AssignmentExpr innerCallableAssignExpr = + AssignmentExpr.builder() + .setVariableExpr(innerCallableVarExpr.toBuilder().setIsDecl(true).build()) + .setValueExpr(createBaseUnaryCallableExpr) + .build(); + createOperationCallableBody.add(ExprStatement.withExpr(innerCallableAssignExpr)); + + // Generate initialCallable + VariableExpr initialCallableVarExpr = + VariableExpr.builder() + .setVariable( + Variable.builder() + .setName("initialCallable") + .setType( + TypeNode.withReference(ConcreteReference.withClazz(UnaryCallable.class))) + .build()) + .setTemplateObjects(Arrays.asList(requestTemplateName, methodVariantName)) + .build(); + MethodInvocationExpr getMethodDescriptorExpr = + MethodInvocationExpr.builder() + .setExprReferenceExpr(VariableExpr.withVariable(httpJsonCallSettingsVar)) + .setMethodName("getMethodDescriptor") + .build(); + MethodInvocationExpr getOperationSnapshotFactoryExpr = + MethodInvocationExpr.builder() + .setExprReferenceExpr(getMethodDescriptorExpr) + .setMethodName("getOperationSnapshotFactory") + .build(); + // This is a temporary solution + VaporReference requestT = + VaporReference.builder() + .setName("RequestT") + .setPakkage("com.google.cloud.compute.v1.stub") + .build(); + TypeNode operationSnapshotCallableType = + TypeNode.withReference( + ConcreteReference.builder() + .setClazz(HttpJsonOperationSnapshotCallable.class) + .setGenerics(requestT, ConcreteReference.withClazz(Operation.class)) + .build()); + NewObjectExpr initialCallableObject = + NewObjectExpr.builder() + .setType(operationSnapshotCallableType) + .setIsGeneric(true) + .setArguments(innerCallableVarExpr, getOperationSnapshotFactoryExpr) + .build(); + AssignmentExpr initialCallableAssignExpr = + AssignmentExpr.builder() + .setVariableExpr(initialCallableVarExpr.toBuilder().setIsDecl(true).build()) + .setValueExpr(initialCallableObject) + .build(); + createOperationCallableBody.add(ExprStatement.withExpr(initialCallableAssignExpr)); + + // Generate return statement + MethodInvocationExpr longRunningClient = + MethodInvocationExpr.builder() + .setExprReferenceExpr(VariableExpr.withVariable(operationsStub)) + .setMethodName("longRunningClient") + .build(); + MethodInvocationExpr createOperationCallable = + MethodInvocationExpr.builder() + .setStaticReferenceType( + TypeNode.withReference(ConcreteReference.withClazz(HttpJsonCallableFactory.class))) + .setMethodName("createOperationCallable") + .setArguments( + VariableExpr.withVariable(callSettingsVar), + VariableExpr.withVariable(clientContextVar), + longRunningClient, + initialCallableVarExpr) + .setReturnType( + TypeNode.withReference(ConcreteReference.withClazz(OperationCallable.class))) + .build(); + + // Add body and return statement to method + return method + .toBuilder() + .setBody(createOperationCallableBody) + .setReturnExpr(createOperationCallable) + .build(); } } diff --git a/src/main/java/com/google/api/generator/gapic/composer/rest/HttpJsonServiceStubClassComposer.java b/src/main/java/com/google/api/generator/gapic/composer/rest/HttpJsonServiceStubClassComposer.java index 901dceacc6..66fdfb2b4e 100644 --- a/src/main/java/com/google/api/generator/gapic/composer/rest/HttpJsonServiceStubClassComposer.java +++ b/src/main/java/com/google/api/generator/gapic/composer/rest/HttpJsonServiceStubClassComposer.java @@ -19,10 +19,12 @@ 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.HttpJsonOperationSnapshot; 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.gax.longrunning.OperationSnapshot; import com.google.api.generator.engine.ast.AnnotationNode; import com.google.api.generator.engine.ast.AssignmentExpr; import com.google.api.generator.engine.ast.ConcreteReference; @@ -34,16 +36,19 @@ 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.TypeNode; import com.google.api.generator.engine.ast.ValueExpr; +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.AbstractServiceStubClassComposer; import com.google.api.generator.gapic.composer.store.TypeStore; import com.google.api.generator.gapic.model.HttpBindings.HttpBinding; +import com.google.api.generator.gapic.model.Message; import com.google.api.generator.gapic.model.Method; import com.google.api.generator.gapic.model.Service; import com.google.api.generator.gapic.utils.JavaStyle; @@ -91,7 +96,10 @@ private static TypeStore createStaticTypes() { @Override protected Statement createMethodDescriptorVariableDecl( - Service service, Method protoMethod, VariableExpr methodDescriptorVarExpr) { + Service service, + Method protoMethod, + VariableExpr methodDescriptorVarExpr, + Map messageTypes) { MethodInvocationExpr expr = MethodInvocationExpr.builder() .setMethodName("newBuilder") @@ -116,6 +124,22 @@ protected Statement createMethodDescriptorVariableDecl( methodMaker.apply("setRequestFormatter", getRequestFormatterExpr(protoMethod)).apply(expr); expr = methodMaker.apply("setResponseParser", setResponseParserExpr(protoMethod)).apply(expr); + // System.out.println(protoMethod.outputType().reference().simpleName()); + if (protoMethod.outputType().reference().simpleName().equals("Operation")) { + expr = + methodMaker + .apply( + "setOperationSnapshotFactory", + setOperationSnapshotFactoryExpr(protoMethod, messageTypes)) + .apply(expr); + expr = + methodMaker + .apply( + "setPollingRequestFactory", + setPollingRequestFactoryExpr(protoMethod, messageTypes)) + .apply(expr); + } + expr = MethodInvocationExpr.builder() .setMethodName("build") @@ -356,6 +380,277 @@ private List setResponseParserExpr(Method protoMethod) { return Collections.singletonList(expr); } + private List setOperationSnapshotFactoryExpr( + Method protoMethod, Map messageTypes) { + + BiFunction, Function> + methodMaker = getMethodMaker(); + + // Generate input varibles for create() + VariableExpr requestVarExpr = + VariableExpr.withVariable( + Variable.builder().setType(protoMethod.inputType()).setName("request").build()); + VariableExpr responseVarExpr = + VariableExpr.withVariable( + Variable.builder().setType(protoMethod.outputType()).setName("response").build()); + + List createBody = new ArrayList(4); + + // Generate opName + // This will be replaced and edited based on annotations + TypeNode stringBuilderType = + TypeNode.withReference(ConcreteReference.withClazz(StringBuilder.class)); + VariableExpr opNameVarExpr = + VariableExpr.withVariable( + Variable.builder().setType(stringBuilderType).setName("opName").build()); + MethodInvocationExpr getId = + MethodInvocationExpr.builder() + .setMethodName("getId") + .setExprReferenceExpr(responseVarExpr) + .build(); + Expr opNameObjectExpr = + NewObjectExpr.builder().setType(stringBuilderType).setArguments(getId).build(); + AssignmentExpr opNameAssignExpr = + AssignmentExpr.builder() + .setVariableExpr(opNameVarExpr.toBuilder().setIsDecl(true).build()) + .setValueExpr(opNameObjectExpr) + .build(); + createBody.add(ExprStatement.withExpr(opNameAssignExpr)); + + // Generate changes opName + // This will be replaced and edited based on annotations + MethodInvocationExpr requestGetProjectExpr = + MethodInvocationExpr.builder() + .setMethodName("getProject") + .setExprReferenceExpr(requestVarExpr) + .build(); + ValueExpr colonValueExpr = + ValueExpr.builder().setValue(StringObjectValue.builder().setValue(":").build()).build(); + MethodInvocationExpr opNameAppendColonProjectExpr = + MethodInvocationExpr.builder() + .setMethodName("append") + .setArguments(colonValueExpr) + .setExprReferenceExpr(opNameVarExpr) + .build(); + opNameAppendColonProjectExpr = + methodMaker + .apply("append", Collections.singletonList(requestGetProjectExpr)) + .apply(opNameAppendColonProjectExpr); + createBody.add(ExprStatement.withExpr(opNameAppendColonProjectExpr)); + + // Generate changes to opName + MethodInvocationExpr requestGetRegionExpr = + MethodInvocationExpr.builder() + .setMethodName("getRegion") + .setExprReferenceExpr(requestVarExpr) + .build(); + MethodInvocationExpr opNameAppendColonRegionExpr = + MethodInvocationExpr.builder() + .setMethodName("append") + .setArguments(colonValueExpr) + .setExprReferenceExpr(opNameVarExpr) + .build(); + opNameAppendColonRegionExpr = + methodMaker + .apply("append", Collections.singletonList(requestGetRegionExpr)) + .apply(opNameAppendColonRegionExpr); + createBody.add(ExprStatement.withExpr(opNameAppendColonRegionExpr)); + + // Generate check status expression + // This will be replaced and edited based on annotations + MethodInvocationExpr getStatusExpr = + MethodInvocationExpr.builder() + .setExprReferenceExpr(responseVarExpr) + .setMethodName("getStatus") + .build(); + TypeNode statusType = + TypeNode.withReference( + VaporReference.builder() + .setName("Status") + .setPakkage("com.google.cloud.compute.v1") + .setIsStaticImport(false) + .build()); + VariableExpr statusDoneExpr = + VariableExpr.builder() + .setVariable(Variable.builder().setName("DONE").setType(TypeNode.INT).build()) + .setStaticReferenceType(statusType) + .build(); + MethodInvocationExpr statusEqualsExpr = + methodMaker.apply("equals", Collections.singletonList(statusDoneExpr)).apply(getStatusExpr); + + // Generate return statement + TypeNode httpJsonOperationSnapshotType = + TypeNode.withReference(ConcreteReference.withClazz(HttpJsonOperationSnapshot.class)); + MethodInvocationExpr newBuilderExpr = + MethodInvocationExpr.builder() + .setStaticReferenceType(httpJsonOperationSnapshotType) + .setMethodName("newBuilder") + .build(); + MethodInvocationExpr opNameToStringExpr = + MethodInvocationExpr.builder() + .setMethodName("toString") + .setExprReferenceExpr(opNameVarExpr) + .build(); + // This will be replaced and edited based on annotations + MethodInvocationExpr getHttpErrorStatusCodeExpr = + MethodInvocationExpr.builder() + .setExprReferenceExpr(responseVarExpr) + .setMethodName("getHttpErrorStatusCode") + .build(); + // This will be replaced and edited based on annotations + MethodInvocationExpr getHttpErrorMessageExpr = + MethodInvocationExpr.builder() + .setExprReferenceExpr(responseVarExpr) + .setMethodName("getHttpErrorMessage") + .build(); + newBuilderExpr = + methodMaker + .apply("setName", Collections.singletonList(opNameToStringExpr)) + .apply(newBuilderExpr); + newBuilderExpr = + methodMaker + .apply("setMetadata", Collections.singletonList(responseVarExpr)) + .apply(newBuilderExpr); + newBuilderExpr = + methodMaker + .apply("setDone", Collections.singletonList(statusEqualsExpr)) + .apply(newBuilderExpr); + newBuilderExpr = + methodMaker + .apply("setResponse", Collections.singletonList(responseVarExpr)) + .apply(newBuilderExpr); + newBuilderExpr = + methodMaker + .apply("setError", Arrays.asList(getHttpErrorStatusCodeExpr, getHttpErrorMessageExpr)) + .apply(newBuilderExpr); + TypeNode operationSnapshotType = + TypeNode.withReference( + ConcreteReference.builder().setClazz(OperationSnapshot.class).build()); + MethodInvocationExpr buildExpr = + MethodInvocationExpr.builder() + .setExprReferenceExpr(newBuilderExpr) + .setMethodName("build") + .setReturnType(operationSnapshotType) + .build(); + + // Generate lambda anonymous class + return Collections.singletonList( + LambdaExpr.builder() + .setArguments( + requestVarExpr.toBuilder().setIsDecl(true).build(), + responseVarExpr.toBuilder().setIsDecl(true).build()) + .setBody(createBody) + .setReturnExpr(buildExpr) + .build()); + } + + private List setPollingRequestFactoryExpr( + Method protoMethod, Map messageTypes) { + + BiFunction, Function> + methodMaker = getMethodMaker(); + + List createBody = new ArrayList(1); + + // Generate input variables for create + VariableExpr compoundOperationIdVarExpr = + VariableExpr.builder() + .setVariable( + Variable.builder().setType(TypeNode.STRING).setName("compoundOperationId").build()) + .build(); + + // Generate idComponenets + TypeNode listStringType = + TypeNode.withReference( + ConcreteReference.builder() + .setClazz(List.class) + .setGenerics(ConcreteReference.withClazz(String.class)) + .build()); + TypeNode arrayListStringType = + TypeNode.withReference( + ConcreteReference.builder() + .setClazz(ArrayList.class) + .setGenerics(ConcreteReference.withClazz(String.class)) + .build()); + TypeNode arraysType = TypeNode.withReference(ConcreteReference.withClazz(Arrays.class)); + VariableExpr idComponentsVarExpr = + VariableExpr.withVariable( + Variable.builder().setName("idComponents").setType(listStringType).build()); + MethodInvocationExpr compoundOperationIdSplitExpr = + MethodInvocationExpr.builder() + .setExprReferenceExpr(compoundOperationIdVarExpr) + .setMethodName("split") + .setArguments(ValueExpr.withValue(StringObjectValue.withValue(":"))) + .setReturnType(arrayListStringType) + .build(); + MethodInvocationExpr asListExpr = + MethodInvocationExpr.builder() + .setStaticReferenceType(arraysType) + .setMethodName("asList") + .setArguments(compoundOperationIdSplitExpr) + .setReturnType(arrayListStringType) + .build(); + AssignmentExpr idComponentsAssignExpr = + AssignmentExpr.builder() + .setVariableExpr(idComponentsVarExpr.toBuilder().setIsDecl(true).build()) + .setValueExpr(asListExpr) + .build(); + createBody.add(ExprStatement.withExpr(idComponentsAssignExpr)); + + // Generate return statement + // This will be replaced and edited based on annotations + TypeNode getRegionOperationRequestType = + TypeNode.withReference( + VaporReference.builder() + .setName("GetRegionOperationRequest") + .setPakkage("com.google.cloud.compute.v1") + .setIsStaticImport(false) + .build()); + MethodInvocationExpr newBuilderExpr = + MethodInvocationExpr.builder() + .setStaticReferenceType(getRegionOperationRequestType) + .setMethodName("newBuilder") + .build(); + newBuilderExpr = + methodMaker + .apply("setOperation", Collections.singletonList(getExpr(idComponentsVarExpr, "0"))) + .apply(newBuilderExpr); + newBuilderExpr = + methodMaker + .apply("setProject", Collections.singletonList(getExpr(idComponentsVarExpr, "1"))) + .apply(newBuilderExpr); + newBuilderExpr = + methodMaker + .apply("setRegion", Collections.singletonList(getExpr(idComponentsVarExpr, "2"))) + .apply(newBuilderExpr); + MethodInvocationExpr buildExpr = + MethodInvocationExpr.builder() + .setExprReferenceExpr(newBuilderExpr) + .setMethodName("build") + .setReturnType(getRegionOperationRequestType) + .build(); + + // Return lambda anonymous class + return Collections.singletonList( + LambdaExpr.builder() + .setArguments(compoundOperationIdVarExpr.toBuilder().setIsDecl(true).build()) + .setBody(createBody) + .setReturnExpr(buildExpr) + .build()); + } + + // returns var.get(num); + private MethodInvocationExpr getExpr(VariableExpr var, String num) { + return MethodInvocationExpr.builder() + .setExprReferenceExpr(var) + .setMethodName("get") + .setArguments( + ValueExpr.builder() + .setValue(PrimitiveValue.builder().setValue(num).setType(TypeNode.INT).build()) + .build()) + .build(); + } + private Expr createFieldsExtractorClassInstance( Method method, TypeNode extractorReturnType, diff --git a/src/test/java/com/google/api/generator/gapic/composer/rest/goldens/HttpJsonComplianceCallableFactory.golden b/src/test/java/com/google/api/generator/gapic/composer/rest/goldens/HttpJsonComplianceCallableFactory.golden index 7d6032778d..0b58310417 100644 --- a/src/test/java/com/google/api/generator/gapic/composer/rest/goldens/HttpJsonComplianceCallableFactory.golden +++ b/src/test/java/com/google/api/generator/gapic/composer/rest/goldens/HttpJsonComplianceCallableFactory.golden @@ -5,6 +5,7 @@ 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.HttpJsonOperationSnapshotCallable; import com.google.api.gax.httpjson.HttpJsonStubCallableFactory; import com.google.api.gax.rpc.BatchingCallSettings; import com.google.api.gax.rpc.ClientContext; @@ -13,6 +14,8 @@ import com.google.api.gax.rpc.OperationCallable; import com.google.api.gax.rpc.PagedCallSettings; import com.google.api.gax.rpc.UnaryCallSettings; import com.google.api.gax.rpc.UnaryCallable; +import com.google.cloud.compute.v1.stub.RequestT; +import com.google.longrunning.Operation; import javax.annotation.Generated; // AUTO-GENERATED DOCUMENTATION AND CLASS. @@ -63,6 +66,14 @@ public class HttpJsonComplianceCallableFactory OperationCallSettings callSettings, ClientContext clientContext, BackgroundResource operationsStub) { - return null; + UnaryCallable innerCallable = + HttpJsonCallableFactory.createBaseUnaryCallable( + httpJsonCallSettings, callSettings.getInitialCallSettings(), clientContext); + UnaryCallable initialCallable = + new HttpJsonOperationSnapshotCallable( + innerCallable, + httpJsonCallSettings.getMethodDescriptor().getOperationSnapshotFactory()); + return HttpJsonCallableFactory.createOperationCallable( + callSettings, clientContext, operationsStub.longRunningClient(), initialCallable); } } diff --git a/test/integration/goldens/compute/com/google/cloud/compute/v1/stub/HttpJsonAddressesCallableFactory.java b/test/integration/goldens/compute/com/google/cloud/compute/v1/stub/HttpJsonAddressesCallableFactory.java index afa275a6f5..49347e5792 100644 --- a/test/integration/goldens/compute/com/google/cloud/compute/v1/stub/HttpJsonAddressesCallableFactory.java +++ b/test/integration/goldens/compute/com/google/cloud/compute/v1/stub/HttpJsonAddressesCallableFactory.java @@ -21,6 +21,7 @@ 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.HttpJsonOperationSnapshotCallable; import com.google.api.gax.httpjson.HttpJsonStubCallableFactory; import com.google.api.gax.rpc.BatchingCallSettings; import com.google.api.gax.rpc.ClientContext; @@ -29,6 +30,7 @@ import com.google.api.gax.rpc.PagedCallSettings; import com.google.api.gax.rpc.UnaryCallSettings; import com.google.api.gax.rpc.UnaryCallable; +import com.google.longrunning.Operation; import javax.annotation.Generated; // AUTO-GENERATED DOCUMENTATION AND CLASS. @@ -79,6 +81,14 @@ OperationCallable createOperationCallable( OperationCallSettings callSettings, ClientContext clientContext, BackgroundResource operationsStub) { - return null; + UnaryCallable innerCallable = + HttpJsonCallableFactory.createBaseUnaryCallable( + httpJsonCallSettings, callSettings.getInitialCallSettings(), clientContext); + UnaryCallable initialCallable = + new HttpJsonOperationSnapshotCallable( + innerCallable, + httpJsonCallSettings.getMethodDescriptor().getOperationSnapshotFactory()); + return HttpJsonCallableFactory.createOperationCallable( + callSettings, clientContext, operationsStub.longRunningClient(), initialCallable); } } diff --git a/test/integration/goldens/compute/com/google/cloud/compute/v1/stub/HttpJsonAddressesStub.java b/test/integration/goldens/compute/com/google/cloud/compute/v1/stub/HttpJsonAddressesStub.java index d8d960d342..e2d4a26060 100644 --- a/test/integration/goldens/compute/com/google/cloud/compute/v1/stub/HttpJsonAddressesStub.java +++ b/test/integration/goldens/compute/com/google/cloud/compute/v1/stub/HttpJsonAddressesStub.java @@ -26,21 +26,26 @@ import com.google.api.gax.core.BackgroundResourceAggregation; import com.google.api.gax.httpjson.ApiMethodDescriptor; import com.google.api.gax.httpjson.HttpJsonCallSettings; +import com.google.api.gax.httpjson.HttpJsonOperationSnapshot; 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.gax.longrunning.OperationSnapshot; import com.google.api.gax.rpc.ClientContext; import com.google.api.gax.rpc.UnaryCallable; import com.google.cloud.compute.v1.AddressAggregatedList; import com.google.cloud.compute.v1.AddressList; import com.google.cloud.compute.v1.AggregatedListAddressesRequest; import com.google.cloud.compute.v1.DeleteAddressRequest; +import com.google.cloud.compute.v1.GetRegionOperationRequest; import com.google.cloud.compute.v1.InsertAddressRequest; import com.google.cloud.compute.v1.ListAddressesRequest; import com.google.cloud.compute.v1.Operation; +import com.google.cloud.compute.v1.Status; import java.io.IOException; import java.util.ArrayList; +import java.util.Arrays; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -137,6 +142,28 @@ public class HttpJsonAddressesStub extends AddressesStub { ProtoMessageResponseParser.newBuilder() .setDefaultInstance(Operation.getDefaultInstance()) .build()) + .setOperationSnapshotFactory( + (DeleteAddressRequest request, Operation response) -> { + StringBuilder opName = new StringBuilder(response.getId()); + opName.append(":").append(request.getProject()); + opName.append(":").append(request.getRegion()); + return HttpJsonOperationSnapshot.newBuilder() + .setName(opName.toString()) + .setMetadata(response) + .setDone(response.getStatus().equals(Status.DONE)) + .setResponse(response) + .setError(response.getHttpErrorStatusCode(), response.getHttpErrorMessage()) + .build(); + }) + .setPollingRequestFactory( + compoundOperationId -> { + List idComponents = Arrays.asList(compoundOperationId.split(":")); + return GetRegionOperationRequest.newBuilder() + .setOperation(idComponents.get(0)) + .setProject(idComponents.get(1)) + .setRegion(idComponents.get(2)) + .build(); + }) .build(); private static final ApiMethodDescriptor insertMethodDescriptor = @@ -174,6 +201,28 @@ public class HttpJsonAddressesStub extends AddressesStub { ProtoMessageResponseParser.newBuilder() .setDefaultInstance(Operation.getDefaultInstance()) .build()) + .setOperationSnapshotFactory( + (InsertAddressRequest request, Operation response) -> { + StringBuilder opName = new StringBuilder(response.getId()); + opName.append(":").append(request.getProject()); + opName.append(":").append(request.getRegion()); + return HttpJsonOperationSnapshot.newBuilder() + .setName(opName.toString()) + .setMetadata(response) + .setDone(response.getStatus().equals(Status.DONE)) + .setResponse(response) + .setError(response.getHttpErrorStatusCode(), response.getHttpErrorMessage()) + .build(); + }) + .setPollingRequestFactory( + compoundOperationId -> { + List idComponents = Arrays.asList(compoundOperationId.split(":")); + return GetRegionOperationRequest.newBuilder() + .setOperation(idComponents.get(0)) + .setProject(idComponents.get(1)) + .setRegion(idComponents.get(2)) + .build(); + }) .build(); private static final ApiMethodDescriptor listMethodDescriptor = diff --git a/test/integration/goldens/compute/com/google/cloud/compute/v1/stub/HttpJsonRegionOperationsCallableFactory.java b/test/integration/goldens/compute/com/google/cloud/compute/v1/stub/HttpJsonRegionOperationsCallableFactory.java index 6dac14a84e..6113b5f496 100644 --- a/test/integration/goldens/compute/com/google/cloud/compute/v1/stub/HttpJsonRegionOperationsCallableFactory.java +++ b/test/integration/goldens/compute/com/google/cloud/compute/v1/stub/HttpJsonRegionOperationsCallableFactory.java @@ -21,6 +21,7 @@ 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.HttpJsonOperationSnapshotCallable; import com.google.api.gax.httpjson.HttpJsonStubCallableFactory; import com.google.api.gax.rpc.BatchingCallSettings; import com.google.api.gax.rpc.ClientContext; @@ -29,6 +30,7 @@ import com.google.api.gax.rpc.PagedCallSettings; import com.google.api.gax.rpc.UnaryCallSettings; import com.google.api.gax.rpc.UnaryCallable; +import com.google.longrunning.Operation; import javax.annotation.Generated; // AUTO-GENERATED DOCUMENTATION AND CLASS. @@ -79,6 +81,14 @@ OperationCallable createOperationCallable( OperationCallSettings callSettings, ClientContext clientContext, BackgroundResource operationsStub) { - return null; + UnaryCallable innerCallable = + HttpJsonCallableFactory.createBaseUnaryCallable( + httpJsonCallSettings, callSettings.getInitialCallSettings(), clientContext); + UnaryCallable initialCallable = + new HttpJsonOperationSnapshotCallable( + innerCallable, + httpJsonCallSettings.getMethodDescriptor().getOperationSnapshotFactory()); + return HttpJsonCallableFactory.createOperationCallable( + callSettings, clientContext, operationsStub.longRunningClient(), initialCallable); } } diff --git a/test/integration/goldens/compute/com/google/cloud/compute/v1/stub/HttpJsonRegionOperationsStub.java b/test/integration/goldens/compute/com/google/cloud/compute/v1/stub/HttpJsonRegionOperationsStub.java index 9d90915792..47bc6a36a7 100644 --- a/test/integration/goldens/compute/com/google/cloud/compute/v1/stub/HttpJsonRegionOperationsStub.java +++ b/test/integration/goldens/compute/com/google/cloud/compute/v1/stub/HttpJsonRegionOperationsStub.java @@ -23,16 +23,20 @@ import com.google.api.gax.core.BackgroundResourceAggregation; import com.google.api.gax.httpjson.ApiMethodDescriptor; import com.google.api.gax.httpjson.HttpJsonCallSettings; +import com.google.api.gax.httpjson.HttpJsonOperationSnapshot; 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.gax.longrunning.OperationSnapshot; import com.google.api.gax.rpc.ClientContext; import com.google.api.gax.rpc.UnaryCallable; import com.google.cloud.compute.v1.GetRegionOperationRequest; import com.google.cloud.compute.v1.Operation; +import com.google.cloud.compute.v1.Status; import java.io.IOException; import java.util.ArrayList; +import java.util.Arrays; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -79,6 +83,28 @@ public class HttpJsonRegionOperationsStub extends RegionOperationsStub { ProtoMessageResponseParser.newBuilder() .setDefaultInstance(Operation.getDefaultInstance()) .build()) + .setOperationSnapshotFactory( + (GetRegionOperationRequest request, Operation response) -> { + StringBuilder opName = new StringBuilder(response.getId()); + opName.append(":").append(request.getProject()); + opName.append(":").append(request.getRegion()); + return HttpJsonOperationSnapshot.newBuilder() + .setName(opName.toString()) + .setMetadata(response) + .setDone(response.getStatus().equals(Status.DONE)) + .setResponse(response) + .setError(response.getHttpErrorStatusCode(), response.getHttpErrorMessage()) + .build(); + }) + .setPollingRequestFactory( + compoundOperationId -> { + List idComponents = Arrays.asList(compoundOperationId.split(":")); + return GetRegionOperationRequest.newBuilder() + .setOperation(idComponents.get(0)) + .setProject(idComponents.get(1)) + .setRegion(idComponents.get(2)) + .build(); + }) .build(); private final UnaryCallable getCallable; From 00d94ed6a15d9f75874691ffc875df6f1af223e3 Mon Sep 17 00:00:00 2001 From: Vadym Matsishevskyi <25311427+vam-google@users.noreply.github.com> Date: Tue, 24 Aug 2021 01:02:39 -0700 Subject: [PATCH 2/9] Diregapic lro (#828) * feat: enable self signed jwt for gapic clients (#794) * feat: enable self signed jwt for gapic clients * resolve comments * update gax version * update goldens * update golden files * chore: release 2.1.0 (#827) Co-authored-by: release-please[bot] <55107282+release-please[bot]@users.noreply.github.com> * ingegrate with latest googleapis and googleapis-discovery * ingegrate with latest googleapis and googleapis-discovery Co-authored-by: arithmetic1728 <58957152+arithmetic1728@users.noreply.github.com> Co-authored-by: release-please[bot] <55107282+release-please[bot]@users.noreply.github.com> --- CHANGELOG.md | 7 ++ WORKSPACE | 2 +- repositories.bzl | 10 ++- .../java/com/google/api/generator/BUILD.bazel | 1 + .../google/api/generator/ProtoRegistry.java | 2 + ...tractServiceStubSettingsClassComposer.java | 60 +++++++------ .../ServiceStubSettingsClassComposer.java | 43 +++++++++ .../DeprecatedServiceStubSettings.golden | 4 +- .../grpc/goldens/EchoStubSettings.golden | 4 +- .../LoggingServiceV2StubSettings.golden | 4 +- .../grpc/goldens/PublisherStubSettings.golden | 4 +- .../cloud/asset/v1/AssetServiceClient.java | 88 ++++++++++++++++--- .../asset/v1/AssetServiceClientTest.java | 58 ++++++++++++ .../cloud/asset/v1/AssetServiceSettings.java | 15 +++- .../cloud/asset/v1/MockAssetServiceImpl.java | 21 +++++ .../google/cloud/asset/v1/gapic_metadata.json | 3 + .../google/cloud/asset/v1/package-info.java | 1 + .../cloud/asset/v1/stub/AssetServiceStub.java | 9 +- .../v1/stub/AssetServiceStubSettings.java | 48 ++++++++-- .../asset/v1/stub/GrpcAssetServiceStub.java | 36 +++++++- .../cloud/compute/v1/AddressesClientTest.java | 8 +- .../v1/RegionOperationsClientTest.java | 4 +- .../v1/stub/IamCredentialsStubSettings.java | 4 +- .../iam/v1/stub/IAMPolicyStubSettings.java | 4 +- .../KeyManagementServiceStubSettings.java | 4 +- .../v1/stub/LibraryServiceStubSettings.java | 4 +- .../v2/stub/ConfigServiceV2StubSettings.java | 4 +- .../v2/stub/LoggingServiceV2StubSettings.java | 4 +- .../v2/stub/MetricsServiceV2StubSettings.java | 4 +- .../pubsub/v1/SubscriptionAdminClient.java | 2 + .../v1/SubscriptionAdminClientTest.java | 7 ++ .../cloud/pubsub/v1/TopicAdminClient.java | 2 + .../cloud/pubsub/v1/TopicAdminClientTest.java | 6 ++ .../pubsub/v1/stub/PublisherStubSettings.java | 4 +- .../v1/stub/SchemaServiceStubSettings.java | 4 +- .../v1/stub/SubscriberStubSettings.java | 4 +- .../v1beta1/stub/CloudRedisStubSettings.java | 4 +- .../storage/v2/stub/StorageStubSettings.java | 4 +- version.txt | 2 +- 39 files changed, 418 insertions(+), 81 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5679cf07f3..47548ec096 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,12 @@ # Changelog +## [2.1.0](https://www.github.com/googleapis/gapic-generator-java/compare/v2.0.1...v2.1.0) (2021-08-17) + + +### Features + +* enable self signed jwt for gapic clients ([#794](https://www.github.com/googleapis/gapic-generator-java/issues/794)) ([1b7ee1e](https://www.github.com/googleapis/gapic-generator-java/commit/1b7ee1e3911e1c8ecab9a94d68d7a59b437d2449)) + ### [2.0.1](https://www.github.com/googleapis/gapic-generator-java/compare/v2.0.0...v2.0.1) (2021-08-06) diff --git a/WORKSPACE b/WORKSPACE index 1b8335256f..21e5f8ea67 100644 --- a/WORKSPACE +++ b/WORKSPACE @@ -32,7 +32,7 @@ jvm_maven_import_external( # gapic-generator-java dependencies to match the order in googleapis repository, # which in its turn, prioritizes actual generated clients runtime dependencies # over the generator dependencies. -_gax_java_version = "2.2.0" +_gax_java_version = "2.3.0" http_archive( name = "com_google_api_gax_java", diff --git a/repositories.bzl b/repositories.bzl index 67493dba45..f2074f578d 100644 --- a/repositories.bzl +++ b/repositories.bzl @@ -59,18 +59,20 @@ def gapic_generator_java_repositories(): _maybe( http_archive, name = "com_google_googleapis", - strip_prefix = "googleapis-efecdbf96311bb705d619459280ffc651b10844a", + strip_prefix = "googleapis-ba30d8097582039ac4cc4e21b4e4baa426423075", urls = [ - "https://github.com/googleapis/googleapis/archive/efecdbf96311bb705d619459280ffc651b10844a.zip", + "https://github.com/googleapis/googleapis/archive/ba30d8097582039ac4cc4e21b4e4baa426423075.zip", ], ) + # TODO: replace with upstream googleapis-discovery link once + # https://github.com/googleapis/googleapis-discovery/pull/59 is merged _maybe( http_archive, name = "com_google_googleapis_discovery", - strip_prefix = "googleapis-discovery-abf4cec1ce9e02e4d7d650bf66137c347cdd0d44", + strip_prefix = "googleapis-discovery-2872d382ff767518e63d59ececf5d6f9224b21b4", urls = [ - "https://github.com/googleapis/googleapis-discovery/archive/abf4cec1ce9e02e4d7d650bf66137c347cdd0d44.zip", + "https://github.com/vam-google/googleapis-discovery/archive/2872d382ff767518e63d59ececf5d6f9224b21b4.zip", ], ) diff --git a/src/main/java/com/google/api/generator/BUILD.bazel b/src/main/java/com/google/api/generator/BUILD.bazel index de7f95f193..4e678b5b7d 100644 --- a/src/main/java/com/google/api/generator/BUILD.bazel +++ b/src/main/java/com/google/api/generator/BUILD.bazel @@ -39,6 +39,7 @@ java_library( "//src/main/java/com/google/api/generator/gapic/model", "//src/main/java/com/google/api/generator/util", "@com_google_googleapis//google/api:api_java_proto", + "@com_google_googleapis//google/cloud:extended_operations_java_proto", "@com_google_googleapis//google/longrunning:longrunning_java_proto", "@com_google_guava_guava//jar", "@com_google_protobuf//:protobuf_java", diff --git a/src/main/java/com/google/api/generator/ProtoRegistry.java b/src/main/java/com/google/api/generator/ProtoRegistry.java index da4806bba0..d4cce56dcf 100644 --- a/src/main/java/com/google/api/generator/ProtoRegistry.java +++ b/src/main/java/com/google/api/generator/ProtoRegistry.java @@ -18,6 +18,7 @@ import com.google.api.ClientProto; import com.google.api.FieldBehaviorProto; import com.google.api.ResourceProto; +import com.google.cloud.ExtendedOperationsProto; import com.google.longrunning.OperationsProto; import com.google.protobuf.ExtensionRegistry; @@ -29,5 +30,6 @@ public static void registerAllExtensions(ExtensionRegistry extensionRegistry) { ClientProto.registerAllExtensions(extensionRegistry); ResourceProto.registerAllExtensions(extensionRegistry); FieldBehaviorProto.registerAllExtensions(extensionRegistry); + ExtendedOperationsProto.registerAllExtensions(extensionRegistry); } } 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 1d89768a58..c999fccb9d 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 @@ -139,8 +139,6 @@ public abstract class AbstractServiceStubSettingsClassComposer implements ClassC 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 = @@ -150,6 +148,9 @@ public abstract class AbstractServiceStubSettingsClassComposer implements ClassC private final TransportContext transportContext; + protected static final VariableExpr DEFAULT_SERVICE_SCOPES_VAR_EXPR = + createDefaultServiceScopesVarExpr(); + protected AbstractServiceStubSettingsClassComposer(TransportContext transportContext) { this.transportContext = transportContext; } @@ -197,6 +198,33 @@ public GapicClass generate(GapicContext context, Service service) { return GapicClass.create(GapicClass.Kind.STUB, classDef); } + protected MethodDefinition createDefaultCredentialsProviderBuilderMethod() { + TypeNode returnType = + TypeNode.withReference( + ConcreteReference.withClazz(GoogleCredentialsProvider.Builder.class)); + MethodInvocationExpr credsProviderBuilderExpr = + MethodInvocationExpr.builder() + .setStaticReferenceType(FIXED_TYPESTORE.get("GoogleCredentialsProvider")) + .setMethodName("newBuilder") + .build(); + credsProviderBuilderExpr = + MethodInvocationExpr.builder() + .setExprReferenceExpr(credsProviderBuilderExpr) + .setMethodName("setScopesToApply") + .setArguments(DEFAULT_SERVICE_SCOPES_VAR_EXPR) + .setReturnType(returnType) + .build(); + return MethodDefinition.builder() + .setHeaderCommentStatements( + SettingsCommentComposer.DEFAULT_CREDENTIALS_PROVIDER_BUILDER_METHOD_COMMENT) + .setScope(ScopeNode.PUBLIC) + .setIsStatic(true) + .setReturnType(returnType) + .setName("defaultCredentialsProviderBuilder") + .setReturnExpr(credsProviderBuilderExpr) + .build(); + } + protected abstract MethodDefinition createDefaultTransportTransportProviderBuilderMethod(); protected abstract MethodDefinition createDefaultApiClientHeaderProviderBuilderMethod( @@ -992,33 +1020,7 @@ private List createDefaultHelperAndGetterMethods( .setReturnExpr(DEFAULT_SERVICE_SCOPES_VAR_EXPR) .build()); - // Create the defaultCredentialsProviderBuilder method. - returnType = - TypeNode.withReference( - ConcreteReference.withClazz(GoogleCredentialsProvider.Builder.class)); - MethodInvocationExpr credsProviderBuilderExpr = - MethodInvocationExpr.builder() - .setStaticReferenceType(FIXED_TYPESTORE.get("GoogleCredentialsProvider")) - .setMethodName("newBuilder") - .build(); - credsProviderBuilderExpr = - MethodInvocationExpr.builder() - .setExprReferenceExpr(credsProviderBuilderExpr) - .setMethodName("setScopesToApply") - .setArguments(DEFAULT_SERVICE_SCOPES_VAR_EXPR) - .setReturnType(returnType) - .build(); - javaMethods.add( - MethodDefinition.builder() - .setHeaderCommentStatements( - SettingsCommentComposer.DEFAULT_CREDENTIALS_PROVIDER_BUILDER_METHOD_COMMENT) - .setScope(ScopeNode.PUBLIC) - .setIsStatic(true) - .setReturnType(returnType) - .setName("defaultCredentialsProviderBuilder") - .setReturnExpr(credsProviderBuilderExpr) - .build()); - + javaMethods.add(createDefaultCredentialsProviderBuilderMethod()); javaMethods.add(createDefaultTransportTransportProviderBuilderMethod()); javaMethods.add(createDefaultTransportChannelProviderMethod()); javaMethods.add(createDefaultApiClientHeaderProviderBuilderMethod(service, 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 index ceba11ee62..6d0b8e221d 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 @@ -14,6 +14,7 @@ package com.google.api.generator.gapic.composer.grpc; +import com.google.api.gax.core.GoogleCredentialsProvider; import com.google.api.gax.grpc.GaxGrpcProperties; import com.google.api.gax.grpc.GrpcTransportChannel; import com.google.api.gax.grpc.InstantiatingGrpcChannelProvider; @@ -22,6 +23,7 @@ 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.PrimitiveValue; import com.google.api.generator.engine.ast.ScopeNode; import com.google.api.generator.engine.ast.StringObjectValue; import com.google.api.generator.engine.ast.TypeNode; @@ -94,6 +96,47 @@ protected MethodDefinition createDefaultTransportTransportProviderBuilderMethod( .build(); } + @Override + protected MethodDefinition createDefaultCredentialsProviderBuilderMethod() { + TypeNode returnType = + TypeNode.withReference( + ConcreteReference.withClazz(GoogleCredentialsProvider.Builder.class)); + MethodInvocationExpr credsProviderBuilderExpr = + MethodInvocationExpr.builder() + .setStaticReferenceType(FIXED_TYPESTORE.get("GoogleCredentialsProvider")) + .setMethodName("newBuilder") + .build(); + credsProviderBuilderExpr = + MethodInvocationExpr.builder() + .setExprReferenceExpr(credsProviderBuilderExpr) + .setMethodName("setScopesToApply") + .setArguments(DEFAULT_SERVICE_SCOPES_VAR_EXPR) + .setReturnType(returnType) + .build(); + + // This section is specific to GAPIC clients. It sets UseJwtAccessWithScope value to true to + // enable self signed JWT feature. + credsProviderBuilderExpr = + MethodInvocationExpr.builder() + .setExprReferenceExpr(credsProviderBuilderExpr) + .setMethodName("setUseJwtAccessWithScope") + .setArguments( + ValueExpr.withValue( + PrimitiveValue.builder().setType(TypeNode.BOOLEAN).setValue("true").build())) + .setReturnType(returnType) + .build(); + + return MethodDefinition.builder() + .setHeaderCommentStatements( + SettingsCommentComposer.DEFAULT_CREDENTIALS_PROVIDER_BUILDER_METHOD_COMMENT) + .setScope(ScopeNode.PUBLIC) + .setIsStatic(true) + .setReturnType(returnType) + .setName("defaultCredentialsProviderBuilder") + .setReturnExpr(credsProviderBuilderExpr) + .build(); + } + @Override protected MethodDefinition createDefaultApiClientHeaderProviderBuilderMethod( Service service, TypeStore typeStore) { diff --git a/src/test/java/com/google/api/generator/gapic/composer/grpc/goldens/DeprecatedServiceStubSettings.golden b/src/test/java/com/google/api/generator/gapic/composer/grpc/goldens/DeprecatedServiceStubSettings.golden index ddfdcde395..899b03bbce 100644 --- a/src/test/java/com/google/api/generator/gapic/composer/grpc/goldens/DeprecatedServiceStubSettings.golden +++ b/src/test/java/com/google/api/generator/gapic/composer/grpc/goldens/DeprecatedServiceStubSettings.golden @@ -120,7 +120,9 @@ public class DeprecatedServiceStubSettings extends StubSettings { /** Returns a builder for the default credentials for this service. */ public static GoogleCredentialsProvider.Builder defaultCredentialsProviderBuilder() { - return GoogleCredentialsProvider.newBuilder().setScopesToApply(DEFAULT_SERVICE_SCOPES); + return GoogleCredentialsProvider.newBuilder() + .setScopesToApply(DEFAULT_SERVICE_SCOPES) + .setUseJwtAccessWithScope(true); } /** Returns a builder for the default ChannelProvider for this service. */ diff --git a/src/test/java/com/google/api/generator/gapic/composer/grpc/goldens/LoggingServiceV2StubSettings.golden b/src/test/java/com/google/api/generator/gapic/composer/grpc/goldens/LoggingServiceV2StubSettings.golden index 1de81fd223..cc308eb5de 100644 --- a/src/test/java/com/google/api/generator/gapic/composer/grpc/goldens/LoggingServiceV2StubSettings.golden +++ b/src/test/java/com/google/api/generator/gapic/composer/grpc/goldens/LoggingServiceV2StubSettings.golden @@ -440,7 +440,9 @@ public class LoggingServiceV2StubSettings extends StubSettings { /** Returns a builder for the default credentials for this service. */ public static GoogleCredentialsProvider.Builder defaultCredentialsProviderBuilder() { - return GoogleCredentialsProvider.newBuilder().setScopesToApply(DEFAULT_SERVICE_SCOPES); + return GoogleCredentialsProvider.newBuilder() + .setScopesToApply(DEFAULT_SERVICE_SCOPES) + .setUseJwtAccessWithScope(true); } /** Returns a builder for the default ChannelProvider for this service. */ diff --git a/test/integration/goldens/asset/com/google/cloud/asset/v1/AssetServiceClient.java b/test/integration/goldens/asset/com/google/cloud/asset/v1/AssetServiceClient.java index 1860b0cca4..af1cc6dd1f 100644 --- a/test/integration/goldens/asset/com/google/cloud/asset/v1/AssetServiceClient.java +++ b/test/integration/goldens/asset/com/google/cloud/asset/v1/AssetServiceClient.java @@ -54,6 +54,7 @@ * .addAllAssetNames(new ArrayList()) * .setContentType(ContentType.forNumber(0)) * .setReadTimeWindow(TimeWindow.newBuilder().build()) + * .addAllRelationshipTypes(new ArrayList()) * .build(); * BatchGetAssetsHistoryResponse response = assetServiceClient.batchGetAssetsHistory(request); * } @@ -190,6 +191,7 @@ public final OperationsClient getOperationsClient() { * .addAllAssetTypes(new ArrayList()) * .setContentType(ContentType.forNumber(0)) * .setOutputConfig(OutputConfig.newBuilder().build()) + * .addAllRelationshipTypes(new ArrayList()) * .build(); * ExportAssetsResponse response = assetServiceClient.exportAssetsAsync(request).get(); * } @@ -225,6 +227,7 @@ public final OperationFuture exportAs * .addAllAssetTypes(new ArrayList()) * .setContentType(ContentType.forNumber(0)) * .setOutputConfig(OutputConfig.newBuilder().build()) + * .addAllRelationshipTypes(new ArrayList()) * .build(); * OperationFuture future = * assetServiceClient.exportAssetsOperationCallable().futureCall(request); @@ -260,6 +263,7 @@ public final OperationFuture exportAs * .addAllAssetTypes(new ArrayList()) * .setContentType(ContentType.forNumber(0)) * .setOutputConfig(OutputConfig.newBuilder().build()) + * .addAllRelationshipTypes(new ArrayList()) * .build(); * ApiFuture future = assetServiceClient.exportAssetsCallable().futureCall(request); * // Do something. @@ -340,6 +344,7 @@ public final ListAssetsPagedResponse listAssets(String parent) { * .setContentType(ContentType.forNumber(0)) * .setPageSize(883849137) * .setPageToken("pageToken873572522") + * .addAllRelationshipTypes(new ArrayList()) * .build(); * for (Asset element : assetServiceClient.listAssets(request).iterateAll()) { * // doThingsWith(element); @@ -370,6 +375,7 @@ public final ListAssetsPagedResponse listAssets(ListAssetsRequest request) { * .setContentType(ContentType.forNumber(0)) * .setPageSize(883849137) * .setPageToken("pageToken873572522") + * .addAllRelationshipTypes(new ArrayList()) * .build(); * ApiFuture future = assetServiceClient.listAssetsPagedCallable().futureCall(request); * // Do something. @@ -399,6 +405,7 @@ public final UnaryCallable listAsset * .setContentType(ContentType.forNumber(0)) * .setPageSize(883849137) * .setPageToken("pageToken873572522") + * .addAllRelationshipTypes(new ArrayList()) * .build(); * while (true) { * ListAssetsResponse response = assetServiceClient.listAssetsCallable().call(request); @@ -437,6 +444,7 @@ public final UnaryCallable listAssetsCall * .addAllAssetNames(new ArrayList()) * .setContentType(ContentType.forNumber(0)) * .setReadTimeWindow(TimeWindow.newBuilder().build()) + * .addAllRelationshipTypes(new ArrayList()) * .build(); * BatchGetAssetsHistoryResponse response = assetServiceClient.batchGetAssetsHistory(request); * } @@ -468,6 +476,7 @@ public final BatchGetAssetsHistoryResponse batchGetAssetsHistory( * .addAllAssetNames(new ArrayList()) * .setContentType(ContentType.forNumber(0)) * .setReadTimeWindow(TimeWindow.newBuilder().build()) + * .addAllRelationshipTypes(new ArrayList()) * .build(); * ApiFuture future = * assetServiceClient.batchGetAssetsHistoryCallable().futureCall(request); @@ -924,8 +933,8 @@ public final UnaryCallable deleteFeedCallable() { *
  • `kmsKey:key` to find Cloud resources encrypted with a customer-managed encryption key * whose name contains the word "key". *
  • `state:ACTIVE` to find Cloud resources whose state contains "ACTIVE" as a word. - *
  • `NOT state:ACTIVE` to find {{gcp_name}} resources whose state doesn't contain - * "ACTIVE" as a word. + *
  • `NOT state:ACTIVE` to find Cloud resources whose state doesn't contain "ACTIVE" as a + * word. *
  • `createTime<1609459200` to find Cloud resources that were created before * "2021-01-01 00:00:00 UTC". 1609459200 is the epoch timestamp of "2021-01-01 00:00:00 * UTC" in seconds. @@ -985,6 +994,7 @@ public final SearchAllResourcesPagedResponse searchAllResources( * .setPageSize(883849137) * .setPageToken("pageToken873572522") * .setOrderBy("orderBy-1207110587") + * .setReadMask(FieldMask.newBuilder().build()) * .build(); * for (ResourceSearchResult element : * assetServiceClient.searchAllResources(request).iterateAll()) { @@ -1019,6 +1029,7 @@ public final SearchAllResourcesPagedResponse searchAllResources( * .setPageSize(883849137) * .setPageToken("pageToken873572522") * .setOrderBy("orderBy-1207110587") + * .setReadMask(FieldMask.newBuilder().build()) * .build(); * ApiFuture future = * assetServiceClient.searchAllResourcesPagedCallable().futureCall(request); @@ -1052,6 +1063,7 @@ public final SearchAllResourcesPagedResponse searchAllResources( * .setPageSize(883849137) * .setPageToken("pageToken873572522") * .setOrderBy("orderBy-1207110587") + * .setReadMask(FieldMask.newBuilder().build()) * .build(); * while (true) { * SearchAllResourcesResponse response = @@ -1314,8 +1326,8 @@ public final AnalyzeIamPolicyResponse analyzeIamPolicy(AnalyzeIamPolicyRequest r * [AnalyzeIamPolicyResponse][google.cloud.asset.v1.AnalyzeIamPolicyResponse]. This method * implements the [google.longrunning.Operation][google.longrunning.Operation], which allows you * to track the operation status. We recommend intervals of at least 2 seconds with exponential - * backoff retry to poll the operation result. The metadata contains the request to help callers - * to map responses to requests. + * backoff retry to poll the operation result. The metadata contains the metadata for the + * long-running operation. * *

    Sample code: * @@ -1335,7 +1347,7 @@ public final AnalyzeIamPolicyResponse analyzeIamPolicy(AnalyzeIamPolicyRequest r * @throws com.google.api.gax.rpc.ApiException if the remote call fails */ public final OperationFuture< - AnalyzeIamPolicyLongrunningResponse, AnalyzeIamPolicyLongrunningRequest> + AnalyzeIamPolicyLongrunningResponse, AnalyzeIamPolicyLongrunningMetadata> analyzeIamPolicyLongrunningAsync(AnalyzeIamPolicyLongrunningRequest request) { return analyzeIamPolicyLongrunningOperationCallable().futureCall(request); } @@ -1348,8 +1360,8 @@ public final AnalyzeIamPolicyResponse analyzeIamPolicy(AnalyzeIamPolicyRequest r * [AnalyzeIamPolicyResponse][google.cloud.asset.v1.AnalyzeIamPolicyResponse]. This method * implements the [google.longrunning.Operation][google.longrunning.Operation], which allows you * to track the operation status. We recommend intervals of at least 2 seconds with exponential - * backoff retry to poll the operation result. The metadata contains the request to help callers - * to map responses to requests. + * backoff retry to poll the operation result. The metadata contains the metadata for the + * long-running operation. * *

    Sample code: * @@ -1360,7 +1372,7 @@ public final AnalyzeIamPolicyResponse analyzeIamPolicy(AnalyzeIamPolicyRequest r * .setAnalysisQuery(IamPolicyAnalysisQuery.newBuilder().build()) * .setOutputConfig(IamPolicyAnalysisOutputConfig.newBuilder().build()) * .build(); - * OperationFuture + * OperationFuture * future = * assetServiceClient.analyzeIamPolicyLongrunningOperationCallable().futureCall(request); * // Do something. @@ -1371,7 +1383,7 @@ public final AnalyzeIamPolicyResponse analyzeIamPolicy(AnalyzeIamPolicyRequest r public final OperationCallable< AnalyzeIamPolicyLongrunningRequest, AnalyzeIamPolicyLongrunningResponse, - AnalyzeIamPolicyLongrunningRequest> + AnalyzeIamPolicyLongrunningMetadata> analyzeIamPolicyLongrunningOperationCallable() { return stub.analyzeIamPolicyLongrunningOperationCallable(); } @@ -1384,8 +1396,8 @@ public final AnalyzeIamPolicyResponse analyzeIamPolicy(AnalyzeIamPolicyRequest r * [AnalyzeIamPolicyResponse][google.cloud.asset.v1.AnalyzeIamPolicyResponse]. This method * implements the [google.longrunning.Operation][google.longrunning.Operation], which allows you * to track the operation status. We recommend intervals of at least 2 seconds with exponential - * backoff retry to poll the operation result. The metadata contains the request to help callers - * to map responses to requests. + * backoff retry to poll the operation result. The metadata contains the metadata for the + * long-running operation. * *

    Sample code: * @@ -1408,6 +1420,60 @@ public final AnalyzeIamPolicyResponse analyzeIamPolicy(AnalyzeIamPolicyRequest r return stub.analyzeIamPolicyLongrunningCallable(); } + // AUTO-GENERATED DOCUMENTATION AND METHOD. + /** + * Analyze moving a resource to a specified destination without kicking off the actual move. The + * analysis is best effort depending on the user's permissions of viewing different hierarchical + * policies and configurations. The policies and configuration are subject to change before the + * actual resource migration takes place. + * + *

    Sample code: + * + *

    {@code
    +   * try (AssetServiceClient assetServiceClient = AssetServiceClient.create()) {
    +   *   AnalyzeMoveRequest request =
    +   *       AnalyzeMoveRequest.newBuilder()
    +   *           .setResource("resource-341064690")
    +   *           .setDestinationParent("destinationParent-1733659048")
    +   *           .build();
    +   *   AnalyzeMoveResponse response = assetServiceClient.analyzeMove(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 AnalyzeMoveResponse analyzeMove(AnalyzeMoveRequest request) { + return analyzeMoveCallable().call(request); + } + + // AUTO-GENERATED DOCUMENTATION AND METHOD. + /** + * Analyze moving a resource to a specified destination without kicking off the actual move. The + * analysis is best effort depending on the user's permissions of viewing different hierarchical + * policies and configurations. The policies and configuration are subject to change before the + * actual resource migration takes place. + * + *

    Sample code: + * + *

    {@code
    +   * try (AssetServiceClient assetServiceClient = AssetServiceClient.create()) {
    +   *   AnalyzeMoveRequest request =
    +   *       AnalyzeMoveRequest.newBuilder()
    +   *           .setResource("resource-341064690")
    +   *           .setDestinationParent("destinationParent-1733659048")
    +   *           .build();
    +   *   ApiFuture future =
    +   *       assetServiceClient.analyzeMoveCallable().futureCall(request);
    +   *   // Do something.
    +   *   AnalyzeMoveResponse response = future.get();
    +   * }
    +   * }
    + */ + public final UnaryCallable analyzeMoveCallable() { + return stub.analyzeMoveCallable(); + } + @Override public final void close() { stub.close(); diff --git a/test/integration/goldens/asset/com/google/cloud/asset/v1/AssetServiceClientTest.java b/test/integration/goldens/asset/com/google/cloud/asset/v1/AssetServiceClientTest.java index de8ca67414..41f50cea3a 100644 --- a/test/integration/goldens/asset/com/google/cloud/asset/v1/AssetServiceClientTest.java +++ b/test/integration/goldens/asset/com/google/cloud/asset/v1/AssetServiceClientTest.java @@ -113,6 +113,7 @@ public void exportAssetsTest() throws Exception { .addAllAssetTypes(new ArrayList()) .setContentType(ContentType.forNumber(0)) .setOutputConfig(OutputConfig.newBuilder().build()) + .addAllRelationshipTypes(new ArrayList()) .build(); ExportAssetsResponse actualResponse = client.exportAssetsAsync(request).get(); @@ -127,6 +128,8 @@ public void exportAssetsTest() throws Exception { Assert.assertEquals(request.getAssetTypesList(), actualRequest.getAssetTypesList()); Assert.assertEquals(request.getContentType(), actualRequest.getContentType()); Assert.assertEquals(request.getOutputConfig(), actualRequest.getOutputConfig()); + Assert.assertEquals( + request.getRelationshipTypesList(), actualRequest.getRelationshipTypesList()); Assert.assertTrue( channelProvider.isHeaderSent( ApiClientHeaderProvider.getDefaultApiClientHeaderKey(), @@ -146,6 +149,7 @@ public void exportAssetsExceptionTest() throws Exception { .addAllAssetTypes(new ArrayList()) .setContentType(ContentType.forNumber(0)) .setOutputConfig(OutputConfig.newBuilder().build()) + .addAllRelationshipTypes(new ArrayList()) .build(); client.exportAssetsAsync(request).get(); Assert.fail("No exception raised"); @@ -258,6 +262,7 @@ public void batchGetAssetsHistoryTest() throws Exception { .addAllAssetNames(new ArrayList()) .setContentType(ContentType.forNumber(0)) .setReadTimeWindow(TimeWindow.newBuilder().build()) + .addAllRelationshipTypes(new ArrayList()) .build(); BatchGetAssetsHistoryResponse actualResponse = client.batchGetAssetsHistory(request); @@ -272,6 +277,8 @@ public void batchGetAssetsHistoryTest() throws Exception { Assert.assertEquals(request.getAssetNamesList(), actualRequest.getAssetNamesList()); Assert.assertEquals(request.getContentType(), actualRequest.getContentType()); Assert.assertEquals(request.getReadTimeWindow(), actualRequest.getReadTimeWindow()); + Assert.assertEquals( + request.getRelationshipTypesList(), actualRequest.getRelationshipTypesList()); Assert.assertTrue( channelProvider.isHeaderSent( ApiClientHeaderProvider.getDefaultApiClientHeaderKey(), @@ -290,6 +297,7 @@ public void batchGetAssetsHistoryExceptionTest() throws Exception { .addAllAssetNames(new ArrayList()) .setContentType(ContentType.forNumber(0)) .setReadTimeWindow(TimeWindow.newBuilder().build()) + .addAllRelationshipTypes(new ArrayList()) .build(); client.batchGetAssetsHistory(request); Assert.fail("No exception raised"); @@ -308,6 +316,7 @@ public void createFeedTest() throws Exception { .setContentType(ContentType.forNumber(0)) .setFeedOutputConfig(FeedOutputConfig.newBuilder().build()) .setCondition(Expr.newBuilder().build()) + .addAllRelationshipTypes(new ArrayList()) .build(); mockAssetService.addResponse(expectedResponse); @@ -351,6 +360,7 @@ public void getFeedTest() throws Exception { .setContentType(ContentType.forNumber(0)) .setFeedOutputConfig(FeedOutputConfig.newBuilder().build()) .setCondition(Expr.newBuilder().build()) + .addAllRelationshipTypes(new ArrayList()) .build(); mockAssetService.addResponse(expectedResponse); @@ -394,6 +404,7 @@ public void getFeedTest2() throws Exception { .setContentType(ContentType.forNumber(0)) .setFeedOutputConfig(FeedOutputConfig.newBuilder().build()) .setCondition(Expr.newBuilder().build()) + .addAllRelationshipTypes(new ArrayList()) .build(); mockAssetService.addResponse(expectedResponse); @@ -473,6 +484,7 @@ public void updateFeedTest() throws Exception { .setContentType(ContentType.forNumber(0)) .setFeedOutputConfig(FeedOutputConfig.newBuilder().build()) .setCondition(Expr.newBuilder().build()) + .addAllRelationshipTypes(new ArrayList()) .build(); mockAssetService.addResponse(expectedResponse); @@ -777,4 +789,50 @@ public void analyzeIamPolicyLongrunningExceptionTest() throws Exception { Assert.assertEquals(StatusCode.Code.INVALID_ARGUMENT, apiException.getStatusCode().getCode()); } } + + @Test + public void analyzeMoveTest() throws Exception { + AnalyzeMoveResponse expectedResponse = + AnalyzeMoveResponse.newBuilder().addAllMoveAnalysis(new ArrayList()).build(); + mockAssetService.addResponse(expectedResponse); + + AnalyzeMoveRequest request = + AnalyzeMoveRequest.newBuilder() + .setResource("resource-341064690") + .setDestinationParent("destinationParent-1733659048") + .build(); + + AnalyzeMoveResponse actualResponse = client.analyzeMove(request); + Assert.assertEquals(expectedResponse, actualResponse); + + List actualRequests = mockAssetService.getRequests(); + Assert.assertEquals(1, actualRequests.size()); + AnalyzeMoveRequest actualRequest = ((AnalyzeMoveRequest) actualRequests.get(0)); + + Assert.assertEquals(request.getResource(), actualRequest.getResource()); + Assert.assertEquals(request.getDestinationParent(), actualRequest.getDestinationParent()); + Assert.assertEquals(request.getView(), actualRequest.getView()); + Assert.assertTrue( + channelProvider.isHeaderSent( + ApiClientHeaderProvider.getDefaultApiClientHeaderKey(), + GaxGrpcProperties.getDefaultApiClientHeaderPattern())); + } + + @Test + public void analyzeMoveExceptionTest() throws Exception { + StatusRuntimeException exception = new StatusRuntimeException(io.grpc.Status.INVALID_ARGUMENT); + mockAssetService.addException(exception); + + try { + AnalyzeMoveRequest request = + AnalyzeMoveRequest.newBuilder() + .setResource("resource-341064690") + .setDestinationParent("destinationParent-1733659048") + .build(); + client.analyzeMove(request); + Assert.fail("No exception raised"); + } catch (InvalidArgumentException e) { + // Expected exception. + } + } } diff --git a/test/integration/goldens/asset/com/google/cloud/asset/v1/AssetServiceSettings.java b/test/integration/goldens/asset/com/google/cloud/asset/v1/AssetServiceSettings.java index df338c00a9..8bca7d5631 100644 --- a/test/integration/goldens/asset/com/google/cloud/asset/v1/AssetServiceSettings.java +++ b/test/integration/goldens/asset/com/google/cloud/asset/v1/AssetServiceSettings.java @@ -154,12 +154,17 @@ public UnaryCallSettings deleteFeedSettings() { public OperationCallSettings< AnalyzeIamPolicyLongrunningRequest, AnalyzeIamPolicyLongrunningResponse, - AnalyzeIamPolicyLongrunningRequest> + AnalyzeIamPolicyLongrunningMetadata> analyzeIamPolicyLongrunningOperationSettings() { return ((AssetServiceStubSettings) getStubSettings()) .analyzeIamPolicyLongrunningOperationSettings(); } + /** Returns the object with the settings used for calls to analyzeMove. */ + public UnaryCallSettings analyzeMoveSettings() { + return ((AssetServiceStubSettings) getStubSettings()).analyzeMoveSettings(); + } + public static final AssetServiceSettings create(AssetServiceStubSettings stub) throws IOException { return new AssetServiceSettings.Builder(stub.toBuilder()).build(); @@ -338,11 +343,17 @@ public UnaryCallSettings.Builder deleteFeedSettings() public OperationCallSettings.Builder< AnalyzeIamPolicyLongrunningRequest, AnalyzeIamPolicyLongrunningResponse, - AnalyzeIamPolicyLongrunningRequest> + AnalyzeIamPolicyLongrunningMetadata> analyzeIamPolicyLongrunningOperationSettings() { return getStubSettingsBuilder().analyzeIamPolicyLongrunningOperationSettings(); } + /** Returns the builder for the settings used for calls to analyzeMove. */ + public UnaryCallSettings.Builder + analyzeMoveSettings() { + return getStubSettingsBuilder().analyzeMoveSettings(); + } + @Override public AssetServiceSettings build() throws IOException { return new AssetServiceSettings(this); diff --git a/test/integration/goldens/asset/com/google/cloud/asset/v1/MockAssetServiceImpl.java b/test/integration/goldens/asset/com/google/cloud/asset/v1/MockAssetServiceImpl.java index 643691d8d4..f72ed1eaa6 100644 --- a/test/integration/goldens/asset/com/google/cloud/asset/v1/MockAssetServiceImpl.java +++ b/test/integration/goldens/asset/com/google/cloud/asset/v1/MockAssetServiceImpl.java @@ -310,4 +310,25 @@ public void analyzeIamPolicyLongrunning( Exception.class.getName()))); } } + + @Override + public void analyzeMove( + AnalyzeMoveRequest request, StreamObserver responseObserver) { + Object response = responses.poll(); + if (response instanceof AnalyzeMoveResponse) { + requests.add(request); + responseObserver.onNext(((AnalyzeMoveResponse) 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 AnalyzeMove, expected %s or %s", + response == null ? "null" : response.getClass().getName(), + AnalyzeMoveResponse.class.getName(), + Exception.class.getName()))); + } + } } diff --git a/test/integration/goldens/asset/com/google/cloud/asset/v1/gapic_metadata.json b/test/integration/goldens/asset/com/google/cloud/asset/v1/gapic_metadata.json index ea1187e7ac..05ba5ae5ea 100644 --- a/test/integration/goldens/asset/com/google/cloud/asset/v1/gapic_metadata.json +++ b/test/integration/goldens/asset/com/google/cloud/asset/v1/gapic_metadata.json @@ -16,6 +16,9 @@ "AnalyzeIamPolicyLongrunning": { "methods": ["analyzeIamPolicyLongrunningAsync", "analyzeIamPolicyLongrunningOperationCallable", "analyzeIamPolicyLongrunningCallable"] }, + "AnalyzeMove": { + "methods": ["analyzeMove", "analyzeMoveCallable"] + }, "BatchGetAssetsHistory": { "methods": ["batchGetAssetsHistory", "batchGetAssetsHistoryCallable"] }, diff --git a/test/integration/goldens/asset/com/google/cloud/asset/v1/package-info.java b/test/integration/goldens/asset/com/google/cloud/asset/v1/package-info.java index 27db247ed3..d07bbc1fb7 100644 --- a/test/integration/goldens/asset/com/google/cloud/asset/v1/package-info.java +++ b/test/integration/goldens/asset/com/google/cloud/asset/v1/package-info.java @@ -31,6 +31,7 @@ * .addAllAssetNames(new ArrayList()) * .setContentType(ContentType.forNumber(0)) * .setReadTimeWindow(TimeWindow.newBuilder().build()) + * .addAllRelationshipTypes(new ArrayList()) * .build(); * BatchGetAssetsHistoryResponse response = assetServiceClient.batchGetAssetsHistory(request); * } diff --git a/test/integration/goldens/asset/com/google/cloud/asset/v1/stub/AssetServiceStub.java b/test/integration/goldens/asset/com/google/cloud/asset/v1/stub/AssetServiceStub.java index 462d7e2922..f3b324ba29 100644 --- a/test/integration/goldens/asset/com/google/cloud/asset/v1/stub/AssetServiceStub.java +++ b/test/integration/goldens/asset/com/google/cloud/asset/v1/stub/AssetServiceStub.java @@ -23,10 +23,13 @@ import com.google.api.gax.core.BackgroundResource; import com.google.api.gax.rpc.OperationCallable; import com.google.api.gax.rpc.UnaryCallable; +import com.google.cloud.asset.v1.AnalyzeIamPolicyLongrunningMetadata; import com.google.cloud.asset.v1.AnalyzeIamPolicyLongrunningRequest; import com.google.cloud.asset.v1.AnalyzeIamPolicyLongrunningResponse; import com.google.cloud.asset.v1.AnalyzeIamPolicyRequest; import com.google.cloud.asset.v1.AnalyzeIamPolicyResponse; +import com.google.cloud.asset.v1.AnalyzeMoveRequest; +import com.google.cloud.asset.v1.AnalyzeMoveResponse; import com.google.cloud.asset.v1.BatchGetAssetsHistoryRequest; import com.google.cloud.asset.v1.BatchGetAssetsHistoryResponse; import com.google.cloud.asset.v1.CreateFeedRequest; @@ -132,7 +135,7 @@ public UnaryCallable deleteFeedCallable() { public OperationCallable< AnalyzeIamPolicyLongrunningRequest, AnalyzeIamPolicyLongrunningResponse, - AnalyzeIamPolicyLongrunningRequest> + AnalyzeIamPolicyLongrunningMetadata> analyzeIamPolicyLongrunningOperationCallable() { throw new UnsupportedOperationException( "Not implemented: analyzeIamPolicyLongrunningOperationCallable()"); @@ -144,6 +147,10 @@ public UnaryCallable deleteFeedCallable() { "Not implemented: analyzeIamPolicyLongrunningCallable()"); } + public UnaryCallable analyzeMoveCallable() { + throw new UnsupportedOperationException("Not implemented: analyzeMoveCallable()"); + } + @Override public abstract void close(); } diff --git a/test/integration/goldens/asset/com/google/cloud/asset/v1/stub/AssetServiceStubSettings.java b/test/integration/goldens/asset/com/google/cloud/asset/v1/stub/AssetServiceStubSettings.java index d5f851bb3b..30012d98c6 100644 --- a/test/integration/goldens/asset/com/google/cloud/asset/v1/stub/AssetServiceStubSettings.java +++ b/test/integration/goldens/asset/com/google/cloud/asset/v1/stub/AssetServiceStubSettings.java @@ -46,10 +46,13 @@ import com.google.api.gax.rpc.TransportChannelProvider; import com.google.api.gax.rpc.UnaryCallSettings; import com.google.api.gax.rpc.UnaryCallable; +import com.google.cloud.asset.v1.AnalyzeIamPolicyLongrunningMetadata; import com.google.cloud.asset.v1.AnalyzeIamPolicyLongrunningRequest; import com.google.cloud.asset.v1.AnalyzeIamPolicyLongrunningResponse; import com.google.cloud.asset.v1.AnalyzeIamPolicyRequest; import com.google.cloud.asset.v1.AnalyzeIamPolicyResponse; +import com.google.cloud.asset.v1.AnalyzeMoveRequest; +import com.google.cloud.asset.v1.AnalyzeMoveResponse; import com.google.cloud.asset.v1.Asset; import com.google.cloud.asset.v1.BatchGetAssetsHistoryRequest; import com.google.cloud.asset.v1.BatchGetAssetsHistoryResponse; @@ -147,8 +150,9 @@ public class AssetServiceStubSettings extends StubSettings + AnalyzeIamPolicyLongrunningMetadata> analyzeIamPolicyLongrunningOperationSettings; + private final UnaryCallSettings analyzeMoveSettings; private static final PagedListDescriptor LIST_ASSETS_PAGE_STR_DESC = @@ -413,11 +417,16 @@ public UnaryCallSettings deleteFeedSettings() { public OperationCallSettings< AnalyzeIamPolicyLongrunningRequest, AnalyzeIamPolicyLongrunningResponse, - AnalyzeIamPolicyLongrunningRequest> + AnalyzeIamPolicyLongrunningMetadata> analyzeIamPolicyLongrunningOperationSettings() { return analyzeIamPolicyLongrunningOperationSettings; } + /** Returns the object with the settings used for calls to analyzeMove. */ + public UnaryCallSettings analyzeMoveSettings() { + return analyzeMoveSettings; + } + @BetaApi("A restructuring of stub classes is planned, so this may break in the future") public AssetServiceStub createStub() throws IOException { if (getTransportChannelProvider() @@ -452,7 +461,9 @@ public static List getDefaultServiceScopes() { /** Returns a builder for the default credentials for this service. */ public static GoogleCredentialsProvider.Builder defaultCredentialsProviderBuilder() { - return GoogleCredentialsProvider.newBuilder().setScopesToApply(DEFAULT_SERVICE_SCOPES); + return GoogleCredentialsProvider.newBuilder() + .setScopesToApply(DEFAULT_SERVICE_SCOPES) + .setUseJwtAccessWithScope(true); } /** Returns a builder for the default ChannelProvider for this service. */ @@ -508,6 +519,7 @@ protected AssetServiceStubSettings(Builder settingsBuilder) throws IOException { settingsBuilder.analyzeIamPolicyLongrunningSettings().build(); analyzeIamPolicyLongrunningOperationSettings = settingsBuilder.analyzeIamPolicyLongrunningOperationSettings().build(); + analyzeMoveSettings = settingsBuilder.analyzeMoveSettings().build(); } /** Builder for AssetServiceStubSettings. */ @@ -543,8 +555,10 @@ public static class Builder extends StubSettings.Builder + AnalyzeIamPolicyLongrunningMetadata> analyzeIamPolicyLongrunningOperationSettings; + private final UnaryCallSettings.Builder + analyzeMoveSettings; private static final ImmutableMap> RETRYABLE_CODE_DEFINITIONS; @@ -564,6 +578,7 @@ public static class Builder extends StubSettings.BuildernewArrayList(StatusCode.Code.UNAVAILABLE))); + definitions.put("no_retry_codes", ImmutableSet.copyOf(Lists.newArrayList())); RETRYABLE_CODE_DEFINITIONS = definitions.build(); } @@ -613,6 +628,8 @@ public static class Builder extends StubSettings.Builder>of( @@ -652,7 +670,8 @@ protected Builder(ClientContext clientContext) { searchAllResourcesSettings, searchAllIamPoliciesSettings, analyzeIamPolicySettings, - analyzeIamPolicyLongrunningSettings); + analyzeIamPolicyLongrunningSettings, + analyzeMoveSettings); initDefaults(this); } @@ -675,6 +694,7 @@ protected Builder(AssetServiceStubSettings settings) { settings.analyzeIamPolicyLongrunningSettings.toBuilder(); analyzeIamPolicyLongrunningOperationSettings = settings.analyzeIamPolicyLongrunningOperationSettings.toBuilder(); + analyzeMoveSettings = settings.analyzeMoveSettings.toBuilder(); unaryMethodSettingsBuilders = ImmutableList.>of( @@ -689,7 +709,8 @@ protected Builder(AssetServiceStubSettings settings) { searchAllResourcesSettings, searchAllIamPoliciesSettings, analyzeIamPolicySettings, - analyzeIamPolicyLongrunningSettings); + analyzeIamPolicyLongrunningSettings, + analyzeMoveSettings); } private static Builder createDefault() { @@ -766,6 +787,11 @@ private static Builder initDefaults(Builder builder) { .setRetryableCodes(RETRYABLE_CODE_DEFINITIONS.get("no_retry_0_codes")) .setRetrySettings(RETRY_PARAM_DEFINITIONS.get("no_retry_0_params")); + builder + .analyzeMoveSettings() + .setRetryableCodes(RETRYABLE_CODE_DEFINITIONS.get("no_retry_codes")) + .setRetrySettings(RETRY_PARAM_DEFINITIONS.get("no_retry_params")); + builder .exportAssetsOperationSettings() .setInitialCallSettings( @@ -804,7 +830,7 @@ private static Builder initDefaults(Builder builder) { AnalyzeIamPolicyLongrunningResponse.class)) .setMetadataTransformer( ProtoOperationTransformers.MetadataTransformer.create( - AnalyzeIamPolicyLongrunningRequest.class)) + AnalyzeIamPolicyLongrunningMetadata.class)) .setPollingAlgorithm( OperationTimedPollAlgorithm.create( RetrySettings.newBuilder() @@ -920,11 +946,17 @@ public UnaryCallSettings.Builder deleteFeedSettings() public OperationCallSettings.Builder< AnalyzeIamPolicyLongrunningRequest, AnalyzeIamPolicyLongrunningResponse, - AnalyzeIamPolicyLongrunningRequest> + AnalyzeIamPolicyLongrunningMetadata> analyzeIamPolicyLongrunningOperationSettings() { return analyzeIamPolicyLongrunningOperationSettings; } + /** Returns the builder for the settings used for calls to analyzeMove. */ + public UnaryCallSettings.Builder + analyzeMoveSettings() { + return analyzeMoveSettings; + } + @Override public AssetServiceStubSettings build() throws IOException { return new AssetServiceStubSettings(this); diff --git a/test/integration/goldens/asset/com/google/cloud/asset/v1/stub/GrpcAssetServiceStub.java b/test/integration/goldens/asset/com/google/cloud/asset/v1/stub/GrpcAssetServiceStub.java index d884f02bf9..d467435938 100644 --- a/test/integration/goldens/asset/com/google/cloud/asset/v1/stub/GrpcAssetServiceStub.java +++ b/test/integration/goldens/asset/com/google/cloud/asset/v1/stub/GrpcAssetServiceStub.java @@ -27,10 +27,13 @@ import com.google.api.gax.rpc.ClientContext; import com.google.api.gax.rpc.OperationCallable; import com.google.api.gax.rpc.UnaryCallable; +import com.google.cloud.asset.v1.AnalyzeIamPolicyLongrunningMetadata; import com.google.cloud.asset.v1.AnalyzeIamPolicyLongrunningRequest; import com.google.cloud.asset.v1.AnalyzeIamPolicyLongrunningResponse; import com.google.cloud.asset.v1.AnalyzeIamPolicyRequest; import com.google.cloud.asset.v1.AnalyzeIamPolicyResponse; +import com.google.cloud.asset.v1.AnalyzeMoveRequest; +import com.google.cloud.asset.v1.AnalyzeMoveResponse; import com.google.cloud.asset.v1.BatchGetAssetsHistoryRequest; import com.google.cloud.asset.v1.BatchGetAssetsHistoryResponse; import com.google.cloud.asset.v1.CreateFeedRequest; @@ -180,6 +183,16 @@ public class GrpcAssetServiceStub extends AssetServiceStub { .setResponseMarshaller(ProtoUtils.marshaller(Operation.getDefaultInstance())) .build(); + private static final MethodDescriptor + analyzeMoveMethodDescriptor = + MethodDescriptor.newBuilder() + .setType(MethodDescriptor.MethodType.UNARY) + .setFullMethodName("google.cloud.asset.v1.AssetService/AnalyzeMove") + .setRequestMarshaller(ProtoUtils.marshaller(AnalyzeMoveRequest.getDefaultInstance())) + .setResponseMarshaller( + ProtoUtils.marshaller(AnalyzeMoveResponse.getDefaultInstance())) + .build(); + private final UnaryCallable exportAssetsCallable; private final OperationCallable exportAssetsOperationCallable; @@ -207,8 +220,9 @@ public class GrpcAssetServiceStub extends AssetServiceStub { private final OperationCallable< AnalyzeIamPolicyLongrunningRequest, AnalyzeIamPolicyLongrunningResponse, - AnalyzeIamPolicyLongrunningRequest> + AnalyzeIamPolicyLongrunningMetadata> analyzeIamPolicyLongrunningOperationCallable; + private final UnaryCallable analyzeMoveCallable; private final BackgroundResource backgroundResources; private final GrpcOperationsStub operationsStub; @@ -382,6 +396,16 @@ protected GrpcAssetServiceStub( return params.build(); }) .build(); + GrpcCallSettings analyzeMoveTransportSettings = + GrpcCallSettings.newBuilder() + .setMethodDescriptor(analyzeMoveMethodDescriptor) + .setParamsExtractor( + request -> { + ImmutableMap.Builder params = ImmutableMap.builder(); + params.put("resource", String.valueOf(request.getResource())); + return params.build(); + }) + .build(); this.exportAssetsCallable = callableFactory.createUnaryCallable( @@ -452,6 +476,9 @@ protected GrpcAssetServiceStub( settings.analyzeIamPolicyLongrunningOperationSettings(), clientContext, operationsStub); + this.analyzeMoveCallable = + callableFactory.createUnaryCallable( + analyzeMoveTransportSettings, settings.analyzeMoveSettings(), clientContext); this.backgroundResources = new BackgroundResourceAggregation(clientContext.getBackgroundResources()); @@ -553,11 +580,16 @@ public UnaryCallable deleteFeedCallable() { public OperationCallable< AnalyzeIamPolicyLongrunningRequest, AnalyzeIamPolicyLongrunningResponse, - AnalyzeIamPolicyLongrunningRequest> + AnalyzeIamPolicyLongrunningMetadata> analyzeIamPolicyLongrunningOperationCallable() { return analyzeIamPolicyLongrunningOperationCallable; } + @Override + public UnaryCallable analyzeMoveCallable() { + return analyzeMoveCallable; + } + @Override public final void close() { try { diff --git a/test/integration/goldens/compute/com/google/cloud/compute/v1/AddressesClientTest.java b/test/integration/goldens/compute/com/google/cloud/compute/v1/AddressesClientTest.java index bc7d9c2a16..24d06c2f69 100644 --- a/test/integration/goldens/compute/com/google/cloud/compute/v1/AddressesClientTest.java +++ b/test/integration/goldens/compute/com/google/cloud/compute/v1/AddressesClientTest.java @@ -141,7 +141,7 @@ public void deleteTest() throws Exception { .setError(Error.newBuilder().build()) .setHttpErrorMessage("httpErrorMessage1577303431") .setHttpErrorStatusCode(1386087020) - .setId("id3355") + .setId(3355) .setInsertTime("insertTime966165798") .setKind("kind3292052") .setName("name3373707") @@ -151,7 +151,7 @@ public void deleteTest() throws Exception { .setSelfLink("selfLink1191800166") .setStartTime("startTime-2129294769") .setStatusMessage("statusMessage-958704715") - .setTargetId("targetId-441951604") + .setTargetId(-815576439) .setTargetLink("targetLink486368555") .setUser("user3599307") .addAllWarnings(new ArrayList()) @@ -210,7 +210,7 @@ public void insertTest() throws Exception { .setError(Error.newBuilder().build()) .setHttpErrorMessage("httpErrorMessage1577303431") .setHttpErrorStatusCode(1386087020) - .setId("id3355") + .setId(3355) .setInsertTime("insertTime966165798") .setKind("kind3292052") .setName("name3373707") @@ -220,7 +220,7 @@ public void insertTest() throws Exception { .setSelfLink("selfLink1191800166") .setStartTime("startTime-2129294769") .setStatusMessage("statusMessage-958704715") - .setTargetId("targetId-441951604") + .setTargetId(-815576439) .setTargetLink("targetLink486368555") .setUser("user3599307") .addAllWarnings(new ArrayList()) diff --git a/test/integration/goldens/compute/com/google/cloud/compute/v1/RegionOperationsClientTest.java b/test/integration/goldens/compute/com/google/cloud/compute/v1/RegionOperationsClientTest.java index 7f6b78232a..d41b1f5191 100644 --- a/test/integration/goldens/compute/com/google/cloud/compute/v1/RegionOperationsClientTest.java +++ b/test/integration/goldens/compute/com/google/cloud/compute/v1/RegionOperationsClientTest.java @@ -83,7 +83,7 @@ public void getTest() throws Exception { .setError(Error.newBuilder().build()) .setHttpErrorMessage("httpErrorMessage1577303431") .setHttpErrorStatusCode(1386087020) - .setId("id3355") + .setId(3355) .setInsertTime("insertTime966165798") .setKind("kind3292052") .setName("name3373707") @@ -93,7 +93,7 @@ public void getTest() throws Exception { .setSelfLink("selfLink1191800166") .setStartTime("startTime-2129294769") .setStatusMessage("statusMessage-958704715") - .setTargetId("targetId-441951604") + .setTargetId(-815576439) .setTargetLink("targetLink486368555") .setUser("user3599307") .addAllWarnings(new ArrayList()) diff --git a/test/integration/goldens/credentials/com/google/cloud/iam/credentials/v1/stub/IamCredentialsStubSettings.java b/test/integration/goldens/credentials/com/google/cloud/iam/credentials/v1/stub/IamCredentialsStubSettings.java index 45338c519e..26792da200 100644 --- a/test/integration/goldens/credentials/com/google/cloud/iam/credentials/v1/stub/IamCredentialsStubSettings.java +++ b/test/integration/goldens/credentials/com/google/cloud/iam/credentials/v1/stub/IamCredentialsStubSettings.java @@ -150,7 +150,9 @@ public static List getDefaultServiceScopes() { /** Returns a builder for the default credentials for this service. */ public static GoogleCredentialsProvider.Builder defaultCredentialsProviderBuilder() { - return GoogleCredentialsProvider.newBuilder().setScopesToApply(DEFAULT_SERVICE_SCOPES); + return GoogleCredentialsProvider.newBuilder() + .setScopesToApply(DEFAULT_SERVICE_SCOPES) + .setUseJwtAccessWithScope(true); } /** Returns a builder for the default ChannelProvider for this service. */ diff --git a/test/integration/goldens/iam/com/google/iam/v1/stub/IAMPolicyStubSettings.java b/test/integration/goldens/iam/com/google/iam/v1/stub/IAMPolicyStubSettings.java index 0c1876afa5..03c10fcb73 100644 --- a/test/integration/goldens/iam/com/google/iam/v1/stub/IAMPolicyStubSettings.java +++ b/test/integration/goldens/iam/com/google/iam/v1/stub/IAMPolicyStubSettings.java @@ -137,7 +137,9 @@ public static List getDefaultServiceScopes() { /** Returns a builder for the default credentials for this service. */ public static GoogleCredentialsProvider.Builder defaultCredentialsProviderBuilder() { - return GoogleCredentialsProvider.newBuilder().setScopesToApply(DEFAULT_SERVICE_SCOPES); + return GoogleCredentialsProvider.newBuilder() + .setScopesToApply(DEFAULT_SERVICE_SCOPES) + .setUseJwtAccessWithScope(true); } /** Returns a builder for the default ChannelProvider for this service. */ 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 830ca8ca8d..e3faa10060 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 @@ -657,7 +657,9 @@ public static List getDefaultServiceScopes() { /** Returns a builder for the default credentials for this service. */ public static GoogleCredentialsProvider.Builder defaultCredentialsProviderBuilder() { - return GoogleCredentialsProvider.newBuilder().setScopesToApply(DEFAULT_SERVICE_SCOPES); + return GoogleCredentialsProvider.newBuilder() + .setScopesToApply(DEFAULT_SERVICE_SCOPES) + .setUseJwtAccessWithScope(true); } /** Returns a builder for the default ChannelProvider for this service. */ diff --git a/test/integration/goldens/library/com/google/cloud/example/library/v1/stub/LibraryServiceStubSettings.java b/test/integration/goldens/library/com/google/cloud/example/library/v1/stub/LibraryServiceStubSettings.java index 614a5b7c98..159cd561a6 100644 --- a/test/integration/goldens/library/com/google/cloud/example/library/v1/stub/LibraryServiceStubSettings.java +++ b/test/integration/goldens/library/com/google/cloud/example/library/v1/stub/LibraryServiceStubSettings.java @@ -316,7 +316,9 @@ public static List getDefaultServiceScopes() { /** Returns a builder for the default credentials for this service. */ public static GoogleCredentialsProvider.Builder defaultCredentialsProviderBuilder() { - return GoogleCredentialsProvider.newBuilder().setScopesToApply(DEFAULT_SERVICE_SCOPES); + return GoogleCredentialsProvider.newBuilder() + .setScopesToApply(DEFAULT_SERVICE_SCOPES) + .setUseJwtAccessWithScope(true); } /** Returns a builder for the default ChannelProvider for this service. */ diff --git a/test/integration/goldens/logging/com/google/cloud/logging/v2/stub/ConfigServiceV2StubSettings.java b/test/integration/goldens/logging/com/google/cloud/logging/v2/stub/ConfigServiceV2StubSettings.java index 942d01f547..faf8137eea 100644 --- a/test/integration/goldens/logging/com/google/cloud/logging/v2/stub/ConfigServiceV2StubSettings.java +++ b/test/integration/goldens/logging/com/google/cloud/logging/v2/stub/ConfigServiceV2StubSettings.java @@ -526,7 +526,9 @@ public static List getDefaultServiceScopes() { /** Returns a builder for the default credentials for this service. */ public static GoogleCredentialsProvider.Builder defaultCredentialsProviderBuilder() { - return GoogleCredentialsProvider.newBuilder().setScopesToApply(DEFAULT_SERVICE_SCOPES); + return GoogleCredentialsProvider.newBuilder() + .setScopesToApply(DEFAULT_SERVICE_SCOPES) + .setUseJwtAccessWithScope(true); } /** Returns a builder for the default ChannelProvider for this service. */ diff --git a/test/integration/goldens/logging/com/google/cloud/logging/v2/stub/LoggingServiceV2StubSettings.java b/test/integration/goldens/logging/com/google/cloud/logging/v2/stub/LoggingServiceV2StubSettings.java index ae4a0acbb2..3f3b507702 100644 --- a/test/integration/goldens/logging/com/google/cloud/logging/v2/stub/LoggingServiceV2StubSettings.java +++ b/test/integration/goldens/logging/com/google/cloud/logging/v2/stub/LoggingServiceV2StubSettings.java @@ -456,7 +456,9 @@ public static List getDefaultServiceScopes() { /** Returns a builder for the default credentials for this service. */ public static GoogleCredentialsProvider.Builder defaultCredentialsProviderBuilder() { - return GoogleCredentialsProvider.newBuilder().setScopesToApply(DEFAULT_SERVICE_SCOPES); + return GoogleCredentialsProvider.newBuilder() + .setScopesToApply(DEFAULT_SERVICE_SCOPES) + .setUseJwtAccessWithScope(true); } /** Returns a builder for the default ChannelProvider for this service. */ diff --git a/test/integration/goldens/logging/com/google/cloud/logging/v2/stub/MetricsServiceV2StubSettings.java b/test/integration/goldens/logging/com/google/cloud/logging/v2/stub/MetricsServiceV2StubSettings.java index 5694e24035..3cf4be8d73 100644 --- a/test/integration/goldens/logging/com/google/cloud/logging/v2/stub/MetricsServiceV2StubSettings.java +++ b/test/integration/goldens/logging/com/google/cloud/logging/v2/stub/MetricsServiceV2StubSettings.java @@ -224,7 +224,9 @@ public static List getDefaultServiceScopes() { /** Returns a builder for the default credentials for this service. */ public static GoogleCredentialsProvider.Builder defaultCredentialsProviderBuilder() { - return GoogleCredentialsProvider.newBuilder().setScopesToApply(DEFAULT_SERVICE_SCOPES); + return GoogleCredentialsProvider.newBuilder() + .setScopesToApply(DEFAULT_SERVICE_SCOPES) + .setUseJwtAccessWithScope(true); } /** Returns a builder for the default ChannelProvider for this service. */ diff --git a/test/integration/goldens/pubsub/com/google/cloud/pubsub/v1/SubscriptionAdminClient.java b/test/integration/goldens/pubsub/com/google/cloud/pubsub/v1/SubscriptionAdminClient.java index a6adbe6945..01e6bd03a6 100644 --- a/test/integration/goldens/pubsub/com/google/cloud/pubsub/v1/SubscriptionAdminClient.java +++ b/test/integration/goldens/pubsub/com/google/cloud/pubsub/v1/SubscriptionAdminClient.java @@ -485,6 +485,7 @@ public final Subscription createSubscription( * .setDeadLetterPolicy(DeadLetterPolicy.newBuilder().build()) * .setRetryPolicy(RetryPolicy.newBuilder().build()) * .setDetached(true) + * .setTopicMessageRetentionDuration(Duration.newBuilder().build()) * .build(); * Subscription response = subscriptionAdminClient.createSubscription(request); * } @@ -529,6 +530,7 @@ public final Subscription createSubscription(Subscription request) { * .setDeadLetterPolicy(DeadLetterPolicy.newBuilder().build()) * .setRetryPolicy(RetryPolicy.newBuilder().build()) * .setDetached(true) + * .setTopicMessageRetentionDuration(Duration.newBuilder().build()) * .build(); * ApiFuture future = * subscriptionAdminClient.createSubscriptionCallable().futureCall(request); diff --git a/test/integration/goldens/pubsub/com/google/cloud/pubsub/v1/SubscriptionAdminClientTest.java b/test/integration/goldens/pubsub/com/google/cloud/pubsub/v1/SubscriptionAdminClientTest.java index dd1bd27dac..9d53a7554a 100644 --- a/test/integration/goldens/pubsub/com/google/cloud/pubsub/v1/SubscriptionAdminClientTest.java +++ b/test/integration/goldens/pubsub/com/google/cloud/pubsub/v1/SubscriptionAdminClientTest.java @@ -149,6 +149,7 @@ public void createSubscriptionTest() throws Exception { .setDeadLetterPolicy(DeadLetterPolicy.newBuilder().build()) .setRetryPolicy(RetryPolicy.newBuilder().build()) .setDetached(true) + .setTopicMessageRetentionDuration(Duration.newBuilder().build()) .build(); mockSubscriber.addResponse(expectedResponse); @@ -209,6 +210,7 @@ public void createSubscriptionTest2() throws Exception { .setDeadLetterPolicy(DeadLetterPolicy.newBuilder().build()) .setRetryPolicy(RetryPolicy.newBuilder().build()) .setDetached(true) + .setTopicMessageRetentionDuration(Duration.newBuilder().build()) .build(); mockSubscriber.addResponse(expectedResponse); @@ -269,6 +271,7 @@ public void createSubscriptionTest3() throws Exception { .setDeadLetterPolicy(DeadLetterPolicy.newBuilder().build()) .setRetryPolicy(RetryPolicy.newBuilder().build()) .setDetached(true) + .setTopicMessageRetentionDuration(Duration.newBuilder().build()) .build(); mockSubscriber.addResponse(expectedResponse); @@ -329,6 +332,7 @@ public void createSubscriptionTest4() throws Exception { .setDeadLetterPolicy(DeadLetterPolicy.newBuilder().build()) .setRetryPolicy(RetryPolicy.newBuilder().build()) .setDetached(true) + .setTopicMessageRetentionDuration(Duration.newBuilder().build()) .build(); mockSubscriber.addResponse(expectedResponse); @@ -389,6 +393,7 @@ public void getSubscriptionTest() throws Exception { .setDeadLetterPolicy(DeadLetterPolicy.newBuilder().build()) .setRetryPolicy(RetryPolicy.newBuilder().build()) .setDetached(true) + .setTopicMessageRetentionDuration(Duration.newBuilder().build()) .build(); mockSubscriber.addResponse(expectedResponse); @@ -439,6 +444,7 @@ public void getSubscriptionTest2() throws Exception { .setDeadLetterPolicy(DeadLetterPolicy.newBuilder().build()) .setRetryPolicy(RetryPolicy.newBuilder().build()) .setDetached(true) + .setTopicMessageRetentionDuration(Duration.newBuilder().build()) .build(); mockSubscriber.addResponse(expectedResponse); @@ -489,6 +495,7 @@ public void updateSubscriptionTest() throws Exception { .setDeadLetterPolicy(DeadLetterPolicy.newBuilder().build()) .setRetryPolicy(RetryPolicy.newBuilder().build()) .setDetached(true) + .setTopicMessageRetentionDuration(Duration.newBuilder().build()) .build(); mockSubscriber.addResponse(expectedResponse); diff --git a/test/integration/goldens/pubsub/com/google/cloud/pubsub/v1/TopicAdminClient.java b/test/integration/goldens/pubsub/com/google/cloud/pubsub/v1/TopicAdminClient.java index 802fe3e940..be0a3a2e42 100644 --- a/test/integration/goldens/pubsub/com/google/cloud/pubsub/v1/TopicAdminClient.java +++ b/test/integration/goldens/pubsub/com/google/cloud/pubsub/v1/TopicAdminClient.java @@ -237,6 +237,7 @@ public final Topic createTopic(String name) { * .setKmsKeyName("kmsKeyName412586233") * .setSchemaSettings(SchemaSettings.newBuilder().build()) * .setSatisfiesPzs(true) + * .setMessageRetentionDuration(Duration.newBuilder().build()) * .build(); * Topic response = topicAdminClient.createTopic(request); * } @@ -266,6 +267,7 @@ public final Topic createTopic(Topic request) { * .setKmsKeyName("kmsKeyName412586233") * .setSchemaSettings(SchemaSettings.newBuilder().build()) * .setSatisfiesPzs(true) + * .setMessageRetentionDuration(Duration.newBuilder().build()) * .build(); * ApiFuture future = topicAdminClient.createTopicCallable().futureCall(request); * // Do something. diff --git a/test/integration/goldens/pubsub/com/google/cloud/pubsub/v1/TopicAdminClientTest.java b/test/integration/goldens/pubsub/com/google/cloud/pubsub/v1/TopicAdminClientTest.java index 09b8de0f90..02d6a55850 100644 --- a/test/integration/goldens/pubsub/com/google/cloud/pubsub/v1/TopicAdminClientTest.java +++ b/test/integration/goldens/pubsub/com/google/cloud/pubsub/v1/TopicAdminClientTest.java @@ -37,6 +37,7 @@ import com.google.iam.v1.TestIamPermissionsResponse; import com.google.protobuf.AbstractMessage; import com.google.protobuf.ByteString; +import com.google.protobuf.Duration; import com.google.protobuf.Empty; import com.google.protobuf.FieldMask; import com.google.pubsub.v1.DeleteTopicRequest; @@ -125,6 +126,7 @@ public void createTopicTest() throws Exception { .setKmsKeyName("kmsKeyName412586233") .setSchemaSettings(SchemaSettings.newBuilder().build()) .setSatisfiesPzs(true) + .setMessageRetentionDuration(Duration.newBuilder().build()) .build(); mockPublisher.addResponse(expectedResponse); @@ -168,6 +170,7 @@ public void createTopicTest2() throws Exception { .setKmsKeyName("kmsKeyName412586233") .setSchemaSettings(SchemaSettings.newBuilder().build()) .setSatisfiesPzs(true) + .setMessageRetentionDuration(Duration.newBuilder().build()) .build(); mockPublisher.addResponse(expectedResponse); @@ -211,6 +214,7 @@ public void updateTopicTest() throws Exception { .setKmsKeyName("kmsKeyName412586233") .setSchemaSettings(SchemaSettings.newBuilder().build()) .setSatisfiesPzs(true) + .setMessageRetentionDuration(Duration.newBuilder().build()) .build(); mockPublisher.addResponse(expectedResponse); @@ -341,6 +345,7 @@ public void getTopicTest() throws Exception { .setKmsKeyName("kmsKeyName412586233") .setSchemaSettings(SchemaSettings.newBuilder().build()) .setSatisfiesPzs(true) + .setMessageRetentionDuration(Duration.newBuilder().build()) .build(); mockPublisher.addResponse(expectedResponse); @@ -384,6 +389,7 @@ public void getTopicTest2() throws Exception { .setKmsKeyName("kmsKeyName412586233") .setSchemaSettings(SchemaSettings.newBuilder().build()) .setSatisfiesPzs(true) + .setMessageRetentionDuration(Duration.newBuilder().build()) .build(); mockPublisher.addResponse(expectedResponse); diff --git a/test/integration/goldens/pubsub/com/google/cloud/pubsub/v1/stub/PublisherStubSettings.java b/test/integration/goldens/pubsub/com/google/cloud/pubsub/v1/stub/PublisherStubSettings.java index e5ea4e34bc..166775ec3c 100644 --- a/test/integration/goldens/pubsub/com/google/cloud/pubsub/v1/stub/PublisherStubSettings.java +++ b/test/integration/goldens/pubsub/com/google/cloud/pubsub/v1/stub/PublisherStubSettings.java @@ -490,7 +490,9 @@ public static List getDefaultServiceScopes() { /** Returns a builder for the default credentials for this service. */ public static GoogleCredentialsProvider.Builder defaultCredentialsProviderBuilder() { - return GoogleCredentialsProvider.newBuilder().setScopesToApply(DEFAULT_SERVICE_SCOPES); + return GoogleCredentialsProvider.newBuilder() + .setScopesToApply(DEFAULT_SERVICE_SCOPES) + .setUseJwtAccessWithScope(true); } /** Returns a builder for the default ChannelProvider for this service. */ diff --git a/test/integration/goldens/pubsub/com/google/cloud/pubsub/v1/stub/SchemaServiceStubSettings.java b/test/integration/goldens/pubsub/com/google/cloud/pubsub/v1/stub/SchemaServiceStubSettings.java index 00489c3f74..fb8a87653d 100644 --- a/test/integration/goldens/pubsub/com/google/cloud/pubsub/v1/stub/SchemaServiceStubSettings.java +++ b/test/integration/goldens/pubsub/com/google/cloud/pubsub/v1/stub/SchemaServiceStubSettings.java @@ -254,7 +254,9 @@ public static List getDefaultServiceScopes() { /** Returns a builder for the default credentials for this service. */ public static GoogleCredentialsProvider.Builder defaultCredentialsProviderBuilder() { - return GoogleCredentialsProvider.newBuilder().setScopesToApply(DEFAULT_SERVICE_SCOPES); + return GoogleCredentialsProvider.newBuilder() + .setScopesToApply(DEFAULT_SERVICE_SCOPES) + .setUseJwtAccessWithScope(true); } /** Returns a builder for the default ChannelProvider for this service. */ diff --git a/test/integration/goldens/pubsub/com/google/cloud/pubsub/v1/stub/SubscriberStubSettings.java b/test/integration/goldens/pubsub/com/google/cloud/pubsub/v1/stub/SubscriberStubSettings.java index 00ad4dd1c6..567da1624b 100644 --- a/test/integration/goldens/pubsub/com/google/cloud/pubsub/v1/stub/SubscriberStubSettings.java +++ b/test/integration/goldens/pubsub/com/google/cloud/pubsub/v1/stub/SubscriberStubSettings.java @@ -395,7 +395,9 @@ public static List getDefaultServiceScopes() { /** Returns a builder for the default credentials for this service. */ public static GoogleCredentialsProvider.Builder defaultCredentialsProviderBuilder() { - return GoogleCredentialsProvider.newBuilder().setScopesToApply(DEFAULT_SERVICE_SCOPES); + return GoogleCredentialsProvider.newBuilder() + .setScopesToApply(DEFAULT_SERVICE_SCOPES) + .setUseJwtAccessWithScope(true); } /** Returns a builder for the default ChannelProvider for this service. */ diff --git a/test/integration/goldens/redis/com/google/cloud/redis/v1beta1/stub/CloudRedisStubSettings.java b/test/integration/goldens/redis/com/google/cloud/redis/v1beta1/stub/CloudRedisStubSettings.java index c6e6faa442..b92734fabc 100644 --- a/test/integration/goldens/redis/com/google/cloud/redis/v1beta1/stub/CloudRedisStubSettings.java +++ b/test/integration/goldens/redis/com/google/cloud/redis/v1beta1/stub/CloudRedisStubSettings.java @@ -306,7 +306,9 @@ public static List getDefaultServiceScopes() { /** Returns a builder for the default credentials for this service. */ public static GoogleCredentialsProvider.Builder defaultCredentialsProviderBuilder() { - return GoogleCredentialsProvider.newBuilder().setScopesToApply(DEFAULT_SERVICE_SCOPES); + return GoogleCredentialsProvider.newBuilder() + .setScopesToApply(DEFAULT_SERVICE_SCOPES) + .setUseJwtAccessWithScope(true); } /** Returns a builder for the default ChannelProvider for this service. */ diff --git a/test/integration/goldens/storage/com/google/storage/v2/stub/StorageStubSettings.java b/test/integration/goldens/storage/com/google/storage/v2/stub/StorageStubSettings.java index 7a10ecf5e4..85c8639848 100644 --- a/test/integration/goldens/storage/com/google/storage/v2/stub/StorageStubSettings.java +++ b/test/integration/goldens/storage/com/google/storage/v2/stub/StorageStubSettings.java @@ -157,7 +157,9 @@ public static List getDefaultServiceScopes() { /** Returns a builder for the default credentials for this service. */ public static GoogleCredentialsProvider.Builder defaultCredentialsProviderBuilder() { - return GoogleCredentialsProvider.newBuilder().setScopesToApply(DEFAULT_SERVICE_SCOPES); + return GoogleCredentialsProvider.newBuilder() + .setScopesToApply(DEFAULT_SERVICE_SCOPES) + .setUseJwtAccessWithScope(true); } /** Returns a builder for the default ChannelProvider for this service. */ diff --git a/version.txt b/version.txt index 38f77a65b3..7ec1d6db40 100644 --- a/version.txt +++ b/version.txt @@ -1 +1 @@ -2.0.1 +2.1.0 From d7b29e05d7cfda1eb1a3b09d7ad7d625cab4bde1 Mon Sep 17 00:00:00 2001 From: Gabriel Gonzalez Date: Fri, 3 Sep 2021 19:36:29 -0400 Subject: [PATCH 3/9] Feat: Implement DIREGAPIC LRO annotations (#832) * fix ServiceStub Goldens * fix Stub golden * fix Stub golden * fix CallableFactory golden * fix java format * add annotation placement comments * only add machinery to methods that return operation * add grpc file that contained method that was edited on abstract class * update HttpJsonComplianceStub.golden * java format * add initial methods from annotations * add initial methods from annotations * Implement annotations * java format * fix package for Status * fix CallableFactory generics * java format * initialize new fields in message for parser test * set default value for operation_polling_method * add brackets to if statement * remove comments and invoke methods * add brackets to if statements and remove invoke methods * java formet --- WORKSPACE | 1 + ...ctServiceCallableFactoryClassComposer.java | 16 +- .../AbstractServiceStubClassComposer.java | 41 +- ...pcServiceCallableFactoryClassComposer.java | 9 +- ...onServiceCallableFactoryClassComposer.java | 56 ++- .../HttpJsonServiceStubClassComposer.java | 351 +++++++++++++----- .../api/generator/gapic/model/Message.java | 20 +- .../api/generator/gapic/model/Method.java | 21 +- .../gapic/model/OperationResponse.java | 56 +++ .../generator/gapic/protoparser/BUILD.bazel | 1 + .../generator/gapic/protoparser/Parser.java | 51 +++ .../HttpJsonComplianceCallableFactory.golden | 7 +- .../HttpJsonAddressesCallableFactory.java | 7 +- .../v1/stub/HttpJsonAddressesStub.java | 30 +- ...tpJsonRegionOperationsCallableFactory.java | 7 +- .../v1/stub/HttpJsonRegionOperationsStub.java | 21 +- 16 files changed, 532 insertions(+), 163 deletions(-) create mode 100644 src/main/java/com/google/api/generator/gapic/model/OperationResponse.java diff --git a/WORKSPACE b/WORKSPACE index 21e5f8ea67..cc406611a9 100644 --- a/WORKSPACE +++ b/WORKSPACE @@ -32,6 +32,7 @@ jvm_maven_import_external( # gapic-generator-java dependencies to match the order in googleapis repository, # which in its turn, prioritizes actual generated clients runtime dependencies # over the generator dependencies. + _gax_java_version = "2.3.0" http_archive( 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 b3f4c7ee74..d643c9726b 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 @@ -41,6 +41,7 @@ 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.Method; import com.google.api.generator.gapic.model.Service; import java.util.ArrayList; import java.util.Arrays; @@ -68,6 +69,13 @@ public GapicClass generate(GapicContext context, Service service) { GapicClass.Kind kind = Kind.STUB; String pakkage = String.format("%s.stub", service.pakkage()); + String operationService = ""; + for(Method method : service.methods()) { + if(method.operationService() != null) { + operationService = method.operationService(); + } + } + StubCommentComposer commentComposer = new StubCommentComposer(getTransportContext().transportName()); ClassDefinition classDef = @@ -79,7 +87,7 @@ public GapicClass generate(GapicContext context, Service service) { .setAnnotations(createClassAnnotations(service, typeStore)) .setImplementsTypes(createClassImplements(typeStore)) .setName(className) - .setMethods(createClassMethods(typeStore)) + .setMethods(createClassMethods(typeStore, operationService)) .setScope(ScopeNode.PUBLIC) .build(); return GapicClass.create(kind, classDef); @@ -112,12 +120,12 @@ protected List createClassAnnotations(Service service, TypeStore */ protected abstract List createClassImplements(TypeStore typeStore); - protected List createClassMethods(TypeStore typeStore) { + protected List createClassMethods(TypeStore typeStore, String operationService) { return Arrays.asList( createUnaryCallableMethod(typeStore), createPagedCallableMethod(typeStore), createBatchingCallableMethod(typeStore), - createOperationCallableMethod(typeStore)); + createOperationCallableMethod(typeStore, operationService)); } protected MethodDefinition createUnaryCallableMethod(TypeStore typeStore) { @@ -182,7 +190,7 @@ protected MethodDefinition createBatchingCallableMethod(TypeStore typeStore) { .collect(Collectors.toList())); } - protected abstract MethodDefinition createOperationCallableMethod(TypeStore typeStore); + protected abstract MethodDefinition createOperationCallableMethod(TypeStore typeStore, String operationService); protected MethodDefinition createGenericCallableMethod( TypeStore typeStore, 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 524f8f6361..3202684691 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 @@ -57,6 +57,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.ImmutableList; import com.google.common.collect.ImmutableMap; import com.google.longrunning.Operation; import java.io.IOException; @@ -152,6 +153,12 @@ public GapicClass generate(GapicContext context, Service service) { .setType(getTransportContext().transportOperationsStubType()) .build())); } + + boolean operationPollingMethod = checkOperationPollingMethod(service); + if(operationPollingMethod) { + declareLongRunningClient(classMemberVarExprs); + } + classMemberVarExprs.put( CALLABLE_FACTORY_MEMBER_NAME, VariableExpr.withVariable( @@ -383,7 +390,7 @@ protected List createClassMethods( createOperationsStubGetterMethod(classMemberVarExprs.get(OPERATIONS_STUB_MEMBER_NAME))); javaMethods.addAll(createCallableGetterMethods(callableClassMemberVarExprs)); javaMethods.addAll( - createStubOverrideMethods(classMemberVarExprs.get(BACKGROUND_RESOURCES_MEMBER_NAME))); + createStubOverrideMethods(classMemberVarExprs.get(BACKGROUND_RESOURCES_MEMBER_NAME), service)); return javaMethods; } @@ -625,12 +632,16 @@ protected List createConstructorMethods( secondCtorExprs.clear(); secondCtorStatements.add(EMPTY_LINE_STATEMENT); + + secondCtorStatements.addAll(createLongRunningClient(service, typeStore)); + // Instantiate backgroundResources. MethodInvocationExpr getBackgroundResourcesMethodExpr = MethodInvocationExpr.builder() .setExprReferenceExpr(clientContextVarExpr) .setMethodName("getBackgroundResources") .build(); + VariableExpr backgroundResourcesVarExpr = classMemberVarExprs.get("backgroundResources"); secondCtorExprs.add( AssignmentExpr.builder() @@ -655,6 +666,14 @@ protected List createConstructorMethods( return Arrays.asList(firstCtor, secondCtor); } + protected List createLongRunningClient(Service service, TypeStore typeStore) { + return ImmutableList.of(); + } + + protected void declareLongRunningClient(Map classMemberVarExprs) { + + } + private static Expr createCallableInitExpr( String callableVarName, VariableExpr callableVarExpr, @@ -762,7 +781,7 @@ private static List createCallableGetterMethods( } private List createStubOverrideMethods( - VariableExpr backgroundResourcesVarExpr) { + VariableExpr backgroundResourcesVarExpr, Service service) { Function methodMakerStarterFn = methodName -> MethodDefinition.builder() @@ -826,6 +845,11 @@ private List createStubOverrideMethods( .build()) .build(); List javaMethods = new ArrayList<>(); + //TODO: check for operation polling method + boolean operationPollingMethod = checkOperationPollingMethod(service); + if (operationPollingMethod) { + getterLongRunningClient(javaMethods); + } javaMethods.add( methodMakerStarterFn .apply("close") @@ -898,6 +922,19 @@ private List createStubOverrideMethods( return javaMethods; } + private boolean checkOperationPollingMethod(Service service) { + for(Method method : service.methods()) { + if(method.isOperationPollingMethod()) { + return true; + } + } + return false; + } + + protected void getterLongRunningClient(List javaMethods) { + + } + private TypeStore createDynamicTypes(Service service, String stubPakkage) { TypeStore typeStore = new TypeStore(); typeStore.putAll( 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 5698f5a443..06bb6695b2 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 @@ -45,8 +45,10 @@ protected List createClassImplements(TypeStore typeStore) { return Arrays.asList(getTransportContext().stubCallableFactoryType()); } - protected List createClassMethods(TypeStore typeStore) { - List classMethods = new ArrayList<>(super.createClassMethods(typeStore)); + protected List createClassMethods( + TypeStore typeStore, String operationService) { + List classMethods = + new ArrayList<>(super.createClassMethods(typeStore, operationService)); classMethods.addAll( Arrays.asList( createBidiStreamingCallableMethod(typeStore), @@ -98,7 +100,8 @@ protected MethodDefinition createPagedCallableMethod(TypeStore typeStore) { } @Override - protected MethodDefinition createOperationCallableMethod(TypeStore typeStore) { + protected MethodDefinition createOperationCallableMethod( + TypeStore typeStore, String operationService) { String methodVariantName = "Operation"; String requestTemplateName = "RequestT"; String responseTemplateName = "ResponseT"; diff --git a/src/main/java/com/google/api/generator/gapic/composer/rest/HttpJsonServiceCallableFactoryClassComposer.java b/src/main/java/com/google/api/generator/gapic/composer/rest/HttpJsonServiceCallableFactoryClassComposer.java index 191c1d15fa..919e6c973c 100644 --- a/src/main/java/com/google/api/generator/gapic/composer/rest/HttpJsonServiceCallableFactoryClassComposer.java +++ b/src/main/java/com/google/api/generator/gapic/composer/rest/HttpJsonServiceCallableFactoryClassComposer.java @@ -15,7 +15,6 @@ package com.google.api.generator.gapic.composer.rest; import com.google.api.gax.core.BackgroundResource; -import com.google.api.gax.httpjson.ApiMessage; import com.google.api.gax.httpjson.HttpJsonCallableFactory; import com.google.api.gax.httpjson.HttpJsonOperationSnapshotCallable; import com.google.api.gax.rpc.OperationCallable; @@ -47,7 +46,7 @@ public class HttpJsonServiceCallableFactoryClassComposer new HttpJsonServiceCallableFactoryClassComposer(); private static final TypeNode MESSAGE_TYPE = - TypeNode.withReference(ConcreteReference.withClazz(ApiMessage.class)); + TypeNode.withReference(ConcreteReference.withClazz(Operation.class)); private static final TypeNode BACKGROUND_RESOURCE_TYPE = TypeNode.withReference(ConcreteReference.withClazz(BackgroundResource.class)); @@ -86,7 +85,8 @@ protected List createClassImplements(TypeStore typeStore) { } @Override - protected MethodDefinition createOperationCallableMethod(TypeStore typeStore) { + protected MethodDefinition createOperationCallableMethod( + TypeStore typeStore, String operationService) { String methodVariantName = "Operation"; String requestTemplateName = "RequestT"; String responseTemplateName = "ResponseT"; @@ -104,6 +104,7 @@ protected MethodDefinition createOperationCallableMethod(TypeStore typeStore) { + " future."); // Generate generic method without the body + // TODO: change static usages to vapor references MethodDefinition method = createGenericCallableMethod( typeStore, @@ -119,13 +120,25 @@ protected MethodDefinition createOperationCallableMethod(TypeStore typeStore) { .collect(Collectors.toList()), Arrays.asList(betaAnnotation)); + // if (operationService.equals("")) { + // return method.toBuilder().setReturnExpr(ValueExpr.createNullExpr()).build(); + // } + List createOperationCallableBody = new ArrayList(2); - List arguments = method.arguments(); + List arguments = new ArrayList<>(method.arguments()); + // Variable stubVar = arguments.get(3).variable(); + // stubVar = Variable.builder() + // .setName(stubVar.identifier().name()) + // .setType(typeStore.get(operationService+"Stub")) + // .build(); + // arguments.set(3,VariableExpr.withVariable(stubVar)); + // method = method.toBuilder().setArguments(arguments).build(); + Variable httpJsonCallSettingsVar = arguments.get(0).variable(); - Variable callSettingsVar = arguments.get(1).variable(); + Variable operationCallSettingsVar = arguments.get(1).variable(); Variable clientContextVar = arguments.get(2).variable(); - Variable operationsStub = arguments.get(3).variable(); + Variable operationsStubVar = arguments.get(3).variable(); // Generate innerCallable VariableExpr innerCallableVarExpr = VariableExpr.builder() @@ -139,7 +152,7 @@ protected MethodDefinition createOperationCallableMethod(TypeStore typeStore) { .build(); MethodInvocationExpr getInitialCallSettingsExpr = MethodInvocationExpr.builder() - .setExprReferenceExpr(VariableExpr.withVariable(callSettingsVar)) + .setExprReferenceExpr(VariableExpr.withVariable(operationCallSettingsVar)) .setMethodName("getInitialCallSettings") .build(); MethodInvocationExpr createBaseUnaryCallableExpr = @@ -160,6 +173,20 @@ protected MethodDefinition createOperationCallableMethod(TypeStore typeStore) { .build(); createOperationCallableBody.add(ExprStatement.withExpr(innerCallableAssignExpr)); + // This is a temporary solution + VaporReference requestT = + VaporReference.builder() + .setName("RequestT") + .setPakkage("com.google.cloud.compute.v1.stub") + .build(); + + TypeNode initialCallableType = + TypeNode.withReference( + ConcreteReference.builder() + .setClazz(HttpJsonOperationSnapshotCallable.class) + .setGenerics(requestT, ConcreteReference.withClazz(Operation.class)) + .build()); + // Generate initialCallable VariableExpr initialCallableVarExpr = VariableExpr.builder() @@ -167,9 +194,9 @@ protected MethodDefinition createOperationCallableMethod(TypeStore typeStore) { Variable.builder() .setName("initialCallable") .setType( - TypeNode.withReference(ConcreteReference.withClazz(UnaryCallable.class))) + initialCallableType) // TypeNode.withReference(ConcreteReference.withClazz(UnaryCallable.class))) .build()) - .setTemplateObjects(Arrays.asList(requestTemplateName, methodVariantName)) + // .setTemplateObjects(Arrays.asList(requestTemplateName, "OperationSnapshot")) .build(); MethodInvocationExpr getMethodDescriptorExpr = MethodInvocationExpr.builder() @@ -181,12 +208,7 @@ protected MethodDefinition createOperationCallableMethod(TypeStore typeStore) { .setExprReferenceExpr(getMethodDescriptorExpr) .setMethodName("getOperationSnapshotFactory") .build(); - // This is a temporary solution - VaporReference requestT = - VaporReference.builder() - .setName("RequestT") - .setPakkage("com.google.cloud.compute.v1.stub") - .build(); + TypeNode operationSnapshotCallableType = TypeNode.withReference( ConcreteReference.builder() @@ -209,7 +231,7 @@ protected MethodDefinition createOperationCallableMethod(TypeStore typeStore) { // Generate return statement MethodInvocationExpr longRunningClient = MethodInvocationExpr.builder() - .setExprReferenceExpr(VariableExpr.withVariable(operationsStub)) + .setExprReferenceExpr(VariableExpr.withVariable(operationsStubVar)) .setMethodName("longRunningClient") .build(); MethodInvocationExpr createOperationCallable = @@ -218,7 +240,7 @@ protected MethodDefinition createOperationCallableMethod(TypeStore typeStore) { TypeNode.withReference(ConcreteReference.withClazz(HttpJsonCallableFactory.class))) .setMethodName("createOperationCallable") .setArguments( - VariableExpr.withVariable(callSettingsVar), + VariableExpr.withVariable(operationCallSettingsVar), VariableExpr.withVariable(clientContextVar), longRunningClient, initialCallableVarExpr) diff --git a/src/main/java/com/google/api/generator/gapic/composer/rest/HttpJsonServiceStubClassComposer.java b/src/main/java/com/google/api/generator/gapic/composer/rest/HttpJsonServiceStubClassComposer.java index 66fdfb2b4e..d00e23c5fc 100644 --- a/src/main/java/com/google/api/generator/gapic/composer/rest/HttpJsonServiceStubClassComposer.java +++ b/src/main/java/com/google/api/generator/gapic/composer/rest/HttpJsonServiceStubClassComposer.java @@ -19,12 +19,15 @@ 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.HttpJsonLongRunningClient; import com.google.api.gax.httpjson.HttpJsonOperationSnapshot; 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.gax.longrunning.OperationSnapshot; +import com.google.api.gax.rpc.LongRunningClient; +import com.google.api.gax.rpc.UnaryCallable; import com.google.api.generator.engine.ast.AnnotationNode; import com.google.api.generator.engine.ast.AssignmentExpr; import com.google.api.generator.engine.ast.ConcreteReference; @@ -40,18 +43,22 @@ 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; 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.AbstractServiceStubClassComposer; +import com.google.api.generator.gapic.composer.common.TransportContext; import com.google.api.generator.gapic.composer.store.TypeStore; import com.google.api.generator.gapic.model.HttpBindings.HttpBinding; import com.google.api.generator.gapic.model.Message; import com.google.api.generator.gapic.model.Method; +import com.google.api.generator.gapic.model.OperationResponse; import com.google.api.generator.gapic.model.Service; import com.google.api.generator.gapic.utils.JavaStyle; +import com.google.common.collect.BiMap; import com.google.common.collect.ImmutableList; import java.util.ArrayList; import java.util.Arrays; @@ -124,14 +131,15 @@ protected Statement createMethodDescriptorVariableDecl( methodMaker.apply("setRequestFormatter", getRequestFormatterExpr(protoMethod)).apply(expr); expr = methodMaker.apply("setResponseParser", setResponseParserExpr(protoMethod)).apply(expr); - // System.out.println(protoMethod.outputType().reference().simpleName()); - if (protoMethod.outputType().reference().simpleName().equals("Operation")) { + if (protoMethod.isOperationPollingMethod() || protoMethod.operationService() != null) { expr = methodMaker .apply( "setOperationSnapshotFactory", setOperationSnapshotFactoryExpr(protoMethod, messageTypes)) .apply(expr); + } + if (protoMethod.isOperationPollingMethod()) { expr = methodMaker .apply( @@ -167,6 +175,10 @@ protected List createOperationsStubGetterMethod( return Collections.emptyList(); } + public HttpJsonServiceStubClassComposer(TransportContext transportContext) { + super(transportContext); + } + @Override protected Expr createTransportSettingsInitExpr( Method method, VariableExpr transportSettingsVarExpr, VariableExpr methodDescriptorVarExpr) { @@ -380,9 +392,62 @@ private List setResponseParserExpr(Method protoMethod) { return Collections.singletonList(expr); } + // Generates get[camelCase(fieldName)] + private String getMethodFormat(String fieldName) { + return "get" + JavaStyle.toUpperCamelCase(fieldName); + } + + // Generates set[camelCase(fieldName)] + private String setMethodFormat(String fieldName) { + return "set" + JavaStyle.toUpperCamelCase(fieldName); + } + + // Generates: [nameVar].append(":").append([requestVar].get[FieldName]()); + private ExprStatement appendField( + VariableExpr nameVar, VariableExpr requestVar, String fieldName) { + BiFunction, Function> + methodMaker = getMethodMaker(); + ValueExpr colonValueExpr = + ValueExpr.builder().setValue(StringObjectValue.builder().setValue(":").build()).build(); + MethodInvocationExpr opNameAppendColonExpr = + MethodInvocationExpr.builder() + .setMethodName("append") + .setArguments(colonValueExpr) + .setExprReferenceExpr(nameVar) + .build(); + MethodInvocationExpr getField = + MethodInvocationExpr.builder() + .setExprReferenceExpr(requestVar) + .setMethodName(getMethodFormat(fieldName)) + .build(); + opNameAppendColonExpr = + methodMaker + .apply("append", Collections.singletonList(getField)) + .apply(opNameAppendColonExpr); + return ExprStatement.withExpr(opNameAppendColonExpr); + } + + // returns var.get(num); + private MethodInvocationExpr getExpr(VariableExpr var, String num) { + return MethodInvocationExpr.builder() + .setExprReferenceExpr(var) + .setMethodName("get") + .setArguments( + ValueExpr.builder() + .setValue(PrimitiveValue.builder().setValue(num).setType(TypeNode.INT).build()) + .build()) + .build(); + } + private List setOperationSnapshotFactoryExpr( Method protoMethod, Map messageTypes) { + Message inputOperationMessage = + messageTypes.get(protoMethod.inputType().reference().fullName()); + Message outputOperationMessage = + messageTypes.get(protoMethod.outputType().reference().fullName()); + OperationResponse operationResponse = outputOperationMessage.operationResponse(); + BiFunction, Function> methodMaker = getMethodMaker(); @@ -397,7 +462,6 @@ private List setOperationSnapshotFactoryExpr( List createBody = new ArrayList(4); // Generate opName - // This will be replaced and edited based on annotations TypeNode stringBuilderType = TypeNode.withReference(ConcreteReference.withClazz(StringBuilder.class)); VariableExpr opNameVarExpr = @@ -405,8 +469,8 @@ private List setOperationSnapshotFactoryExpr( Variable.builder().setType(stringBuilderType).setName("opName").build()); MethodInvocationExpr getId = MethodInvocationExpr.builder() - .setMethodName("getId") .setExprReferenceExpr(responseVarExpr) + .setMethodName(getMethodFormat(operationResponse.getNameFieldName())) .build(); Expr opNameObjectExpr = NewObjectExpr.builder().setType(stringBuilderType).setArguments(getId).build(); @@ -417,57 +481,34 @@ private List setOperationSnapshotFactoryExpr( .build(); createBody.add(ExprStatement.withExpr(opNameAssignExpr)); - // Generate changes opName - // This will be replaced and edited based on annotations - MethodInvocationExpr requestGetProjectExpr = - MethodInvocationExpr.builder() - .setMethodName("getProject") - .setExprReferenceExpr(requestVarExpr) - .build(); - ValueExpr colonValueExpr = - ValueExpr.builder().setValue(StringObjectValue.builder().setValue(":").build()).build(); - MethodInvocationExpr opNameAppendColonProjectExpr = - MethodInvocationExpr.builder() - .setMethodName("append") - .setArguments(colonValueExpr) - .setExprReferenceExpr(opNameVarExpr) - .build(); - opNameAppendColonProjectExpr = - methodMaker - .apply("append", Collections.singletonList(requestGetProjectExpr)) - .apply(opNameAppendColonProjectExpr); - createBody.add(ExprStatement.withExpr(opNameAppendColonProjectExpr)); - - // Generate changes to opName - MethodInvocationExpr requestGetRegionExpr = - MethodInvocationExpr.builder() - .setMethodName("getRegion") - .setExprReferenceExpr(requestVarExpr) - .build(); - MethodInvocationExpr opNameAppendColonRegionExpr = - MethodInvocationExpr.builder() - .setMethodName("append") - .setArguments(colonValueExpr) - .setExprReferenceExpr(opNameVarExpr) - .build(); - opNameAppendColonRegionExpr = - methodMaker - .apply("append", Collections.singletonList(requestGetRegionExpr)) - .apply(opNameAppendColonRegionExpr); - createBody.add(ExprStatement.withExpr(opNameAppendColonRegionExpr)); + // Generate compound operation name + if (!protoMethod.isOperationPollingMethod()) { + // TODO: Change to ordered map + Map requestFields = inputOperationMessage.operationRequestFields(); + List fieldAnnotationNames = new ArrayList(requestFields.keySet()); + Collections.sort(fieldAnnotationNames); + for (String fieldName : fieldAnnotationNames) { + createBody.add(appendField(opNameVarExpr, requestVarExpr, requestFields.get(fieldName))); + } + } - // Generate check status expression - // This will be replaced and edited based on annotations + // Generate check for status == done MethodInvocationExpr getStatusExpr = MethodInvocationExpr.builder() .setExprReferenceExpr(responseVarExpr) - .setMethodName("getStatus") + .setMethodName(getMethodFormat(operationResponse.getStatusFieldName())) .build(); + + String statusTypeName = operationResponse.getStatusFieldTypeName(); + String statusClassName = statusTypeName.substring(statusTypeName.lastIndexOf('.') + 1); + String statusPackage = protoMethod.servicePackage(); // "com" + + // statusTypeName.substring(0,statusTypeName.lastIndexOf('.')); + TypeNode statusType = TypeNode.withReference( VaporReference.builder() - .setName("Status") - .setPakkage("com.google.cloud.compute.v1") + .setName(statusClassName) + .setPakkage(statusPackage + "." + protoMethod.outputType().reference().simpleName()) .setIsStaticImport(false) .build()); VariableExpr statusDoneExpr = @@ -476,33 +517,38 @@ private List setOperationSnapshotFactoryExpr( .setStaticReferenceType(statusType) .build(); MethodInvocationExpr statusEqualsExpr = - methodMaker.apply("equals", Collections.singletonList(statusDoneExpr)).apply(getStatusExpr); + MethodInvocationExpr.builder() + .setExprReferenceExpr(statusDoneExpr) + .setMethodName("equals") + .setArguments(getStatusExpr) + .build(); // Generate return statement TypeNode httpJsonOperationSnapshotType = TypeNode.withReference(ConcreteReference.withClazz(HttpJsonOperationSnapshot.class)); - MethodInvocationExpr newBuilderExpr = - MethodInvocationExpr.builder() - .setStaticReferenceType(httpJsonOperationSnapshotType) - .setMethodName("newBuilder") - .build(); + + // Generate getter methods from annotations MethodInvocationExpr opNameToStringExpr = MethodInvocationExpr.builder() - .setMethodName("toString") .setExprReferenceExpr(opNameVarExpr) + .setMethodName("toString") .build(); - // This will be replaced and edited based on annotations MethodInvocationExpr getHttpErrorStatusCodeExpr = MethodInvocationExpr.builder() .setExprReferenceExpr(responseVarExpr) - .setMethodName("getHttpErrorStatusCode") + .setMethodName(getMethodFormat(operationResponse.getErrorCodeFieldName())) .build(); - // This will be replaced and edited based on annotations MethodInvocationExpr getHttpErrorMessageExpr = MethodInvocationExpr.builder() .setExprReferenceExpr(responseVarExpr) - .setMethodName("getHttpErrorMessage") + .setMethodName(getMethodFormat(operationResponse.getErrorMessageFieldName())) .build(); + MethodInvocationExpr newBuilderExpr = + MethodInvocationExpr.builder() + .setStaticReferenceType(httpJsonOperationSnapshotType) + .setMethodName("newBuilder") + .build(); + newBuilderExpr = methodMaker .apply("setName", Collections.singletonList(opNameToStringExpr)) @@ -546,10 +592,12 @@ private List setOperationSnapshotFactoryExpr( private List setPollingRequestFactoryExpr( Method protoMethod, Map messageTypes) { - BiFunction, Function> methodMaker = getMethodMaker(); + Message inputOperationMessage = + messageTypes.get(protoMethod.inputType().reference().fullName()); + List createBody = new ArrayList(1); // Generate input variables for create @@ -598,36 +646,49 @@ private List setPollingRequestFactoryExpr( createBody.add(ExprStatement.withExpr(idComponentsAssignExpr)); // Generate return statement - // This will be replaced and edited based on annotations - TypeNode getRegionOperationRequestType = - TypeNode.withReference( - VaporReference.builder() - .setName("GetRegionOperationRequest") - .setPakkage("com.google.cloud.compute.v1") - .setIsStaticImport(false) - .build()); + TypeNode getOperationRequestType = TypeNode.withReference(protoMethod.inputType().reference()); MethodInvocationExpr newBuilderExpr = MethodInvocationExpr.builder() - .setStaticReferenceType(getRegionOperationRequestType) + .setStaticReferenceType(getOperationRequestType) .setMethodName("newBuilder") .build(); - newBuilderExpr = - methodMaker - .apply("setOperation", Collections.singletonList(getExpr(idComponentsVarExpr, "0"))) - .apply(newBuilderExpr); - newBuilderExpr = - methodMaker - .apply("setProject", Collections.singletonList(getExpr(idComponentsVarExpr, "1"))) - .apply(newBuilderExpr); - newBuilderExpr = - methodMaker - .apply("setRegion", Collections.singletonList(getExpr(idComponentsVarExpr, "2"))) - .apply(newBuilderExpr); + BiMap responseFieldsMap = inputOperationMessage.operationResponseFields(); + List responseFieldAnnotationNames = new ArrayList(responseFieldsMap.keySet()); + Collections.sort(responseFieldAnnotationNames); + Set responseFieldsNames = responseFieldsMap.inverse().keySet(); + Set allFieldsNames = inputOperationMessage.fieldMap().keySet(); + ArrayList nonResponseFieldsNames = new ArrayList(); + for (String fieldName : allFieldsNames) { + if (!responseFieldsNames.contains(fieldName)) { + nonResponseFieldsNames.add(fieldName); + } + } + Collections.sort(nonResponseFieldsNames); + int index = 0; + for (String fieldAnnotationName : responseFieldAnnotationNames) { + newBuilderExpr = + methodMaker + .apply( + setMethodFormat(responseFieldsMap.get(fieldAnnotationName)), + Collections.singletonList(getExpr(idComponentsVarExpr, Integer.toString(index)))) + .apply(newBuilderExpr); + index++; + } + for (String fieldName : nonResponseFieldsNames) { + newBuilderExpr = + methodMaker + .apply( + setMethodFormat(fieldName), + Collections.singletonList(getExpr(idComponentsVarExpr, Integer.toString(index)))) + .apply(newBuilderExpr); + index++; + } + MethodInvocationExpr buildExpr = MethodInvocationExpr.builder() .setExprReferenceExpr(newBuilderExpr) .setMethodName("build") - .setReturnType(getRegionOperationRequestType) + .setReturnType(getOperationRequestType) .build(); // Return lambda anonymous class @@ -639,18 +700,6 @@ private List setPollingRequestFactoryExpr( .build()); } - // returns var.get(num); - private MethodInvocationExpr getExpr(VariableExpr var, String num) { - return MethodInvocationExpr.builder() - .setExprReferenceExpr(var) - .setMethodName("get") - .setArguments( - ValueExpr.builder() - .setValue(PrimitiveValue.builder().setValue(num).setType(TypeNode.INT).build()) - .build()) - .build(); - } - private Expr createFieldsExtractorClassInstance( Method method, TypeNode extractorReturnType, @@ -809,4 +858,120 @@ private List getHttpMethodTypeExpr(Method protoMethod) { .build(); return Collections.singletonList(expr); } + + @Override + protected List createLongRunningClient(Service service, TypeStore typeStore) { + boolean operation_polling_method = false; + Method protoMethod = null; + for (Method method : service.methods()) { + if (method.isOperationPollingMethod()) { + protoMethod = method; + operation_polling_method = true; + break; + } + } + if (operation_polling_method) { + Expr thisExpr = + ValueExpr.withValue( + ThisObjectValue.withType( + typeStore.get( + getTransportContext() + .classNames() + .getTransportServiceStubClassName(service)))); + + VariableExpr callable = + VariableExpr.withVariable( + Variable.builder() + .setName(protoMethod.name().toLowerCase() + "Callable") + .setType(TypeNode.withReference(ConcreteReference.withClazz(UnaryCallable.class))) + .build()); + VariableExpr methodDescriptor = + VariableExpr.withVariable( + Variable.builder() + .setName(protoMethod.name().toLowerCase() + "MethodDescriptor") + .setType( + TypeNode.withReference( + ConcreteReference.withClazz(ApiMethodDescriptor.class))) + .build()); + + TypeNode httpJsonLongRunningClientType = + TypeNode.withReference( + ConcreteReference.builder() + .setClazz(HttpJsonLongRunningClient.class) + .setGenerics( + Arrays.asList( + protoMethod.inputType().reference(), + protoMethod.outputType().reference())) + .build()); + + NewObjectExpr HttpJsonLongRunningClient = + NewObjectExpr.builder() + .setType(httpJsonLongRunningClientType) + .setArguments( + Arrays.asList( + callable, + MethodInvocationExpr.builder() + .setExprReferenceExpr(methodDescriptor) + .setMethodName("getOperationSnapshotFactory") + .build(), + MethodInvocationExpr.builder() + .setExprReferenceExpr(methodDescriptor) + .setMethodName("getPollingRequestFactory") + .build())) + .build(); + + AssignmentExpr assignLongRunningClient = + AssignmentExpr.builder() + .setVariableExpr( + VariableExpr.builder() + .setExprReferenceExpr(thisExpr) + .setVariable( + Variable.builder() + .setName("longRunningClient") + .setType( + TypeNode.withReference( + ConcreteReference.withClazz(LongRunningClient.class))) + .build()) + .build()) + .setValueExpr(HttpJsonLongRunningClient) + .build(); + + return Arrays.asList(ExprStatement.withExpr(assignLongRunningClient)); + } else { + return Collections.emptyList(); + } + } + + @Override + protected void declareLongRunningClient(Map classMemberVarExprs) { + classMemberVarExprs.put( + "longRunningClient", + VariableExpr.withVariable( + Variable.builder() + .setName("longRunningClient") + .setType( + TypeNode.withReference(ConcreteReference.withClazz(LongRunningClient.class))) + .build())); + } + + @Override + protected void getterLongRunningClient(List javaMethods) { + VariableExpr longRunningClient = + VariableExpr.withVariable( + Variable.builder() + .setName("longRunningClient") + .setType( + TypeNode.withReference(ConcreteReference.withClazz(LongRunningClient.class))) + .build()); + + javaMethods.add( + MethodDefinition.builder() + .setName("longRunningClient") + .setScope(ScopeNode.PUBLIC) + .setIsOverride(true) + .setReturnType( + TypeNode.withReference(ConcreteReference.withClazz(LongRunningClient.class))) + .setReturnExpr(longRunningClient) + .build()); + } } diff --git a/src/main/java/com/google/api/generator/gapic/model/Message.java b/src/main/java/com/google/api/generator/gapic/model/Message.java index c58e62582e..51245444fe 100644 --- a/src/main/java/com/google/api/generator/gapic/model/Message.java +++ b/src/main/java/com/google/api/generator/gapic/model/Message.java @@ -18,6 +18,8 @@ import com.google.api.generator.engine.ast.Reference; import com.google.api.generator.engine.ast.TypeNode; import com.google.auto.value.AutoValue; +import com.google.common.collect.BiMap; +import com.google.common.collect.HashBiMap; import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableMap; import java.util.Arrays; @@ -51,6 +53,12 @@ public abstract class Message { public abstract ImmutableMap fieldMap(); + public abstract OperationResponse operationResponse(); + + public abstract Map operationRequestFields(); + + public abstract BiMap operationResponseFields(); + // The resource name annotation (and definition) in this message. Optional. // Expected dto be empty for messages that have no such definition. @Nullable @@ -103,7 +111,10 @@ public static Builder builder() { .setOuterNestedTypes(Collections.emptyList()) .setFields(Collections.emptyList()) .setFieldMap(Collections.emptyMap()) - .setEnumValues(Collections.emptyMap()); + .setEnumValues(Collections.emptyMap()) + .setOperationResponseFields(HashBiMap.create()) + .setOperationRequestFields(Collections.emptyMap()) + .setOperationResponse(OperationResponse.builder().build()); } @AutoValue.Builder @@ -129,6 +140,13 @@ public Builder setEnumValues(List names, List numbers) { public abstract Builder setOuterNestedTypes(List outerNestedTypes); + public abstract Builder setOperationResponse(OperationResponse operationResponse); + + public abstract Builder setOperationRequestFields(Map operationRequestFields); + + public abstract Builder setOperationResponseFields( + BiMap operationRequestFields); + abstract Builder setFieldMap(Map fieldMap); abstract ImmutableList fields(); 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 56a1403098..aaf3f4a596 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 @@ -66,6 +66,14 @@ public boolean isPaged() { // [["content", "error"], ["content", "error", "info"]]. public abstract ImmutableList> methodSignatures(); + public abstract boolean operationPollingMethod(); + + @Nullable + public abstract String operationService(); + + @Nullable + public abstract String servicePackage(); + public boolean hasLro() { return lro() != null; } @@ -82,6 +90,10 @@ public boolean isMixin() { return mixedInApiName() != null; } + public boolean isOperationPollingMethod() { + return operationPollingMethod(); + } + public abstract Builder toBuilder(); public static Builder builder() { @@ -89,7 +101,8 @@ public static Builder builder() { .setStream(Stream.NONE) .setMethodSignatures(ImmutableList.of()) .setIsBatching(false) - .setIsDeprecated(false); + .setIsDeprecated(false) + .setOperationPollingMethod(false); } public static Stream toStream(boolean isClientStreaming, boolean isServerStreaming) { @@ -131,6 +144,12 @@ public abstract static class Builder { public abstract Builder setIsDeprecated(boolean isDeprecated); + public abstract Builder setOperationPollingMethod(boolean operationPollingMethod); + + public abstract Builder setOperationService(String operationService); + + public abstract Builder setServicePackage(String servicePackage); + public abstract Method build(); } } diff --git a/src/main/java/com/google/api/generator/gapic/model/OperationResponse.java b/src/main/java/com/google/api/generator/gapic/model/OperationResponse.java new file mode 100644 index 0000000000..1a141479ac --- /dev/null +++ b/src/main/java/com/google/api/generator/gapic/model/OperationResponse.java @@ -0,0 +1,56 @@ +/* + * 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; + +import com.google.auto.value.AutoValue; +import javax.annotation.Nullable; + +@AutoValue +public abstract class OperationResponse { + @Nullable + public abstract String getNameFieldName(); + + @Nullable + public abstract String getStatusFieldName(); + + @Nullable + public abstract String getErrorCodeFieldName(); + + @Nullable + public abstract String getErrorMessageFieldName(); + + @Nullable + public abstract String getStatusFieldTypeName(); + + public static Builder builder() { + return new AutoValue_OperationResponse.Builder(); + } + + @AutoValue.Builder + public abstract static class Builder { + public abstract Builder setNameFieldName(String nameFieldName); + + public abstract Builder setStatusFieldName(String val); + + public abstract Builder setErrorCodeFieldName(String val); + + public abstract Builder setErrorMessageFieldName(String val); + + public abstract Builder setStatusFieldTypeName(String className); + + public abstract OperationResponse build(); + } +} diff --git a/src/main/java/com/google/api/generator/gapic/protoparser/BUILD.bazel b/src/main/java/com/google/api/generator/gapic/protoparser/BUILD.bazel index 6cccdd373a..904b7fbf2b 100644 --- a/src/main/java/com/google/api/generator/gapic/protoparser/BUILD.bazel +++ b/src/main/java/com/google/api/generator/gapic/protoparser/BUILD.bazel @@ -30,6 +30,7 @@ java_library( "@com_google_code_findbugs_jsr305//jar", "@com_google_code_gson//jar", "@com_google_googleapis//google/api:api_java_proto", + "@com_google_googleapis//google/cloud:extended_operations_java_proto", "@com_google_googleapis//google/longrunning:longrunning_java_proto", "@com_google_guava_guava//jar", "@com_google_protobuf//:protobuf_java", 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 42e2abaa2f..0fdbb86c2b 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 @@ -30,15 +30,20 @@ import com.google.api.generator.gapic.model.LongrunningOperation; import com.google.api.generator.gapic.model.Message; import com.google.api.generator.gapic.model.Method; +import com.google.api.generator.gapic.model.OperationResponse; import com.google.api.generator.gapic.model.ResourceName; 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.cloud.ExtendedOperationsProto; +import com.google.cloud.OperationResponseMapping; import com.google.common.annotations.VisibleForTesting; import com.google.common.base.Preconditions; import com.google.common.base.Strings; +import com.google.common.collect.BiMap; +import com.google.common.collect.HashBiMap; import com.google.common.collect.ImmutableSet; import com.google.common.collect.Maps; import com.google.longrunning.OperationInfo; @@ -554,6 +559,35 @@ private static Map parseMessages( } } TypeNode messageType = TypeParser.parseType(messageDescriptor); + + List fields = messageDescriptor.getFields(); + HashMap operationRequestFields = new HashMap(); + BiMap operationResponseFields = HashBiMap.create(); + OperationResponse.Builder operationResponse = OperationResponse.builder(); + for (FieldDescriptor fd : fields) { + if (fd.getOptions().hasExtension(ExtendedOperationsProto.operationRequestField)) { + String orf = fd.getOptions().getExtension(ExtendedOperationsProto.operationRequestField); + operationRequestFields.put(orf, fd.getName()); + } + if (fd.getOptions().hasExtension(ExtendedOperationsProto.operationResponseField)) { + String orf = fd.getOptions().getExtension(ExtendedOperationsProto.operationResponseField); + operationResponseFields.put(orf, fd.getName()); + } + if (fd.getOptions().hasExtension(ExtendedOperationsProto.operationField)) { + OperationResponseMapping orm = + fd.getOptions().getExtension(ExtendedOperationsProto.operationField); + if (orm.equals(OperationResponseMapping.NAME)) { + operationResponse.setNameFieldName(fd.getName()); + } else if (orm.equals(OperationResponseMapping.STATUS)) { + operationResponse.setStatusFieldName(fd.getName()); + operationResponse.setStatusFieldTypeName(fd.toProto().getTypeName()); + } else if (orm.equals(OperationResponseMapping.ERROR_CODE)) { + operationResponse.setErrorCodeFieldName(fd.getName()); + } else if (orm.equals(OperationResponseMapping.ERROR_MESSAGE)) { + operationResponse.setErrorMessageFieldName(fd.getName()); + } + } + } messages.put( messageType.reference().fullName(), Message.builder() @@ -562,6 +596,9 @@ private static Map parseMessages( .setFullProtoName(messageDescriptor.getFullName()) .setFields(parseFields(messageDescriptor, outputResourceReferencesSeen)) .setOuterNestedTypes(outerNestedTypes) + .setOperationRequestFields(operationRequestFields) + .setOperationResponseFields(operationResponseFields) + .setOperationResponse(operationResponse.build()) .build()); return messages; } @@ -664,6 +701,17 @@ static List parseMethods( serviceDescriptor.getName(), protoMethod.getName()); + boolean operationPollingMethod = + protoMethod.getOptions().hasExtension(ExtendedOperationsProto.operationPollingMethod) + ? protoMethod + .getOptions() + .getExtension(ExtendedOperationsProto.operationPollingMethod) + : false; + String operationService = + protoMethod.getOptions().hasExtension(ExtendedOperationsProto.operationService) + ? protoMethod.getOptions().getExtension(ExtendedOperationsProto.operationService) + : null; + methods.add( methodBuilder .setName(protoMethod.getName()) @@ -684,6 +732,9 @@ static List parseMethods( .setIsBatching(isBatching) .setPageSizeFieldName(parsePageSizeFieldName(protoMethod, messageTypes, transport)) .setIsDeprecated(isDeprecated) + .setOperationPollingMethod(operationPollingMethod) + .setOperationService(operationService) + .setServicePackage(servicePackage) .build()); // Any input type that has a resource reference will need a resource name helper class. diff --git a/src/test/java/com/google/api/generator/gapic/composer/rest/goldens/HttpJsonComplianceCallableFactory.golden b/src/test/java/com/google/api/generator/gapic/composer/rest/goldens/HttpJsonComplianceCallableFactory.golden index 0b58310417..f2b65c4025 100644 --- a/src/test/java/com/google/api/generator/gapic/composer/rest/goldens/HttpJsonComplianceCallableFactory.golden +++ b/src/test/java/com/google/api/generator/gapic/composer/rest/goldens/HttpJsonComplianceCallableFactory.golden @@ -2,7 +2,6 @@ package com.google.showcase.v1beta1.stub; import com.google.api.core.BetaApi; 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.HttpJsonOperationSnapshotCallable; @@ -27,7 +26,7 @@ import javax.annotation.Generated; @BetaApi @Generated("by gapic-generator-java") public class HttpJsonComplianceCallableFactory - implements HttpJsonStubCallableFactory { + implements HttpJsonStubCallableFactory { @Override public UnaryCallable createUnaryCallable( @@ -62,14 +61,14 @@ public class HttpJsonComplianceCallableFactory @Override public OperationCallable createOperationCallable( - HttpJsonCallSettings httpJsonCallSettings, + HttpJsonCallSettings httpJsonCallSettings, OperationCallSettings callSettings, ClientContext clientContext, BackgroundResource operationsStub) { UnaryCallable innerCallable = HttpJsonCallableFactory.createBaseUnaryCallable( httpJsonCallSettings, callSettings.getInitialCallSettings(), clientContext); - UnaryCallable initialCallable = + HttpJsonOperationSnapshotCallable initialCallable = new HttpJsonOperationSnapshotCallable( innerCallable, httpJsonCallSettings.getMethodDescriptor().getOperationSnapshotFactory()); diff --git a/test/integration/goldens/compute/com/google/cloud/compute/v1/stub/HttpJsonAddressesCallableFactory.java b/test/integration/goldens/compute/com/google/cloud/compute/v1/stub/HttpJsonAddressesCallableFactory.java index 49347e5792..b9e0385e12 100644 --- a/test/integration/goldens/compute/com/google/cloud/compute/v1/stub/HttpJsonAddressesCallableFactory.java +++ b/test/integration/goldens/compute/com/google/cloud/compute/v1/stub/HttpJsonAddressesCallableFactory.java @@ -18,7 +18,6 @@ import com.google.api.core.BetaApi; 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.HttpJsonOperationSnapshotCallable; @@ -42,7 +41,7 @@ @Generated("by gapic-generator-java") @BetaApi public class HttpJsonAddressesCallableFactory - implements HttpJsonStubCallableFactory { + implements HttpJsonStubCallableFactory { @Override public UnaryCallable createUnaryCallable( @@ -77,14 +76,14 @@ public UnaryCallable createBatchingCa @Override public OperationCallable createOperationCallable( - HttpJsonCallSettings httpJsonCallSettings, + HttpJsonCallSettings httpJsonCallSettings, OperationCallSettings callSettings, ClientContext clientContext, BackgroundResource operationsStub) { UnaryCallable innerCallable = HttpJsonCallableFactory.createBaseUnaryCallable( httpJsonCallSettings, callSettings.getInitialCallSettings(), clientContext); - UnaryCallable initialCallable = + HttpJsonOperationSnapshotCallable initialCallable = new HttpJsonOperationSnapshotCallable( innerCallable, httpJsonCallSettings.getMethodDescriptor().getOperationSnapshotFactory()); diff --git a/test/integration/goldens/compute/com/google/cloud/compute/v1/stub/HttpJsonAddressesStub.java b/test/integration/goldens/compute/com/google/cloud/compute/v1/stub/HttpJsonAddressesStub.java index e2d4a26060..d79d2cc64a 100644 --- a/test/integration/goldens/compute/com/google/cloud/compute/v1/stub/HttpJsonAddressesStub.java +++ b/test/integration/goldens/compute/com/google/cloud/compute/v1/stub/HttpJsonAddressesStub.java @@ -38,14 +38,12 @@ import com.google.cloud.compute.v1.AddressList; import com.google.cloud.compute.v1.AggregatedListAddressesRequest; import com.google.cloud.compute.v1.DeleteAddressRequest; -import com.google.cloud.compute.v1.GetRegionOperationRequest; import com.google.cloud.compute.v1.InsertAddressRequest; import com.google.cloud.compute.v1.ListAddressesRequest; import com.google.cloud.compute.v1.Operation; -import com.google.cloud.compute.v1.Status; +import com.google.cloud.compute.v1.Operation.Status; import java.io.IOException; import java.util.ArrayList; -import java.util.Arrays; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -144,26 +142,17 @@ public class HttpJsonAddressesStub extends AddressesStub { .build()) .setOperationSnapshotFactory( (DeleteAddressRequest request, Operation response) -> { - StringBuilder opName = new StringBuilder(response.getId()); + StringBuilder opName = new StringBuilder(response.getName()); opName.append(":").append(request.getProject()); opName.append(":").append(request.getRegion()); return HttpJsonOperationSnapshot.newBuilder() .setName(opName.toString()) .setMetadata(response) - .setDone(response.getStatus().equals(Status.DONE)) + .setDone(Status.DONE.equals(response.getStatus())) .setResponse(response) .setError(response.getHttpErrorStatusCode(), response.getHttpErrorMessage()) .build(); }) - .setPollingRequestFactory( - compoundOperationId -> { - List idComponents = Arrays.asList(compoundOperationId.split(":")); - return GetRegionOperationRequest.newBuilder() - .setOperation(idComponents.get(0)) - .setProject(idComponents.get(1)) - .setRegion(idComponents.get(2)) - .build(); - }) .build(); private static final ApiMethodDescriptor insertMethodDescriptor = @@ -203,26 +192,17 @@ public class HttpJsonAddressesStub extends AddressesStub { .build()) .setOperationSnapshotFactory( (InsertAddressRequest request, Operation response) -> { - StringBuilder opName = new StringBuilder(response.getId()); + StringBuilder opName = new StringBuilder(response.getName()); opName.append(":").append(request.getProject()); opName.append(":").append(request.getRegion()); return HttpJsonOperationSnapshot.newBuilder() .setName(opName.toString()) .setMetadata(response) - .setDone(response.getStatus().equals(Status.DONE)) + .setDone(Status.DONE.equals(response.getStatus())) .setResponse(response) .setError(response.getHttpErrorStatusCode(), response.getHttpErrorMessage()) .build(); }) - .setPollingRequestFactory( - compoundOperationId -> { - List idComponents = Arrays.asList(compoundOperationId.split(":")); - return GetRegionOperationRequest.newBuilder() - .setOperation(idComponents.get(0)) - .setProject(idComponents.get(1)) - .setRegion(idComponents.get(2)) - .build(); - }) .build(); private static final ApiMethodDescriptor listMethodDescriptor = diff --git a/test/integration/goldens/compute/com/google/cloud/compute/v1/stub/HttpJsonRegionOperationsCallableFactory.java b/test/integration/goldens/compute/com/google/cloud/compute/v1/stub/HttpJsonRegionOperationsCallableFactory.java index 6113b5f496..b775dbba59 100644 --- a/test/integration/goldens/compute/com/google/cloud/compute/v1/stub/HttpJsonRegionOperationsCallableFactory.java +++ b/test/integration/goldens/compute/com/google/cloud/compute/v1/stub/HttpJsonRegionOperationsCallableFactory.java @@ -18,7 +18,6 @@ import com.google.api.core.BetaApi; 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.HttpJsonOperationSnapshotCallable; @@ -42,7 +41,7 @@ @Generated("by gapic-generator-java") @BetaApi public class HttpJsonRegionOperationsCallableFactory - implements HttpJsonStubCallableFactory { + implements HttpJsonStubCallableFactory { @Override public UnaryCallable createUnaryCallable( @@ -77,14 +76,14 @@ public UnaryCallable createBatchingCa @Override public OperationCallable createOperationCallable( - HttpJsonCallSettings httpJsonCallSettings, + HttpJsonCallSettings httpJsonCallSettings, OperationCallSettings callSettings, ClientContext clientContext, BackgroundResource operationsStub) { UnaryCallable innerCallable = HttpJsonCallableFactory.createBaseUnaryCallable( httpJsonCallSettings, callSettings.getInitialCallSettings(), clientContext); - UnaryCallable initialCallable = + HttpJsonOperationSnapshotCallable initialCallable = new HttpJsonOperationSnapshotCallable( innerCallable, httpJsonCallSettings.getMethodDescriptor().getOperationSnapshotFactory()); diff --git a/test/integration/goldens/compute/com/google/cloud/compute/v1/stub/HttpJsonRegionOperationsStub.java b/test/integration/goldens/compute/com/google/cloud/compute/v1/stub/HttpJsonRegionOperationsStub.java index 47bc6a36a7..1949dd2c60 100644 --- a/test/integration/goldens/compute/com/google/cloud/compute/v1/stub/HttpJsonRegionOperationsStub.java +++ b/test/integration/goldens/compute/com/google/cloud/compute/v1/stub/HttpJsonRegionOperationsStub.java @@ -23,6 +23,7 @@ import com.google.api.gax.core.BackgroundResourceAggregation; import com.google.api.gax.httpjson.ApiMethodDescriptor; import com.google.api.gax.httpjson.HttpJsonCallSettings; +import com.google.api.gax.httpjson.HttpJsonLongRunningClient; import com.google.api.gax.httpjson.HttpJsonOperationSnapshot; import com.google.api.gax.httpjson.HttpJsonStubCallableFactory; import com.google.api.gax.httpjson.ProtoMessageRequestFormatter; @@ -30,10 +31,11 @@ import com.google.api.gax.httpjson.ProtoRestSerializer; import com.google.api.gax.longrunning.OperationSnapshot; import com.google.api.gax.rpc.ClientContext; +import com.google.api.gax.rpc.LongRunningClient; import com.google.api.gax.rpc.UnaryCallable; import com.google.cloud.compute.v1.GetRegionOperationRequest; import com.google.cloud.compute.v1.Operation; -import com.google.cloud.compute.v1.Status; +import com.google.cloud.compute.v1.Operation.Status; import java.io.IOException; import java.util.ArrayList; import java.util.Arrays; @@ -85,13 +87,11 @@ public class HttpJsonRegionOperationsStub extends RegionOperationsStub { .build()) .setOperationSnapshotFactory( (GetRegionOperationRequest request, Operation response) -> { - StringBuilder opName = new StringBuilder(response.getId()); - opName.append(":").append(request.getProject()); - opName.append(":").append(request.getRegion()); + StringBuilder opName = new StringBuilder(response.getName()); return HttpJsonOperationSnapshot.newBuilder() .setName(opName.toString()) .setMetadata(response) - .setDone(response.getStatus().equals(Status.DONE)) + .setDone(Status.DONE.equals(response.getStatus())) .setResponse(response) .setError(response.getHttpErrorStatusCode(), response.getHttpErrorMessage()) .build(); @@ -110,6 +110,7 @@ public class HttpJsonRegionOperationsStub extends RegionOperationsStub { private final UnaryCallable getCallable; private final BackgroundResource backgroundResources; + private final LongRunningClient longRunningClient; private final HttpJsonStubCallableFactory callableFactory; public static final HttpJsonRegionOperationsStub create(RegionOperationsStubSettings settings) @@ -160,6 +161,11 @@ protected HttpJsonRegionOperationsStub( callableFactory.createUnaryCallable( getTransportSettings, settings.getSettings(), clientContext); + this.longRunningClient = + new HttpJsonLongRunningClient( + getCallable, + getMethodDescriptor.getOperationSnapshotFactory(), + getMethodDescriptor.getPollingRequestFactory()); this.backgroundResources = new BackgroundResourceAggregation(clientContext.getBackgroundResources()); } @@ -176,6 +182,11 @@ public UnaryCallable getCallable() { return getCallable; } + @Override + public LongRunningClient longRunningClient() { + return longRunningClient; + } + @Override public final void close() { try { From 957f69a0dc063e77b5e49da28f0a6d9a4a6c3bdb Mon Sep 17 00:00:00 2001 From: Vadym Matsishevskyi <25311427+vam-google@users.noreply.github.com> Date: Mon, 6 Sep 2021 14:01:46 -0700 Subject: [PATCH 4/9] fix: fix diregapic-lro logic (#834) There are 2 more things left: 1) longRunnignOperation() getter method on the transport-agnostic (parent) class 2) proper (transport-specific) Response and Metadata transformers for OperationSettings initialization --- ...ctServiceCallableFactoryClassComposer.java | 55 ++++++---- .../AbstractServiceStubClassComposer.java | 50 ++++++--- .../common/ServiceClientClassComposer.java | 6 +- .../common/ServiceStubClassComposer.java | 10 +- ...pcServiceCallableFactoryClassComposer.java | 38 ++++--- ...onServiceCallableFactoryClassComposer.java | 47 ++++---- .../HttpJsonServiceStubClassComposer.java | 56 ++++------ .../gapic/model/LongrunningOperation.java | 20 ++-- .../api/generator/gapic/model/Method.java | 10 -- .../gapic/model/OperationResponse.java | 10 +- .../api/generator/gapic/model/Service.java | 30 ++++++ .../generator/gapic/protoparser/Parser.java | 60 +++++++---- .../HttpJsonComplianceCallableFactory.golden | 1 - .../ServiceClientSampleCodeComposerTest.java | 60 +++++++++-- .../gapic/protoparser/ParserTest.java | 4 +- .../cloud/compute/v1/AddressesClient.java | 89 +++++++++++++--- .../cloud/compute/v1/AddressesClientTest.java | 43 +++++--- .../cloud/compute/v1/AddressesSettings.java | 31 +++++- .../cloud/compute/v1/gapic_metadata.json | 4 +- .../google/cloud/compute/v1/package-info.java | 7 +- .../cloud/compute/v1/stub/AddressesStub.java | 13 +++ .../v1/stub/AddressesStubSettings.java | 100 +++++++++++++++++- .../HttpJsonAddressesCallableFactory.java | 7 +- .../v1/stub/HttpJsonAddressesStub.java | 29 +++++ 24 files changed, 562 insertions(+), 218 deletions(-) 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 d643c9726b..ea3898051c 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 @@ -41,7 +41,6 @@ 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.Method; import com.google.api.generator.gapic.model.Service; import java.util.ArrayList; import java.util.Arrays; @@ -63,19 +62,13 @@ protected TransportContext getTransportContext() { @Override public GapicClass generate(GapicContext context, Service service) { - TypeStore typeStore = createTypes(); + TypeStore typeStore = createTypes(service); + String className = getTransportContext().classNames().getTransportServiceCallableFactoryClassName(service); GapicClass.Kind kind = Kind.STUB; String pakkage = String.format("%s.stub", service.pakkage()); - String operationService = ""; - for(Method method : service.methods()) { - if(method.operationService() != null) { - operationService = method.operationService(); - } - } - StubCommentComposer commentComposer = new StubCommentComposer(getTransportContext().transportName()); ClassDefinition classDef = @@ -85,9 +78,9 @@ public GapicClass generate(GapicContext context, Service service) { commentComposer.createTransportServiceCallableFactoryClassHeaderComments( service.name(), service.isDeprecated())) .setAnnotations(createClassAnnotations(service, typeStore)) - .setImplementsTypes(createClassImplements(typeStore)) + .setImplementsTypes(createClassImplements(typeStore, service)) .setName(className) - .setMethods(createClassMethods(typeStore, operationService)) + .setMethods(createClassMethods(service, typeStore)) .setScope(ScopeNode.PUBLIC) .build(); return GapicClass.create(kind, classDef); @@ -118,22 +111,23 @@ protected List createClassAnnotations(Service service, TypeStore * @return {@code TypeNode} containing the interface to be implemented by the generated callable * factory class. */ - protected abstract List createClassImplements(TypeStore typeStore); + protected abstract List createClassImplements(TypeStore typeStore, Service service); - protected List createClassMethods(TypeStore typeStore, String operationService) { + protected List createClassMethods(Service service, TypeStore typeStore) { return Arrays.asList( - createUnaryCallableMethod(typeStore), - createPagedCallableMethod(typeStore), - createBatchingCallableMethod(typeStore), - createOperationCallableMethod(typeStore, operationService)); + createUnaryCallableMethod(service, typeStore), + createPagedCallableMethod(service, typeStore), + createBatchingCallableMethod(service, typeStore), + createOperationCallableMethod(service, typeStore)); } - protected MethodDefinition createUnaryCallableMethod(TypeStore typeStore) { + protected MethodDefinition createUnaryCallableMethod(Service service, TypeStore typeStore) { String methodVariantName = "Unary"; String requestTemplateName = "RequestT"; String responseTemplateName = "ResponseT"; List methodTemplateNames = Arrays.asList(requestTemplateName, responseTemplateName); return createGenericCallableMethod( + service, typeStore, /*methodTemplateNames=*/ methodTemplateNames, /*returnCallableKindName=*/ methodVariantName, @@ -148,7 +142,7 @@ protected MethodDefinition createUnaryCallableMethod(TypeStore typeStore) { .collect(Collectors.toList())); } - protected MethodDefinition createPagedCallableMethod(TypeStore typeStore) { + protected MethodDefinition createPagedCallableMethod(Service service, TypeStore typeStore) { String methodVariantName = "Paged"; String requestTemplateName = "RequestT"; String pagedResponseTemplateName = "PagedListResponseT"; @@ -156,6 +150,7 @@ protected MethodDefinition createPagedCallableMethod(TypeStore typeStore) { List methodTemplateNames = Arrays.asList(requestTemplateName, responseTemplateName, pagedResponseTemplateName); return createGenericCallableMethod( + service, typeStore, /*methodTemplateNames=*/ methodTemplateNames, /*returnCallableKindName=*/ "Unary", @@ -170,12 +165,13 @@ protected MethodDefinition createPagedCallableMethod(TypeStore typeStore) { .collect(Collectors.toList())); } - protected MethodDefinition createBatchingCallableMethod(TypeStore typeStore) { + protected MethodDefinition createBatchingCallableMethod(Service service, TypeStore typeStore) { String methodVariantName = "Batching"; String requestTemplateName = "RequestT"; String responseTemplateName = "ResponseT"; List methodTemplateNames = Arrays.asList(requestTemplateName, responseTemplateName); return createGenericCallableMethod( + service, typeStore, /*methodTemplateNames=*/ methodTemplateNames, /*returnCallableKindName=*/ "Unary", @@ -190,9 +186,11 @@ protected MethodDefinition createBatchingCallableMethod(TypeStore typeStore) { .collect(Collectors.toList())); } - protected abstract MethodDefinition createOperationCallableMethod(TypeStore typeStore, String operationService); + protected abstract MethodDefinition createOperationCallableMethod( + Service service, TypeStore typeStore); protected MethodDefinition createGenericCallableMethod( + Service service, TypeStore typeStore, List methodTemplateNames, String returnCallableKindName, @@ -202,6 +200,7 @@ protected MethodDefinition createGenericCallableMethod( String callSettingsVariantName, List callSettingsTemplateObjects) { return createGenericCallableMethod( + service, typeStore, methodTemplateNames, returnCallableKindName, @@ -214,6 +213,7 @@ protected MethodDefinition createGenericCallableMethod( } protected MethodDefinition createGenericCallableMethod( + Service service, TypeStore typeStore, List methodTemplateNames, String returnCallableKindName, @@ -265,7 +265,7 @@ protected MethodDefinition createGenericCallableMethod( .setVariable( Variable.builder() .setName("operationsStub") - .setType(getTransportContext().operationsStubType()) + .setType(getOperationsStubType(service)) .build()) .setIsDecl(true) .build()); @@ -296,7 +296,16 @@ protected MethodDefinition createGenericCallableMethod( .build(); } - private static TypeStore createTypes() { + protected TypeNode getOperationsStubType(Service service) { + TypeNode opeationsStubType = service.operationServiceStubType(); + if (opeationsStubType == null) { + opeationsStubType = getTransportContext().operationsStubType(); + } + return opeationsStubType; + } + + + private TypeStore createTypes(Service service) { List concreteClazzes = Arrays.asList( // Gax-java classes. 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 3202684691..8935e0b00c 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 @@ -44,6 +44,7 @@ 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.VaporReference; import com.google.api.generator.engine.ast.Variable; import com.google.api.generator.engine.ast.VariableExpr; import com.google.api.generator.gapic.composer.comment.StubCommentComposer; @@ -63,6 +64,7 @@ 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; @@ -144,19 +146,25 @@ public GapicClass generate(GapicContext context, Service service) { .setName(BACKGROUND_RESOURCES_MEMBER_NAME) .setType(FIXED_TYPESTORE.get("BackgroundResource")) .build())); - if (getTransportContext().transportOperationsStubType() != null) { + + + TypeNode opeationsStubType = getTransportOperationsStubType(service); + if (opeationsStubType != null) { classMemberVarExprs.put( OPERATIONS_STUB_MEMBER_NAME, VariableExpr.withVariable( Variable.builder() .setName(OPERATIONS_STUB_MEMBER_NAME) - .setType(getTransportContext().transportOperationsStubType()) + .setType(opeationsStubType) .build())); } boolean operationPollingMethod = checkOperationPollingMethod(service); if(operationPollingMethod) { - declareLongRunningClient(classMemberVarExprs); + VariableExpr longRunningVarExpr = declareLongRunningClient(); + if (longRunningVarExpr != null) { + classMemberVarExprs.put("longRunningClient", longRunningVarExpr); + } } classMemberVarExprs.put( @@ -554,14 +562,16 @@ protected List createConstructorMethods( .setValueExpr(callableFactoryVarExpr) .build()); VariableExpr operationsStubClassVarExpr = classMemberVarExprs.get(OPERATIONS_STUB_MEMBER_NAME); - if (getTransportContext().transportOperationsStubType() != null) { + + TypeNode opeationsStubType = getTransportOperationsStubType(service); + if (opeationsStubType != null) { secondCtorExprs.add( AssignmentExpr.builder() .setVariableExpr( operationsStubClassVarExpr.toBuilder().setExprReferenceExpr(thisExpr).build()) .setValueExpr( MethodInvocationExpr.builder() - .setStaticReferenceType(getTransportContext().transportOperationsStubType()) + .setStaticReferenceType(opeationsStubType) .setMethodName("create") .setArguments(Arrays.asList(clientContextVarExpr, callableFactoryVarExpr)) .setReturnType(operationsStubClassVarExpr.type()) @@ -670,8 +680,8 @@ protected List createLongRunningClient(Service service, TypeStore typ return ImmutableList.of(); } - protected void declareLongRunningClient(Map classMemberVarExprs) { - + protected VariableExpr declareLongRunningClient() { + return null; } private static Expr createCallableInitExpr( @@ -845,10 +855,8 @@ private List createStubOverrideMethods( .build()) .build(); List javaMethods = new ArrayList<>(); - //TODO: check for operation polling method - boolean operationPollingMethod = checkOperationPollingMethod(service); - if (operationPollingMethod) { - getterLongRunningClient(javaMethods); + if (service.operationPollingMethod() != null) { + javaMethods.addAll(createLongRunningClientGetter()); } javaMethods.add( methodMakerStarterFn @@ -931,8 +939,8 @@ private boolean checkOperationPollingMethod(Service service) { return false; } - protected void getterLongRunningClient(List javaMethods) { - + protected List createLongRunningClientGetter() { + return Collections.emptyList(); } private TypeStore createDynamicTypes(Service service, String stubPakkage) { @@ -1002,4 +1010,20 @@ protected String getProtoRpcFullMethodName(Service protoService, Method protoMet return String.format( "%s.%s/%s", protoService.protoPakkage(), protoService.name(), protoMethod.name()); } + + protected TypeNode getTransportOperationsStubType(Service service) { + TypeNode transportOpeationsStubType = service.operationServiceStubType(); + if (transportOpeationsStubType == null) { + transportOpeationsStubType = getTransportContext().transportOperationsStubType(); + } + else { + transportOpeationsStubType = TypeNode.withReference( + VaporReference.builder() + .setName("HttpJson" + transportOpeationsStubType.reference().simpleName()) + .setPakkage(transportOpeationsStubType.reference().pakkage()) + .build()); + } + + return transportOpeationsStubType; + } } diff --git a/src/main/java/com/google/api/generator/gapic/composer/common/ServiceClientClassComposer.java b/src/main/java/com/google/api/generator/gapic/composer/common/ServiceClientClassComposer.java index 5a38db0562..4f804822f1 100644 --- a/src/main/java/com/google/api/generator/gapic/composer/common/ServiceClientClassComposer.java +++ b/src/main/java/com/google/api/generator/gapic/composer/common/ServiceClientClassComposer.java @@ -129,7 +129,7 @@ public GapicClass generate(GapicContext context, Service service) { String className = ClassNames.getServiceClientClassName(service); GapicClass.Kind kind = Kind.MAIN; String pakkage = service.pakkage(); - boolean hasLroClient = hasLroMethods(service); + boolean hasLroClient = exposeOperationsClient(service); Map> grpcRpcsToJavaMethodNames = new HashMap<>(); @@ -216,9 +216,9 @@ private static List createClassMethods( return methods; } - private static boolean hasLroMethods(Service service) { + private static boolean exposeOperationsClient(Service service) { for (Method method : service.methods()) { - if (method.hasLro()) { + if (method.hasLro() && method.lro().operationServiceStubType() == null) { return true; } } diff --git a/src/main/java/com/google/api/generator/gapic/composer/common/ServiceStubClassComposer.java b/src/main/java/com/google/api/generator/gapic/composer/common/ServiceStubClassComposer.java index 9d16f98f88..1c8bed3ccb 100644 --- a/src/main/java/com/google/api/generator/gapic/composer/common/ServiceStubClassComposer.java +++ b/src/main/java/com/google/api/generator/gapic/composer/common/ServiceStubClassComposer.java @@ -112,7 +112,11 @@ private static List createClassMethods( boolean hasLroClient = hasLroMethods(service); List methods = new ArrayList<>(); if (hasLroClient) { - methods.add(createOperationsStubGetter(typeStore)); + TypeNode operationsStubType = service.operationServiceStubType(); + if (operationsStubType == null) { + operationsStubType = typeStore.get("OperationsStub"); + } + methods.add(createOperationsStubGetter(typeStore, operationsStubType)); } methods.addAll(createCallableGetters(service, messageTypes, typeStore)); methods.addAll(createBackgroundResourceMethodOverrides()); @@ -203,11 +207,11 @@ private static MethodDefinition createCallableGetterHelper( .build(); } - private static MethodDefinition createOperationsStubGetter(TypeStore typeStore) { + private static MethodDefinition createOperationsStubGetter(TypeStore typeStore, TypeNode operationsStubType) { String methodName = "getOperationsStub"; return MethodDefinition.builder() .setScope(ScopeNode.PUBLIC) - .setReturnType(typeStore.get("OperationsStub")) + .setReturnType(operationsStubType) .setName(methodName) .setBody(createThrowUOEBody(methodName, typeStore)) .build(); 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 06bb6695b2..38446187e8 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 @@ -19,6 +19,7 @@ import com.google.api.generator.engine.ast.TypeNode; import com.google.api.generator.gapic.composer.common.AbstractServiceCallableFactoryClassComposer; import com.google.api.generator.gapic.composer.store.TypeStore; +import com.google.api.generator.gapic.model.Service; import com.google.longrunning.Operation; import java.util.ArrayList; import java.util.Arrays; @@ -41,28 +42,30 @@ public static GrpcServiceCallableFactoryClassComposer instance() { } @Override - protected List createClassImplements(TypeStore typeStore) { + protected List createClassImplements(TypeStore typeStore, Service service) { return Arrays.asList(getTransportContext().stubCallableFactoryType()); } - protected List createClassMethods( - TypeStore typeStore, String operationService) { + @Override + protected List createClassMethods(Service service, TypeStore typeStore) { List classMethods = - new ArrayList<>(super.createClassMethods(typeStore, operationService)); + new ArrayList<>(super.createClassMethods(service, typeStore)); classMethods.addAll( Arrays.asList( - createBidiStreamingCallableMethod(typeStore), - createServerStreamingCallableMethod(typeStore), - createClientStreamingCallableMethod(typeStore))); + createBidiStreamingCallableMethod(service, typeStore), + createServerStreamingCallableMethod(service, typeStore), + createClientStreamingCallableMethod(service, typeStore))); return classMethods; } - protected MethodDefinition createUnaryCallableMethod(TypeStore typeStore) { + @Override + protected MethodDefinition createUnaryCallableMethod(Service service, TypeStore typeStore) { String methodVariantName = "Unary"; String requestTemplateName = "RequestT"; String responseTemplateName = "ResponseT"; List methodTemplateNames = Arrays.asList(requestTemplateName, responseTemplateName); return createGenericCallableMethod( + service, typeStore, /*methodTemplateNames=*/ methodTemplateNames, /*returnCallableKindName=*/ methodVariantName, @@ -77,7 +80,8 @@ protected MethodDefinition createUnaryCallableMethod(TypeStore typeStore) { .collect(Collectors.toList())); } - protected MethodDefinition createPagedCallableMethod(TypeStore typeStore) { + @Override + protected MethodDefinition createPagedCallableMethod(Service service, TypeStore typeStore) { String methodVariantName = "Paged"; String requestTemplateName = "RequestT"; String pagedResponseTemplateName = "PagedListResponseT"; @@ -85,6 +89,7 @@ protected MethodDefinition createPagedCallableMethod(TypeStore typeStore) { List methodTemplateNames = Arrays.asList(requestTemplateName, responseTemplateName, pagedResponseTemplateName); return createGenericCallableMethod( + service, typeStore, /*methodTemplateNames=*/ methodTemplateNames, /*returnCallableKindName=*/ "Unary", @@ -100,14 +105,14 @@ protected MethodDefinition createPagedCallableMethod(TypeStore typeStore) { } @Override - protected MethodDefinition createOperationCallableMethod( - TypeStore typeStore, String operationService) { + protected MethodDefinition createOperationCallableMethod(Service service, TypeStore typeStore) { String methodVariantName = "Operation"; String requestTemplateName = "RequestT"; String responseTemplateName = "ResponseT"; List methodTemplateNames = Arrays.asList(requestTemplateName, responseTemplateName, "MetadataT"); return createGenericCallableMethod( + service, typeStore, /*methodTemplateNames=*/ methodTemplateNames, /*returnCallableKindName=*/ methodVariantName, @@ -120,12 +125,13 @@ protected MethodDefinition createOperationCallableMethod( .collect(Collectors.toList())); } - private MethodDefinition createBidiStreamingCallableMethod(TypeStore typeStore) { + private MethodDefinition createBidiStreamingCallableMethod(Service service, TypeStore typeStore) { String methodVariantName = "BidiStreaming"; String requestTemplateName = "RequestT"; String responseTemplateName = "ResponseT"; List methodTemplateNames = Arrays.asList(requestTemplateName, responseTemplateName); return createGenericCallableMethod( + service, typeStore, /*methodTemplateNames=*/ methodTemplateNames, /*returnCallableKindName=*/ methodVariantName, @@ -140,12 +146,14 @@ private MethodDefinition createBidiStreamingCallableMethod(TypeStore typeStore) .collect(Collectors.toList())); } - private MethodDefinition createServerStreamingCallableMethod(TypeStore typeStore) { + private MethodDefinition createServerStreamingCallableMethod( + Service service, TypeStore typeStore) { String methodVariantName = "ServerStreaming"; String requestTemplateName = "RequestT"; String responseTemplateName = "ResponseT"; List methodTemplateNames = Arrays.asList(requestTemplateName, responseTemplateName); return createGenericCallableMethod( + service, typeStore, /*methodTemplateNames=*/ methodTemplateNames, /*returnCallableKindName=*/ methodVariantName, @@ -160,12 +168,14 @@ private MethodDefinition createServerStreamingCallableMethod(TypeStore typeStore .collect(Collectors.toList())); } - private MethodDefinition createClientStreamingCallableMethod(TypeStore typeStore) { + private MethodDefinition createClientStreamingCallableMethod( + Service service, TypeStore typeStore) { String methodVariantName = "ClientStreaming"; String requestTemplateName = "RequestT"; String responseTemplateName = "ResponseT"; List methodTemplateNames = Arrays.asList(requestTemplateName, responseTemplateName); return createGenericCallableMethod( + service, typeStore, /*methodTemplateNames=*/ methodTemplateNames, /*returnCallableKindName=*/ methodVariantName, diff --git a/src/main/java/com/google/api/generator/gapic/composer/rest/HttpJsonServiceCallableFactoryClassComposer.java b/src/main/java/com/google/api/generator/gapic/composer/rest/HttpJsonServiceCallableFactoryClassComposer.java index 919e6c973c..7f8a966859 100644 --- a/src/main/java/com/google/api/generator/gapic/composer/rest/HttpJsonServiceCallableFactoryClassComposer.java +++ b/src/main/java/com/google/api/generator/gapic/composer/rest/HttpJsonServiceCallableFactoryClassComposer.java @@ -14,7 +14,6 @@ package com.google.api.generator.gapic.composer.rest; -import com.google.api.gax.core.BackgroundResource; import com.google.api.gax.httpjson.HttpJsonCallableFactory; import com.google.api.gax.httpjson.HttpJsonOperationSnapshotCallable; import com.google.api.gax.rpc.OperationCallable; @@ -45,10 +44,8 @@ public class HttpJsonServiceCallableFactoryClassComposer private static final HttpJsonServiceCallableFactoryClassComposer INSTANCE = new HttpJsonServiceCallableFactoryClassComposer(); - private static final TypeNode MESSAGE_TYPE = + private static final TypeNode DEFAULT_OPERATION_TYPE = TypeNode.withReference(ConcreteReference.withClazz(Operation.class)); - private static final TypeNode BACKGROUND_RESOURCE_TYPE = - TypeNode.withReference(ConcreteReference.withClazz(BackgroundResource.class)); private HttpJsonServiceCallableFactoryClassComposer() { super(RestContext.instance()); @@ -73,23 +70,29 @@ protected List createClassAnnotations(Service service, TypeStore } @Override - protected List createClassImplements(TypeStore typeStore) { + protected List createClassImplements(TypeStore typeStore, Service service) { + TypeNode operationsStubType = getOperationsStubType(service); + + TypeNode operationType = service.operationType(); + if (operationType == null) { + operationType = DEFAULT_OPERATION_TYPE; + } + return Arrays.asList( TypeNode.withReference( getTransportContext() .stubCallableFactoryType() .reference() .copyAndSetGenerics( - Arrays.asList( - MESSAGE_TYPE.reference(), BACKGROUND_RESOURCE_TYPE.reference())))); + Arrays.asList(operationType.reference(), operationsStubType.reference())))); } @Override - protected MethodDefinition createOperationCallableMethod( - TypeStore typeStore, String operationService) { + protected MethodDefinition createOperationCallableMethod(Service service, TypeStore typeStore) { String methodVariantName = "Operation"; String requestTemplateName = "RequestT"; String responseTemplateName = "ResponseT"; + List methodTemplateNames = Arrays.asList(requestTemplateName, responseTemplateName, "MetadataT"); @@ -104,36 +107,28 @@ protected MethodDefinition createOperationCallableMethod( + " future."); // Generate generic method without the body - // TODO: change static usages to vapor references + TypeNode operationType = service.operationType(); + if (operationType == null) { + operationType = DEFAULT_OPERATION_TYPE; + } MethodDefinition method = createGenericCallableMethod( + service, typeStore, /*methodTemplateNames=*/ methodTemplateNames, /*returnCallableKindName=*/ methodVariantName, /*returnCallableTemplateNames=*/ methodTemplateNames, /*methodVariantName=*/ methodVariantName, /*httpJsonCallSettingsTemplateObjects=*/ Arrays.asList( - requestTemplateName, MESSAGE_TYPE), + requestTemplateName, operationType), /*callSettingsVariantName=*/ methodVariantName, /*callSettingsTemplateObjects=*/ methodTemplateNames.stream() .map(n -> (Object) n) .collect(Collectors.toList()), Arrays.asList(betaAnnotation)); - // if (operationService.equals("")) { - // return method.toBuilder().setReturnExpr(ValueExpr.createNullExpr()).build(); - // } - List createOperationCallableBody = new ArrayList(2); - List arguments = new ArrayList<>(method.arguments()); - // Variable stubVar = arguments.get(3).variable(); - // stubVar = Variable.builder() - // .setName(stubVar.identifier().name()) - // .setType(typeStore.get(operationService+"Stub")) - // .build(); - // arguments.set(3,VariableExpr.withVariable(stubVar)); - // method = method.toBuilder().setArguments(arguments).build(); Variable httpJsonCallSettingsVar = arguments.get(0).variable(); Variable operationCallSettingsVar = arguments.get(1).variable(); @@ -177,14 +172,14 @@ protected MethodDefinition createOperationCallableMethod( VaporReference requestT = VaporReference.builder() .setName("RequestT") - .setPakkage("com.google.cloud.compute.v1.stub") + .setPakkage(service.pakkage() + ".stub") .build(); TypeNode initialCallableType = TypeNode.withReference( ConcreteReference.builder() .setClazz(HttpJsonOperationSnapshotCallable.class) - .setGenerics(requestT, ConcreteReference.withClazz(Operation.class)) + .setGenerics(requestT, operationType.reference()) .build()); // Generate initialCallable @@ -213,7 +208,7 @@ protected MethodDefinition createOperationCallableMethod( TypeNode.withReference( ConcreteReference.builder() .setClazz(HttpJsonOperationSnapshotCallable.class) - .setGenerics(requestT, ConcreteReference.withClazz(Operation.class)) + .setGenerics(requestT, operationType.reference()) .build()); NewObjectExpr initialCallableObject = NewObjectExpr.builder() diff --git a/src/main/java/com/google/api/generator/gapic/composer/rest/HttpJsonServiceStubClassComposer.java b/src/main/java/com/google/api/generator/gapic/composer/rest/HttpJsonServiceStubClassComposer.java index d00e23c5fc..39974fe44a 100644 --- a/src/main/java/com/google/api/generator/gapic/composer/rest/HttpJsonServiceStubClassComposer.java +++ b/src/main/java/com/google/api/generator/gapic/composer/rest/HttpJsonServiceStubClassComposer.java @@ -131,7 +131,7 @@ protected Statement createMethodDescriptorVariableDecl( methodMaker.apply("setRequestFormatter", getRequestFormatterExpr(protoMethod)).apply(expr); expr = methodMaker.apply("setResponseParser", setResponseParserExpr(protoMethod)).apply(expr); - if (protoMethod.isOperationPollingMethod() || protoMethod.operationService() != null) { + if (protoMethod.isOperationPollingMethod() || protoMethod.hasLro()) { expr = methodMaker .apply( @@ -139,6 +139,7 @@ protected Statement createMethodDescriptorVariableDecl( setOperationSnapshotFactoryExpr(protoMethod, messageTypes)) .apply(expr); } + if (protoMethod.isOperationPollingMethod()) { expr = methodMaker @@ -470,7 +471,7 @@ private List setOperationSnapshotFactoryExpr( MethodInvocationExpr getId = MethodInvocationExpr.builder() .setExprReferenceExpr(responseVarExpr) - .setMethodName(getMethodFormat(operationResponse.getNameFieldName())) + .setMethodName(getMethodFormat(operationResponse.nameFieldName())) .build(); Expr opNameObjectExpr = NewObjectExpr.builder().setType(stringBuilderType).setArguments(getId).build(); @@ -496,19 +497,17 @@ private List setOperationSnapshotFactoryExpr( MethodInvocationExpr getStatusExpr = MethodInvocationExpr.builder() .setExprReferenceExpr(responseVarExpr) - .setMethodName(getMethodFormat(operationResponse.getStatusFieldName())) + .setMethodName(getMethodFormat(operationResponse.statusFieldName())) .build(); - String statusTypeName = operationResponse.getStatusFieldTypeName(); + String statusTypeName = operationResponse.statusFieldTypeName(); String statusClassName = statusTypeName.substring(statusTypeName.lastIndexOf('.') + 1); - String statusPackage = protoMethod.servicePackage(); // "com" + - // statusTypeName.substring(0,statusTypeName.lastIndexOf('.')); TypeNode statusType = TypeNode.withReference( VaporReference.builder() .setName(statusClassName) - .setPakkage(statusPackage + "." + protoMethod.outputType().reference().simpleName()) + .setPakkage(protoMethod.outputType().reference().fullName()) .setIsStaticImport(false) .build()); VariableExpr statusDoneExpr = @@ -536,12 +535,12 @@ private List setOperationSnapshotFactoryExpr( MethodInvocationExpr getHttpErrorStatusCodeExpr = MethodInvocationExpr.builder() .setExprReferenceExpr(responseVarExpr) - .setMethodName(getMethodFormat(operationResponse.getErrorCodeFieldName())) + .setMethodName(getMethodFormat(operationResponse.errorCodeFieldName())) .build(); MethodInvocationExpr getHttpErrorMessageExpr = MethodInvocationExpr.builder() .setExprReferenceExpr(responseVarExpr) - .setMethodName(getMethodFormat(operationResponse.getErrorMessageFieldName())) + .setMethodName(getMethodFormat(operationResponse.errorMessageFieldName())) .build(); MethodInvocationExpr newBuilderExpr = MethodInvocationExpr.builder() @@ -861,16 +860,8 @@ private List getHttpMethodTypeExpr(Method protoMethod) { @Override protected List createLongRunningClient(Service service, TypeStore typeStore) { - boolean operation_polling_method = false; - Method protoMethod = null; - for (Method method : service.methods()) { - if (method.isOperationPollingMethod()) { - protoMethod = method; - operation_polling_method = true; - break; - } - } - if (operation_polling_method) { + Method pollingMethod = service.operationPollingMethod(); + if (pollingMethod != null) { Expr thisExpr = ValueExpr.withValue( ThisObjectValue.withType( @@ -882,13 +873,13 @@ protected List createLongRunningClient(Service service, TypeStore typ VariableExpr callable = VariableExpr.withVariable( Variable.builder() - .setName(protoMethod.name().toLowerCase() + "Callable") + .setName(pollingMethod.name().toLowerCase() + "Callable") .setType(TypeNode.withReference(ConcreteReference.withClazz(UnaryCallable.class))) .build()); VariableExpr methodDescriptor = VariableExpr.withVariable( Variable.builder() - .setName(protoMethod.name().toLowerCase() + "MethodDescriptor") + .setName(pollingMethod.name().toLowerCase() + "MethodDescriptor") .setType( TypeNode.withReference( ConcreteReference.withClazz(ApiMethodDescriptor.class))) @@ -900,8 +891,8 @@ protected List createLongRunningClient(Service service, TypeStore typ .setClazz(HttpJsonLongRunningClient.class) .setGenerics( Arrays.asList( - protoMethod.inputType().reference(), - protoMethod.outputType().reference())) + pollingMethod.inputType().reference(), + pollingMethod.outputType().reference())) .build()); NewObjectExpr HttpJsonLongRunningClient = @@ -943,19 +934,16 @@ protected List createLongRunningClient(Service service, TypeStore typ } @Override - protected void declareLongRunningClient(Map classMemberVarExprs) { - classMemberVarExprs.put( - "longRunningClient", - VariableExpr.withVariable( - Variable.builder() - .setName("longRunningClient") - .setType( - TypeNode.withReference(ConcreteReference.withClazz(LongRunningClient.class))) - .build())); + protected VariableExpr declareLongRunningClient() { + return VariableExpr.withVariable( + Variable.builder() + .setName("longRunningClient") + .setType(TypeNode.withReference(ConcreteReference.withClazz(LongRunningClient.class))) + .build()); } @Override - protected void getterLongRunningClient(List javaMethods) { + protected List createLongRunningClientGetter() { VariableExpr longRunningClient = VariableExpr.withVariable( Variable.builder() @@ -964,7 +952,7 @@ protected void getterLongRunningClient(List javaMethods) { TypeNode.withReference(ConcreteReference.withClazz(LongRunningClient.class))) .build()); - javaMethods.add( + return ImmutableList.of( MethodDefinition.builder() .setName("longRunningClient") .setScope(ScopeNode.PUBLIC) diff --git a/src/main/java/com/google/api/generator/gapic/model/LongrunningOperation.java b/src/main/java/com/google/api/generator/gapic/model/LongrunningOperation.java index c2b425e2f8..e23e8a6ee3 100644 --- a/src/main/java/com/google/api/generator/gapic/model/LongrunningOperation.java +++ b/src/main/java/com/google/api/generator/gapic/model/LongrunningOperation.java @@ -16,6 +16,7 @@ import com.google.api.generator.engine.ast.TypeNode; import com.google.auto.value.AutoValue; +import javax.annotation.Nullable; @AutoValue public abstract class LongrunningOperation { @@ -23,22 +24,21 @@ public abstract class LongrunningOperation { public abstract TypeNode metadataType(); - public static LongrunningOperation withTypes(TypeNode responseType, TypeNode metadataType) { - return builder().setResponseType(responseType).setMetadataType(metadataType).build(); - } + @Nullable + public abstract TypeNode operationServiceStubType(); - // Private. - static Builder builder() { + public static Builder builder() { return new AutoValue_LongrunningOperation.Builder(); } - // Private. @AutoValue.Builder - abstract static class Builder { - abstract Builder setResponseType(TypeNode responseType); + public abstract static class Builder { + public abstract Builder setResponseType(TypeNode responseType); + + public abstract Builder setMetadataType(TypeNode metadataType); - abstract Builder setMetadataType(TypeNode metadataType); + public abstract Builder setOperationServiceStubType(TypeNode operationServiceType); - abstract LongrunningOperation build(); + public abstract LongrunningOperation 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 aaf3f4a596..286bd8c84e 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 @@ -68,12 +68,6 @@ public boolean isPaged() { public abstract boolean operationPollingMethod(); - @Nullable - public abstract String operationService(); - - @Nullable - public abstract String servicePackage(); - public boolean hasLro() { return lro() != null; } @@ -146,10 +140,6 @@ public abstract static class Builder { public abstract Builder setOperationPollingMethod(boolean operationPollingMethod); - public abstract Builder setOperationService(String operationService); - - public abstract Builder setServicePackage(String servicePackage); - public abstract Method build(); } } diff --git a/src/main/java/com/google/api/generator/gapic/model/OperationResponse.java b/src/main/java/com/google/api/generator/gapic/model/OperationResponse.java index 1a141479ac..20543d3fc8 100644 --- a/src/main/java/com/google/api/generator/gapic/model/OperationResponse.java +++ b/src/main/java/com/google/api/generator/gapic/model/OperationResponse.java @@ -21,19 +21,19 @@ @AutoValue public abstract class OperationResponse { @Nullable - public abstract String getNameFieldName(); + public abstract String nameFieldName(); @Nullable - public abstract String getStatusFieldName(); + public abstract String statusFieldName(); @Nullable - public abstract String getErrorCodeFieldName(); + public abstract String errorCodeFieldName(); @Nullable - public abstract String getErrorMessageFieldName(); + public abstract String errorMessageFieldName(); @Nullable - public abstract String getStatusFieldTypeName(); + public abstract String statusFieldTypeName(); public static Builder builder() { return new AutoValue_OperationResponse.Builder(); diff --git a/src/main/java/com/google/api/generator/gapic/model/Service.java b/src/main/java/com/google/api/generator/gapic/model/Service.java index f21125fb54..ace91051bc 100644 --- a/src/main/java/com/google/api/generator/gapic/model/Service.java +++ b/src/main/java/com/google/api/generator/gapic/model/Service.java @@ -14,6 +14,7 @@ package com.google.api.generator.gapic.model; +import com.google.api.generator.engine.ast.TypeNode; import com.google.auto.value.AutoValue; import com.google.common.base.Strings; import com.google.common.collect.ImmutableList; @@ -49,6 +50,35 @@ public boolean hasDescription() { return !Strings.isNullOrEmpty(description()); } + public Method operationPollingMethod() { + for (Method method : methods()) { + if (method.isOperationPollingMethod()) { + return method; + } + } + return null; + } + + public TypeNode operationServiceStubType() { + for (Method method : methods()) { + if (method.hasLro() && method.lro().operationServiceStubType() != null) { + // All methods within the same service must have the same operationServiceTypeName if + // present + return method.lro().operationServiceStubType(); + } + } + return null; + } + + public TypeNode operationType() { + for (Method method : methods()) { + if (method.hasLro() && method.lro().operationServiceStubType() != null) { + return method.outputType(); + } + } + return null; + } + public abstract Builder toBuilder(); public static Builder builder() { 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 0fdbb86c2b..a5f227a3d7 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 @@ -20,6 +20,7 @@ import com.google.api.ResourceDescriptor; import com.google.api.ResourceProto; import com.google.api.generator.engine.ast.TypeNode; +import com.google.api.generator.engine.ast.VaporReference; import com.google.api.generator.gapic.model.Field; import com.google.api.generator.gapic.model.GapicBatchingSettings; import com.google.api.generator.gapic.model.GapicContext; @@ -707,11 +708,6 @@ static List parseMethods( .getOptions() .getExtension(ExtendedOperationsProto.operationPollingMethod) : false; - String operationService = - protoMethod.getOptions().hasExtension(ExtendedOperationsProto.operationService) - ? protoMethod.getOptions().getExtension(ExtendedOperationsProto.operationService) - : null; - methods.add( methodBuilder .setName(protoMethod.getName()) @@ -719,7 +715,7 @@ static List parseMethods( .setOutputType(TypeParser.parseType(protoMethod.getOutputType())) .setStream( Method.toStream(protoMethod.isClientStreaming(), protoMethod.isServerStreaming())) - .setLro(parseLro(protoMethod, messageTypes)) + .setLro(parseLro(servicePackage, protoMethod, messageTypes)) .setMethodSignatures( MethodSignatureParser.parseMethodSignatures( protoMethod, @@ -733,8 +729,6 @@ static List parseMethods( .setPageSizeFieldName(parsePageSizeFieldName(protoMethod, messageTypes, transport)) .setIsDeprecated(isDeprecated) .setOperationPollingMethod(operationPollingMethod) - .setOperationService(operationService) - .setServicePackage(servicePackage) .build()); // Any input type that has a resource reference will need a resource name helper class. @@ -776,18 +770,43 @@ static List parseMethods( @VisibleForTesting static LongrunningOperation parseLro( - MethodDescriptor methodDescriptor, Map messageTypes) { + String servicePackage, MethodDescriptor methodDescriptor, Map messageTypes) { MethodOptions methodOptions = methodDescriptor.getOptions(); - if (!methodOptions.hasExtension(OperationsProto.operationInfo)) { - return null; + + TypeNode operationServiceStubType = null; + String responseTypeName = null; + String metadataTypeName = null; + + if (methodOptions.hasExtension(OperationsProto.operationInfo)) { + OperationInfo lroInfo = + methodDescriptor.getOptions().getExtension(OperationsProto.operationInfo); + responseTypeName = lroInfo.getResponseType(); + metadataTypeName = lroInfo.getMetadataType(); + } + if (methodOptions.hasExtension(ExtendedOperationsProto.operationService)) { + // TODO: support full package name for operations_service annotation value + String opServiceName = methodOptions.getExtension(ExtendedOperationsProto.operationService); + operationServiceStubType = + TypeNode.withReference( + VaporReference.builder() + .setName(opServiceName + "Stub") + .setPakkage(servicePackage + ".stub") + .build()); + + if (responseTypeName == null) { + responseTypeName = methodDescriptor.getOutputType().getFullName(); + } + if (metadataTypeName == null) { + metadataTypeName = methodDescriptor.getOutputType().getFullName(); + } } - OperationInfo lroInfo = - methodDescriptor.getOptions().getExtension(OperationsProto.operationInfo); + if (responseTypeName == null || metadataTypeName == null) { + return null; + } - // These can be short names (e.g. FooMessage) or fully-qualified names with the *proto* package. - String responseTypeName = lroInfo.getResponseType(); - String metadataTypeName = lroInfo.getMetadataType(); + Message responseMessage = null; + Message metadataMessage = null; int lastDotIndex = responseTypeName.lastIndexOf('.'); boolean isResponseTypeNameShortOnly = lastDotIndex < 0; @@ -799,9 +818,6 @@ static LongrunningOperation parseLro( String metadataTypeShortName = lastDotIndex >= 0 ? metadataTypeName.substring(lastDotIndex + 1) : metadataTypeName; - Message responseMessage = null; - Message metadataMessage = null; - // The messageTypes map keys to the Java fully-qualified name. for (Map.Entry messageEntry : messageTypes.entrySet()) { String messageKey = messageEntry.getKey(); @@ -844,7 +860,11 @@ static LongrunningOperation parseLro( "LRO metadata message %s not found in method %s", metadataTypeName, methodDescriptor.getName())); - return LongrunningOperation.withTypes(responseMessage.type(), metadataMessage.type()); + return LongrunningOperation.builder() + .setResponseType(responseMessage.type()) + .setMetadataType(metadataMessage.type()) + .setOperationServiceStubType(operationServiceStubType) + .build(); } @VisibleForTesting diff --git a/src/test/java/com/google/api/generator/gapic/composer/rest/goldens/HttpJsonComplianceCallableFactory.golden b/src/test/java/com/google/api/generator/gapic/composer/rest/goldens/HttpJsonComplianceCallableFactory.golden index f2b65c4025..8db61290e0 100644 --- a/src/test/java/com/google/api/generator/gapic/composer/rest/goldens/HttpJsonComplianceCallableFactory.golden +++ b/src/test/java/com/google/api/generator/gapic/composer/rest/goldens/HttpJsonComplianceCallableFactory.golden @@ -13,7 +13,6 @@ import com.google.api.gax.rpc.OperationCallable; import com.google.api.gax.rpc.PagedCallSettings; import com.google.api.gax.rpc.UnaryCallSettings; import com.google.api.gax.rpc.UnaryCallable; -import com.google.cloud.compute.v1.stub.RequestT; import com.google.longrunning.Operation; import javax.annotation.Generated; diff --git a/src/test/java/com/google/api/generator/gapic/composer/samplecode/ServiceClientSampleCodeComposerTest.java b/src/test/java/com/google/api/generator/gapic/composer/samplecode/ServiceClientSampleCodeComposerTest.java index 4031df1c0a..e3ca743d8d 100644 --- a/src/test/java/com/google/api/generator/gapic/composer/samplecode/ServiceClientSampleCodeComposerTest.java +++ b/src/test/java/com/google/api/generator/gapic/composer/samplecode/ServiceClientSampleCodeComposerTest.java @@ -104,7 +104,11 @@ public void composeClassHeaderMethodSampleCode_firstMethodIsNotUnaryRpc() { .setName("WaitMetadata") .setPakkage(SHOWCASE_PACKAGE_NAME) .build()); - LongrunningOperation lro = LongrunningOperation.withTypes(responseType, metadataType); + LongrunningOperation lro = + LongrunningOperation.builder() + .setResponseType(responseType) + .setMetadataType(metadataType) + .build(); TypeNode ttlTypeNode = TypeNode.withReference( VaporReference.builder().setName("Duration").setPakkage(PROTO_PACKAGE_NAME).build()); @@ -1252,7 +1256,11 @@ public void validComposeRpcMethodHeaderSampleCode_lroUnaryRpcWithNoMethodArgumen .setName("WaitMetadata") .setPakkage(SHOWCASE_PACKAGE_NAME) .build()); - LongrunningOperation lro = LongrunningOperation.withTypes(responseType, metadataType); + LongrunningOperation lro = + LongrunningOperation.builder() + .setResponseType(responseType) + .setMetadataType(metadataType) + .build(); Method method = Method.builder() .setName("Wait") @@ -1305,7 +1313,11 @@ public void validComposeRpcMethodHeaderSampleCode_lroRpcWithReturnResponseType() .setName("WaitMetadata") .setPakkage(SHOWCASE_PACKAGE_NAME) .build()); - LongrunningOperation lro = LongrunningOperation.withTypes(responseType, metadataType); + LongrunningOperation lro = + LongrunningOperation.builder() + .setResponseType(responseType) + .setMetadataType(metadataType) + .build(); TypeNode ttlTypeNode = TypeNode.withReference( VaporReference.builder().setName("Duration").setPakkage(PROTO_PACKAGE_NAME).build()); @@ -1372,7 +1384,11 @@ public void validComposeRpcMethodHeaderSampleCode_lroRpcWithReturnVoid() { .setName("WaitMetadata") .setPakkage(SHOWCASE_PACKAGE_NAME) .build()); - LongrunningOperation lro = LongrunningOperation.withTypes(responseType, metadataType); + LongrunningOperation lro = + LongrunningOperation.builder() + .setResponseType(responseType) + .setMetadataType(metadataType) + .build(); TypeNode ttlTypeNode = TypeNode.withReference( VaporReference.builder().setName("Duration").setPakkage(PROTO_PACKAGE_NAME).build()); @@ -1528,7 +1544,11 @@ public void validComposeRpcDefaultMethodHeaderSampleCode_hasLroMethodWithReturnR .setName("WaitMetadata") .setPakkage(SHOWCASE_PACKAGE_NAME) .build()); - LongrunningOperation lro = LongrunningOperation.withTypes(responseType, metadataType); + LongrunningOperation lro = + LongrunningOperation.builder() + .setResponseType(responseType) + .setMetadataType(metadataType) + .build(); Method method = Method.builder() .setName("Wait") @@ -1581,7 +1601,11 @@ public void validComposeRpcDefaultMethodHeaderSampleCode_hasLroMethodWithReturnV .setName("WaitMetadata") .setPakkage(SHOWCASE_PACKAGE_NAME) .build()); - LongrunningOperation lro = LongrunningOperation.withTypes(responseType, metadataType); + LongrunningOperation lro = + LongrunningOperation.builder() + .setResponseType(responseType) + .setMetadataType(metadataType) + .build(); Method method = Method.builder() .setName("Wait") @@ -1732,7 +1756,11 @@ public void validComposeLroCallableMethodHeaderSampleCode_withReturnResponse() { .setName("WaitMetadata") .setPakkage(SHOWCASE_PACKAGE_NAME) .build()); - LongrunningOperation lro = LongrunningOperation.withTypes(responseType, metadataType); + LongrunningOperation lro = + LongrunningOperation.builder() + .setResponseType(responseType) + .setMetadataType(metadataType) + .build(); Method method = Method.builder() .setName("Wait") @@ -1784,7 +1812,11 @@ public void validComposeLroCallableMethodHeaderSampleCode_withReturnVoid() { .setName("WaitMetadata") .setPakkage(SHOWCASE_PACKAGE_NAME) .build()); - LongrunningOperation lro = LongrunningOperation.withTypes(responseType, metadataType); + LongrunningOperation lro = + LongrunningOperation.builder() + .setResponseType(responseType) + .setMetadataType(metadataType) + .build(); Method method = Method.builder() .setName("Wait") @@ -2348,7 +2380,11 @@ public void validComposeRegularCallableMethodHeaderSampleCode_lroRpc() { .setName("WaitMetadata") .setPakkage(SHOWCASE_PACKAGE_NAME) .build()); - LongrunningOperation lro = LongrunningOperation.withTypes(responseType, metadataType); + LongrunningOperation lro = + LongrunningOperation.builder() + .setResponseType(responseType) + .setMetadataType(metadataType) + .build(); Method method = Method.builder() .setName("Wait") @@ -2399,7 +2435,11 @@ public void validComposeRegularCallableMethodHeaderSampleCode_lroRpcWithReturnVo .setName("WaitMetadata") .setPakkage(SHOWCASE_PACKAGE_NAME) .build()); - LongrunningOperation lro = LongrunningOperation.withTypes(responseType, metadataType); + LongrunningOperation lro = + LongrunningOperation.builder() + .setResponseType(responseType) + .setMetadataType(metadataType) + .build(); Method method = Method.builder() .setName("Wait") diff --git a/src/test/java/com/google/api/generator/gapic/protoparser/ParserTest.java b/src/test/java/com/google/api/generator/gapic/protoparser/ParserTest.java index d9a31c9fd4..c9e6dbd3e2 100644 --- a/src/test/java/com/google/api/generator/gapic/protoparser/ParserTest.java +++ b/src/test/java/com/google/api/generator/gapic/protoparser/ParserTest.java @@ -201,7 +201,7 @@ public void parseLro_missingResponseType() { assertEquals("Wait", waitMethodDescriptor.getName()); messageTypes.remove("com.google.showcase.v1beta1.WaitResponse"); assertThrows( - NullPointerException.class, () -> Parser.parseLro(waitMethodDescriptor, messageTypes)); + NullPointerException.class, () -> Parser.parseLro("", waitMethodDescriptor, messageTypes)); } @Test @@ -211,7 +211,7 @@ public void parseLro_missingMetadataType() { assertEquals("Wait", waitMethodDescriptor.getName()); messageTypes.remove("com.google.showcase.v1beta1.WaitMetadata"); assertThrows( - NullPointerException.class, () -> Parser.parseLro(waitMethodDescriptor, messageTypes)); + NullPointerException.class, () -> Parser.parseLro("", waitMethodDescriptor, messageTypes)); } @Test diff --git a/test/integration/goldens/compute/com/google/cloud/compute/v1/AddressesClient.java b/test/integration/goldens/compute/com/google/cloud/compute/v1/AddressesClient.java index eb9db7ce24..7173f3bce5 100644 --- a/test/integration/goldens/compute/com/google/cloud/compute/v1/AddressesClient.java +++ b/test/integration/goldens/compute/com/google/cloud/compute/v1/AddressesClient.java @@ -20,9 +20,11 @@ import com.google.api.core.ApiFutures; import com.google.api.core.BetaApi; import com.google.api.gax.core.BackgroundResource; +import com.google.api.gax.longrunning.OperationFuture; import com.google.api.gax.paging.AbstractFixedSizeCollection; import com.google.api.gax.paging.AbstractPage; import com.google.api.gax.paging.AbstractPagedListResponse; +import com.google.api.gax.rpc.OperationCallable; import com.google.api.gax.rpc.PageContext; import com.google.api.gax.rpc.UnaryCallable; import com.google.cloud.compute.v1.stub.AddressesStub; @@ -46,9 +48,10 @@ *
    {@code
      * try (AddressesClient addressesClient = AddressesClient.create()) {
      *   String project = "project-309310695";
    - *   String region = "region-934795532";
    - *   String address = "address-1147692044";
    - *   Operation response = addressesClient.delete(project, region, address);
    + *   for (Map.Entry element :
    + *       addressesClient.aggregatedList(project).iterateAll()) {
    + *     // doThingsWith(element);
    + *   }
      * }
      * }
    * @@ -284,7 +287,7 @@ public final AggregatedListPagedResponse aggregatedList(AggregatedListAddressesR * String project = "project-309310695"; * String region = "region-934795532"; * String address = "address-1147692044"; - * Operation response = addressesClient.delete(project, region, address); + * Operation response = addressesClient.deleteAsync(project, region, address).get(); * } * } * @@ -293,14 +296,15 @@ public final AggregatedListPagedResponse aggregatedList(AggregatedListAddressesR * @param address Name of the address resource to delete. * @throws com.google.api.gax.rpc.ApiException if the remote call fails */ - public final Operation delete(String project, String region, String address) { + public final OperationFuture deleteAsync( + String project, String region, String address) { DeleteAddressRequest request = DeleteAddressRequest.newBuilder() .setProject(project) .setRegion(region) .setAddress(address) .build(); - return delete(request); + return deleteAsync(request); } // AUTO-GENERATED DOCUMENTATION AND METHOD. @@ -318,15 +322,42 @@ public final Operation delete(String project, String region, String address) { * .setRegion("region-934795532") * .setRequestId("requestId693933066") * .build(); - * Operation response = addressesClient.delete(request); + * Operation response = addressesClient.deleteAsync(request).get(); * } * } * * @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 Operation delete(DeleteAddressRequest request) { - return deleteCallable().call(request); + public final OperationFuture deleteAsync(DeleteAddressRequest request) { + return deleteOperationCallable().futureCall(request); + } + + // AUTO-GENERATED DOCUMENTATION AND METHOD. + /** + * Deletes the specified address resource. + * + *

    Sample code: + * + *

    {@code
    +   * try (AddressesClient addressesClient = AddressesClient.create()) {
    +   *   DeleteAddressRequest request =
    +   *       DeleteAddressRequest.newBuilder()
    +   *           .setAddress("address-1147692044")
    +   *           .setProject("project-309310695")
    +   *           .setRegion("region-934795532")
    +   *           .setRequestId("requestId693933066")
    +   *           .build();
    +   *   OperationFuture future =
    +   *       addressesClient.deleteOperationCallable().futureCall(request);
    +   *   // Do something.
    +   *   Operation response = future.get();
    +   * }
    +   * }
    + */ + public final OperationCallable + deleteOperationCallable() { + return stub.deleteOperationCallable(); } // AUTO-GENERATED DOCUMENTATION AND METHOD. @@ -365,7 +396,7 @@ public final UnaryCallable deleteCallable() { * String project = "project-309310695"; * String region = "region-934795532"; * Address addressResource = Address.newBuilder().build(); - * Operation response = addressesClient.insert(project, region, addressResource); + * Operation response = addressesClient.insertAsync(project, region, addressResource).get(); * } * } * @@ -374,14 +405,15 @@ public final UnaryCallable deleteCallable() { * @param addressResource The body resource for this request * @throws com.google.api.gax.rpc.ApiException if the remote call fails */ - public final Operation insert(String project, String region, Address addressResource) { + public final OperationFuture insertAsync( + String project, String region, Address addressResource) { InsertAddressRequest request = InsertAddressRequest.newBuilder() .setProject(project) .setRegion(region) .setAddressResource(addressResource) .build(); - return insert(request); + return insertAsync(request); } // AUTO-GENERATED DOCUMENTATION AND METHOD. @@ -399,15 +431,42 @@ public final Operation insert(String project, String region, Address addressReso * .setRegion("region-934795532") * .setRequestId("requestId693933066") * .build(); - * Operation response = addressesClient.insert(request); + * Operation response = addressesClient.insertAsync(request).get(); * } * } * * @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 Operation insert(InsertAddressRequest request) { - return insertCallable().call(request); + public final OperationFuture insertAsync(InsertAddressRequest request) { + return insertOperationCallable().futureCall(request); + } + + // AUTO-GENERATED DOCUMENTATION AND METHOD. + /** + * Creates an address resource in the specified project by using the data included in the request. + * + *

    Sample code: + * + *

    {@code
    +   * try (AddressesClient addressesClient = AddressesClient.create()) {
    +   *   InsertAddressRequest request =
    +   *       InsertAddressRequest.newBuilder()
    +   *           .setAddressResource(Address.newBuilder().build())
    +   *           .setProject("project-309310695")
    +   *           .setRegion("region-934795532")
    +   *           .setRequestId("requestId693933066")
    +   *           .build();
    +   *   OperationFuture future =
    +   *       addressesClient.insertOperationCallable().futureCall(request);
    +   *   // Do something.
    +   *   Operation response = future.get();
    +   * }
    +   * }
    + */ + public final OperationCallable + insertOperationCallable() { + return stub.insertOperationCallable(); } // AUTO-GENERATED DOCUMENTATION AND METHOD. diff --git a/test/integration/goldens/compute/com/google/cloud/compute/v1/AddressesClientTest.java b/test/integration/goldens/compute/com/google/cloud/compute/v1/AddressesClientTest.java index 24d06c2f69..04f3ea46b9 100644 --- a/test/integration/goldens/compute/com/google/cloud/compute/v1/AddressesClientTest.java +++ b/test/integration/goldens/compute/com/google/cloud/compute/v1/AddressesClientTest.java @@ -30,12 +30,15 @@ import com.google.api.gax.rpc.testing.FakeStatusCode; import com.google.cloud.compute.v1.stub.HttpJsonAddressesStub; import com.google.common.collect.Lists; +import com.google.longrunning.Operation; +import com.google.protobuf.Any; import java.io.IOException; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.List; import java.util.Map; +import java.util.concurrent.ExecutionException; import javax.annotation.Generated; import org.junit.After; import org.junit.AfterClass; @@ -132,8 +135,8 @@ public void aggregatedListExceptionTest() throws Exception { @Test public void deleteTest() throws Exception { - Operation expectedResponse = - Operation.newBuilder() + com.google.cloud.compute.v1.Operation expectedResponse = + com.google.cloud.compute.v1.Operation.newBuilder() .setClientOperationId("clientOperationId-1230366697") .setCreationTimestamp("creationTimestamp-370203401") .setDescription("description-1724546052") @@ -157,13 +160,20 @@ public void deleteTest() throws Exception { .addAllWarnings(new ArrayList()) .setZone("zone3744684") .build(); - mockService.addResponse(expectedResponse); + Operation resultOperation = + Operation.newBuilder() + .setName("deleteTest") + .setDone(true) + .setResponse(Any.pack(expectedResponse)) + .build(); + mockService.addResponse(resultOperation); String project = "project-309310695"; String region = "region-934795532"; String address = "address-1147692044"; - Operation actualResponse = client.delete(project, region, address); + com.google.cloud.compute.v1.Operation actualResponse = + client.deleteAsync(project, region, address).get(); Assert.assertEquals(expectedResponse, actualResponse); List actualRequests = mockService.getRequestPaths(); @@ -192,17 +202,16 @@ public void deleteExceptionTest() throws Exception { String project = "project-309310695"; String region = "region-934795532"; String address = "address-1147692044"; - client.delete(project, region, address); + client.deleteAsync(project, region, address).get(); Assert.fail("No exception raised"); - } catch (InvalidArgumentException e) { - // Expected exception. + } catch (ExecutionException e) { } } @Test public void insertTest() throws Exception { - Operation expectedResponse = - Operation.newBuilder() + com.google.cloud.compute.v1.Operation expectedResponse = + com.google.cloud.compute.v1.Operation.newBuilder() .setClientOperationId("clientOperationId-1230366697") .setCreationTimestamp("creationTimestamp-370203401") .setDescription("description-1724546052") @@ -226,13 +235,20 @@ public void insertTest() throws Exception { .addAllWarnings(new ArrayList()) .setZone("zone3744684") .build(); - mockService.addResponse(expectedResponse); + Operation resultOperation = + Operation.newBuilder() + .setName("insertTest") + .setDone(true) + .setResponse(Any.pack(expectedResponse)) + .build(); + mockService.addResponse(resultOperation); String project = "project-309310695"; String region = "region-934795532"; Address addressResource = Address.newBuilder().build(); - Operation actualResponse = client.insert(project, region, addressResource); + com.google.cloud.compute.v1.Operation actualResponse = + client.insertAsync(project, region, addressResource).get(); Assert.assertEquals(expectedResponse, actualResponse); List actualRequests = mockService.getRequestPaths(); @@ -261,10 +277,9 @@ public void insertExceptionTest() throws Exception { String project = "project-309310695"; String region = "region-934795532"; Address addressResource = Address.newBuilder().build(); - client.insert(project, region, addressResource); + client.insertAsync(project, region, addressResource).get(); Assert.fail("No exception raised"); - } catch (InvalidArgumentException e) { - // Expected exception. + } catch (ExecutionException e) { } } diff --git a/test/integration/goldens/compute/com/google/cloud/compute/v1/AddressesSettings.java b/test/integration/goldens/compute/com/google/cloud/compute/v1/AddressesSettings.java index d2dc359f73..58fbc804d6 100644 --- a/test/integration/goldens/compute/com/google/cloud/compute/v1/AddressesSettings.java +++ b/test/integration/goldens/compute/com/google/cloud/compute/v1/AddressesSettings.java @@ -27,6 +27,7 @@ import com.google.api.gax.rpc.ApiClientHeaderProvider; import com.google.api.gax.rpc.ClientContext; import com.google.api.gax.rpc.ClientSettings; +import com.google.api.gax.rpc.OperationCallSettings; import com.google.api.gax.rpc.PagedCallSettings; import com.google.api.gax.rpc.StubSettings; import com.google.api.gax.rpc.TransportChannelProvider; @@ -51,15 +52,15 @@ *

    The builder of this class is recursive, so contained classes are themselves builders. When * build() is called, the tree of builders is called to create the complete settings object. * - *

    For example, to set the total timeout of delete to 30 seconds: + *

    For example, to set the total timeout of aggregatedList to 30 seconds: * *

    {@code
      * AddressesSettings.Builder addressesSettingsBuilder = AddressesSettings.newBuilder();
      * addressesSettingsBuilder
    - *     .deleteSettings()
    + *     .aggregatedListSettings()
      *     .setRetrySettings(
      *         addressesSettingsBuilder
    - *             .deleteSettings()
    + *             .aggregatedListSettings()
      *             .getRetrySettings()
      *             .toBuilder()
      *             .setTotalTimeout(Duration.ofSeconds(30))
    @@ -82,11 +83,23 @@ public UnaryCallSettings deleteSettings() {
         return ((AddressesStubSettings) getStubSettings()).deleteSettings();
       }
     
    +  /** Returns the object with the settings used for calls to delete. */
    +  public OperationCallSettings
    +      deleteOperationSettings() {
    +    return ((AddressesStubSettings) getStubSettings()).deleteOperationSettings();
    +  }
    +
       /** Returns the object with the settings used for calls to insert. */
       public UnaryCallSettings insertSettings() {
         return ((AddressesStubSettings) getStubSettings()).insertSettings();
       }
     
    +  /** Returns the object with the settings used for calls to insert. */
    +  public OperationCallSettings
    +      insertOperationSettings() {
    +    return ((AddressesStubSettings) getStubSettings()).insertOperationSettings();
    +  }
    +
       /** Returns the object with the settings used for calls to list. */
       public PagedCallSettings listSettings() {
         return ((AddressesStubSettings) getStubSettings()).listSettings();
    @@ -201,11 +214,23 @@ public UnaryCallSettings.Builder deleteSettings
           return getStubSettingsBuilder().deleteSettings();
         }
     
    +    /** Returns the builder for the settings used for calls to delete. */
    +    public OperationCallSettings.Builder
    +        deleteOperationSettings() {
    +      return getStubSettingsBuilder().deleteOperationSettings();
    +    }
    +
         /** Returns the builder for the settings used for calls to insert. */
         public UnaryCallSettings.Builder insertSettings() {
           return getStubSettingsBuilder().insertSettings();
         }
     
    +    /** Returns the builder for the settings used for calls to insert. */
    +    public OperationCallSettings.Builder
    +        insertOperationSettings() {
    +      return getStubSettingsBuilder().insertOperationSettings();
    +    }
    +
         /** Returns the builder for the settings used for calls to list. */
         public PagedCallSettings.Builder
             listSettings() {
    diff --git a/test/integration/goldens/compute/com/google/cloud/compute/v1/gapic_metadata.json b/test/integration/goldens/compute/com/google/cloud/compute/v1/gapic_metadata.json
    index 14eb0320fd..d2f2df6b3d 100644
    --- a/test/integration/goldens/compute/com/google/cloud/compute/v1/gapic_metadata.json
    +++ b/test/integration/goldens/compute/com/google/cloud/compute/v1/gapic_metadata.json
    @@ -14,10 +14,10 @@
                   "methods": ["aggregatedList", "aggregatedList", "aggregatedListPagedCallable", "aggregatedListCallable"]
                 },
                 "Delete": {
    -              "methods": ["delete", "delete", "deleteCallable"]
    +              "methods": ["deleteAsync", "deleteAsync", "deleteOperationCallable", "deleteCallable"]
                 },
                 "Insert": {
    -              "methods": ["insert", "insert", "insertCallable"]
    +              "methods": ["insertAsync", "insertAsync", "insertOperationCallable", "insertCallable"]
                 },
                 "List": {
                   "methods": ["list", "list", "listPagedCallable", "listCallable"]
    diff --git a/test/integration/goldens/compute/com/google/cloud/compute/v1/package-info.java b/test/integration/goldens/compute/com/google/cloud/compute/v1/package-info.java
    index 941f3ab751..e525d9c7df 100644
    --- a/test/integration/goldens/compute/com/google/cloud/compute/v1/package-info.java
    +++ b/test/integration/goldens/compute/com/google/cloud/compute/v1/package-info.java
    @@ -28,9 +28,10 @@
      * 
    {@code
      * try (AddressesClient addressesClient = AddressesClient.create()) {
      *   String project = "project-309310695";
    - *   String region = "region-934795532";
    - *   String address = "address-1147692044";
    - *   Operation response = addressesClient.delete(project, region, address);
    + *   for (Map.Entry element :
    + *       addressesClient.aggregatedList(project).iterateAll()) {
    + *     // doThingsWith(element);
    + *   }
      * }
      * }
    * diff --git a/test/integration/goldens/compute/com/google/cloud/compute/v1/stub/AddressesStub.java b/test/integration/goldens/compute/com/google/cloud/compute/v1/stub/AddressesStub.java index b7d7f6e590..551b0ec0eb 100644 --- a/test/integration/goldens/compute/com/google/cloud/compute/v1/stub/AddressesStub.java +++ b/test/integration/goldens/compute/com/google/cloud/compute/v1/stub/AddressesStub.java @@ -20,6 +20,7 @@ import static com.google.cloud.compute.v1.AddressesClient.ListPagedResponse; import com.google.api.gax.core.BackgroundResource; +import com.google.api.gax.rpc.OperationCallable; import com.google.api.gax.rpc.UnaryCallable; import com.google.cloud.compute.v1.AddressAggregatedList; import com.google.cloud.compute.v1.AddressList; @@ -39,6 +40,10 @@ @Generated("by gapic-generator-java") public abstract class AddressesStub implements BackgroundResource { + public RegionOperationsStub getOperationsStub() { + throw new UnsupportedOperationException("Not implemented: getOperationsStub()"); + } + public UnaryCallable aggregatedListPagedCallable() { throw new UnsupportedOperationException("Not implemented: aggregatedListPagedCallable()"); @@ -49,10 +54,18 @@ public abstract class AddressesStub implements BackgroundResource { throw new UnsupportedOperationException("Not implemented: aggregatedListCallable()"); } + public OperationCallable deleteOperationCallable() { + throw new UnsupportedOperationException("Not implemented: deleteOperationCallable()"); + } + public UnaryCallable deleteCallable() { throw new UnsupportedOperationException("Not implemented: deleteCallable()"); } + public OperationCallable insertOperationCallable() { + throw new UnsupportedOperationException("Not implemented: insertOperationCallable()"); + } + public UnaryCallable insertCallable() { throw new UnsupportedOperationException("Not implemented: insertCallable()"); } diff --git a/test/integration/goldens/compute/com/google/cloud/compute/v1/stub/AddressesStubSettings.java b/test/integration/goldens/compute/com/google/cloud/compute/v1/stub/AddressesStubSettings.java index 69e3c4d6c0..55866e3401 100644 --- a/test/integration/goldens/compute/com/google/cloud/compute/v1/stub/AddressesStubSettings.java +++ b/test/integration/goldens/compute/com/google/cloud/compute/v1/stub/AddressesStubSettings.java @@ -25,13 +25,17 @@ 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.ProtoOperationTransformers; 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.longrunning.OperationSnapshot; +import com.google.api.gax.longrunning.OperationTimedPollAlgorithm; import com.google.api.gax.retrying.RetrySettings; import com.google.api.gax.rpc.ApiCallContext; import com.google.api.gax.rpc.ApiClientHeaderProvider; import com.google.api.gax.rpc.ClientContext; +import com.google.api.gax.rpc.OperationCallSettings; import com.google.api.gax.rpc.PageContext; import com.google.api.gax.rpc.PagedCallSettings; import com.google.api.gax.rpc.PagedListDescriptor; @@ -76,15 +80,15 @@ *

    The builder of this class is recursive, so contained classes are themselves builders. When * build() is called, the tree of builders is called to create the complete settings object. * - *

    For example, to set the total timeout of delete to 30 seconds: + *

    For example, to set the total timeout of aggregatedList to 30 seconds: * *

    {@code
      * AddressesStubSettings.Builder addressesSettingsBuilder = AddressesStubSettings.newBuilder();
      * addressesSettingsBuilder
    - *     .deleteSettings()
    + *     .aggregatedListSettings()
      *     .setRetrySettings(
      *         addressesSettingsBuilder
    - *             .deleteSettings()
    + *             .aggregatedListSettings()
      *             .getRetrySettings()
      *             .toBuilder()
      *             .setTotalTimeout(Duration.ofSeconds(30))
    @@ -105,7 +109,11 @@ public class AddressesStubSettings extends StubSettings {
               AggregatedListAddressesRequest, AddressAggregatedList, AggregatedListPagedResponse>
           aggregatedListSettings;
       private final UnaryCallSettings deleteSettings;
    +  private final OperationCallSettings
    +      deleteOperationSettings;
       private final UnaryCallSettings insertSettings;
    +  private final OperationCallSettings
    +      insertOperationSettings;
       private final PagedCallSettings
           listSettings;
     
    @@ -243,11 +251,23 @@ public UnaryCallSettings deleteSettings() {
         return deleteSettings;
       }
     
    +  /** Returns the object with the settings used for calls to delete. */
    +  public OperationCallSettings
    +      deleteOperationSettings() {
    +    return deleteOperationSettings;
    +  }
    +
       /** Returns the object with the settings used for calls to insert. */
       public UnaryCallSettings insertSettings() {
         return insertSettings;
       }
     
    +  /** Returns the object with the settings used for calls to insert. */
    +  public OperationCallSettings
    +      insertOperationSettings() {
    +    return insertOperationSettings;
    +  }
    +
       /** Returns the object with the settings used for calls to list. */
       public PagedCallSettings listSettings() {
         return listSettings;
    @@ -329,7 +349,9 @@ protected AddressesStubSettings(Builder settingsBuilder) throws IOException {
     
         aggregatedListSettings = settingsBuilder.aggregatedListSettings().build();
         deleteSettings = settingsBuilder.deleteSettings().build();
    +    deleteOperationSettings = settingsBuilder.deleteOperationSettings().build();
         insertSettings = settingsBuilder.insertSettings().build();
    +    insertOperationSettings = settingsBuilder.insertOperationSettings().build();
         listSettings = settingsBuilder.listSettings().build();
       }
     
    @@ -340,7 +362,11 @@ public static class Builder extends StubSettings.Builder
             aggregatedListSettings;
         private final UnaryCallSettings.Builder deleteSettings;
    +    private final OperationCallSettings.Builder
    +        deleteOperationSettings;
         private final UnaryCallSettings.Builder insertSettings;
    +    private final OperationCallSettings.Builder
    +        insertOperationSettings;
         private final PagedCallSettings.Builder
             listSettings;
         private static final ImmutableMap>
    @@ -395,7 +421,9 @@ protected Builder(ClientContext clientContext) {
     
           aggregatedListSettings = PagedCallSettings.newBuilder(AGGREGATED_LIST_PAGE_STR_FACT);
           deleteSettings = UnaryCallSettings.newUnaryCallSettingsBuilder();
    +      deleteOperationSettings = OperationCallSettings.newBuilder();
           insertSettings = UnaryCallSettings.newUnaryCallSettingsBuilder();
    +      insertOperationSettings = OperationCallSettings.newBuilder();
           listSettings = PagedCallSettings.newBuilder(LIST_PAGE_STR_FACT);
     
           unaryMethodSettingsBuilders =
    @@ -409,7 +437,9 @@ protected Builder(AddressesStubSettings settings) {
     
           aggregatedListSettings = settings.aggregatedListSettings.toBuilder();
           deleteSettings = settings.deleteSettings.toBuilder();
    +      deleteOperationSettings = settings.deleteOperationSettings.toBuilder();
           insertSettings = settings.insertSettings.toBuilder();
    +      insertOperationSettings = settings.insertOperationSettings.toBuilder();
           listSettings = settings.listSettings.toBuilder();
     
           unaryMethodSettingsBuilders =
    @@ -451,6 +481,54 @@ private static Builder initDefaults(Builder builder) {
               .setRetryableCodes(RETRYABLE_CODE_DEFINITIONS.get("retry_policy_0_codes"))
               .setRetrySettings(RETRY_PARAM_DEFINITIONS.get("retry_policy_0_params"));
     
    +      builder
    +          .deleteOperationSettings()
    +          .setInitialCallSettings(
    +              UnaryCallSettings
    +                  .newUnaryCallSettingsBuilder()
    +                  .setRetryableCodes(RETRYABLE_CODE_DEFINITIONS.get("no_retry_1_codes"))
    +                  .setRetrySettings(RETRY_PARAM_DEFINITIONS.get("no_retry_1_params"))
    +                  .build())
    +          .setResponseTransformer(
    +              ProtoOperationTransformers.ResponseTransformer.create(Operation.class))
    +          .setMetadataTransformer(
    +              ProtoOperationTransformers.MetadataTransformer.create(Operation.class))
    +          .setPollingAlgorithm(
    +              OperationTimedPollAlgorithm.create(
    +                  RetrySettings.newBuilder()
    +                      .setInitialRetryDelay(Duration.ofMillis(5000L))
    +                      .setRetryDelayMultiplier(1.5)
    +                      .setMaxRetryDelay(Duration.ofMillis(45000L))
    +                      .setInitialRpcTimeout(Duration.ZERO)
    +                      .setRpcTimeoutMultiplier(1.0)
    +                      .setMaxRpcTimeout(Duration.ZERO)
    +                      .setTotalTimeout(Duration.ofMillis(300000L))
    +                      .build()));
    +
    +      builder
    +          .insertOperationSettings()
    +          .setInitialCallSettings(
    +              UnaryCallSettings
    +                  .newUnaryCallSettingsBuilder()
    +                  .setRetryableCodes(RETRYABLE_CODE_DEFINITIONS.get("no_retry_1_codes"))
    +                  .setRetrySettings(RETRY_PARAM_DEFINITIONS.get("no_retry_1_params"))
    +                  .build())
    +          .setResponseTransformer(
    +              ProtoOperationTransformers.ResponseTransformer.create(Operation.class))
    +          .setMetadataTransformer(
    +              ProtoOperationTransformers.MetadataTransformer.create(Operation.class))
    +          .setPollingAlgorithm(
    +              OperationTimedPollAlgorithm.create(
    +                  RetrySettings.newBuilder()
    +                      .setInitialRetryDelay(Duration.ofMillis(5000L))
    +                      .setRetryDelayMultiplier(1.5)
    +                      .setMaxRetryDelay(Duration.ofMillis(45000L))
    +                      .setInitialRpcTimeout(Duration.ZERO)
    +                      .setRpcTimeoutMultiplier(1.0)
    +                      .setMaxRpcTimeout(Duration.ZERO)
    +                      .setTotalTimeout(Duration.ofMillis(300000L))
    +                      .build()));
    +
           return builder;
         }
     
    @@ -481,11 +559,27 @@ public UnaryCallSettings.Builder deleteSettings
           return deleteSettings;
         }
     
    +    /** Returns the builder for the settings used for calls to delete. */
    +    @BetaApi(
    +        "The surface for use by generated code is not stable yet and may change in the future.")
    +    public OperationCallSettings.Builder
    +        deleteOperationSettings() {
    +      return deleteOperationSettings;
    +    }
    +
         /** Returns the builder for the settings used for calls to insert. */
         public UnaryCallSettings.Builder insertSettings() {
           return insertSettings;
         }
     
    +    /** Returns the builder for the settings used for calls to insert. */
    +    @BetaApi(
    +        "The surface for use by generated code is not stable yet and may change in the future.")
    +    public OperationCallSettings.Builder
    +        insertOperationSettings() {
    +      return insertOperationSettings;
    +    }
    +
         /** Returns the builder for the settings used for calls to list. */
         public PagedCallSettings.Builder
             listSettings() {
    diff --git a/test/integration/goldens/compute/com/google/cloud/compute/v1/stub/HttpJsonAddressesCallableFactory.java b/test/integration/goldens/compute/com/google/cloud/compute/v1/stub/HttpJsonAddressesCallableFactory.java
    index b9e0385e12..2290fc6952 100644
    --- a/test/integration/goldens/compute/com/google/cloud/compute/v1/stub/HttpJsonAddressesCallableFactory.java
    +++ b/test/integration/goldens/compute/com/google/cloud/compute/v1/stub/HttpJsonAddressesCallableFactory.java
    @@ -17,7 +17,6 @@
     package com.google.cloud.compute.v1.stub;
     
     import com.google.api.core.BetaApi;
    -import com.google.api.gax.core.BackgroundResource;
     import com.google.api.gax.httpjson.HttpJsonCallSettings;
     import com.google.api.gax.httpjson.HttpJsonCallableFactory;
     import com.google.api.gax.httpjson.HttpJsonOperationSnapshotCallable;
    @@ -29,7 +28,7 @@
     import com.google.api.gax.rpc.PagedCallSettings;
     import com.google.api.gax.rpc.UnaryCallSettings;
     import com.google.api.gax.rpc.UnaryCallable;
    -import com.google.longrunning.Operation;
    +import com.google.cloud.compute.v1.Operation;
     import javax.annotation.Generated;
     
     // AUTO-GENERATED DOCUMENTATION AND CLASS.
    @@ -41,7 +40,7 @@
     @Generated("by gapic-generator-java")
     @BetaApi
     public class HttpJsonAddressesCallableFactory
    -    implements HttpJsonStubCallableFactory {
    +    implements HttpJsonStubCallableFactory {
     
       @Override
       public  UnaryCallable createUnaryCallable(
    @@ -79,7 +78,7 @@ OperationCallable createOperationCallable(
               HttpJsonCallSettings httpJsonCallSettings,
               OperationCallSettings callSettings,
               ClientContext clientContext,
    -          BackgroundResource operationsStub) {
    +          RegionOperationsStub operationsStub) {
         UnaryCallable innerCallable =
             HttpJsonCallableFactory.createBaseUnaryCallable(
                 httpJsonCallSettings, callSettings.getInitialCallSettings(), clientContext);
    diff --git a/test/integration/goldens/compute/com/google/cloud/compute/v1/stub/HttpJsonAddressesStub.java b/test/integration/goldens/compute/com/google/cloud/compute/v1/stub/HttpJsonAddressesStub.java
    index d79d2cc64a..943580e59b 100644
    --- a/test/integration/goldens/compute/com/google/cloud/compute/v1/stub/HttpJsonAddressesStub.java
    +++ b/test/integration/goldens/compute/com/google/cloud/compute/v1/stub/HttpJsonAddressesStub.java
    @@ -33,6 +33,7 @@
     import com.google.api.gax.httpjson.ProtoRestSerializer;
     import com.google.api.gax.longrunning.OperationSnapshot;
     import com.google.api.gax.rpc.ClientContext;
    +import com.google.api.gax.rpc.OperationCallable;
     import com.google.api.gax.rpc.UnaryCallable;
     import com.google.cloud.compute.v1.AddressAggregatedList;
     import com.google.cloud.compute.v1.AddressList;
    @@ -251,11 +252,16 @@ public class HttpJsonAddressesStub extends AddressesStub {
       private final UnaryCallable
           aggregatedListPagedCallable;
       private final UnaryCallable deleteCallable;
    +  private final OperationCallable
    +      deleteOperationCallable;
       private final UnaryCallable insertCallable;
    +  private final OperationCallable
    +      insertOperationCallable;
       private final UnaryCallable listCallable;
       private final UnaryCallable listPagedCallable;
     
       private final BackgroundResource backgroundResources;
    +  private final HttpJsonRegionOperationsStub operationsStub;
       private final HttpJsonStubCallableFactory callableFactory;
     
       public static final HttpJsonAddressesStub create(AddressesStubSettings settings)
    @@ -294,6 +300,7 @@ protected HttpJsonAddressesStub(
           HttpJsonStubCallableFactory callableFactory)
           throws IOException {
         this.callableFactory = callableFactory;
    +    this.operationsStub = HttpJsonRegionOperationsStub.create(clientContext, callableFactory);
     
         HttpJsonCallSettings
             aggregatedListTransportSettings =
    @@ -322,9 +329,21 @@ protected HttpJsonAddressesStub(
         this.deleteCallable =
             callableFactory.createUnaryCallable(
                 deleteTransportSettings, settings.deleteSettings(), clientContext);
    +    this.deleteOperationCallable =
    +        callableFactory.createOperationCallable(
    +            deleteTransportSettings,
    +            settings.deleteOperationSettings(),
    +            clientContext,
    +            operationsStub);
         this.insertCallable =
             callableFactory.createUnaryCallable(
                 insertTransportSettings, settings.insertSettings(), clientContext);
    +    this.insertOperationCallable =
    +        callableFactory.createOperationCallable(
    +            insertTransportSettings,
    +            settings.insertOperationSettings(),
    +            clientContext,
    +            operationsStub);
         this.listCallable =
             callableFactory.createUnaryCallable(
                 listTransportSettings, settings.listSettings(), clientContext);
    @@ -363,11 +382,21 @@ public UnaryCallable deleteCallable() {
         return deleteCallable;
       }
     
    +  @Override
    +  public OperationCallable deleteOperationCallable() {
    +    return deleteOperationCallable;
    +  }
    +
       @Override
       public UnaryCallable insertCallable() {
         return insertCallable;
       }
     
    +  @Override
    +  public OperationCallable insertOperationCallable() {
    +    return insertOperationCallable;
    +  }
    +
       @Override
       public UnaryCallable listCallable() {
         return listCallable;
    
    From 200fce7eb91db005524d722a09656fccb7a040cd Mon Sep 17 00:00:00 2001
    From: Vadym Matsishevskyi <25311427+vam-google@users.noreply.github.com>
    Date: Tue, 7 Sep 2021 00:30:29 -0700
    Subject: [PATCH 5/9] chore: Merge multitransport client and fixes (#836)
    
    * feat: enable self signed jwt for gapic clients (#794)
    
    * feat: enable self signed jwt for gapic clients
    
    * resolve comments
    
    * update gax version
    
    * update goldens
    
    * update golden files
    
    * chore: release 2.1.0 (#827)
    
    Co-authored-by: release-please[bot] <55107282+release-please[bot]@users.noreply.github.com>
    
    * feat: REGAPIC initial implementation (#824)
    
    This includes:
    1) Proper GRPC transcoding
    2) Mimimal REST Operations (go make it compilable)
    3) Rely on resource names for tests values generation (to not fail http url path validation)
    4) Empty Server Streaming method implementation
    
    * feat: REGAPIC Multitransport implementation (grpc+rest) (#833)
    
    1) Fully backward compatible with grpc-only GAPIC
    2) Strictly speaking not fully backward compatible with rest-only REGAPIC (but is compatible for practical cases). See below for details.
    3) Introduces the concept of default transport (is necessary to preserve backward-compabitility). The default behavior assumes grpc transport.
    
    Needed to unblock DIREGAPIC LRO. To be reviewed after submission
    
    * chore: merge DIREGAPIC LRO with multitransport changes from master
    
    * fix: fix Stub.longRunningClient() issues for DIREGAPIC LRO
    
    * fix: [bazel] fix rest transport handling in assembly rule (#835)
    
    Co-authored-by: arithmetic1728 <58957152+arithmetic1728@users.noreply.github.com>
    Co-authored-by: release-please[bot] <55107282+release-please[bot]@users.noreply.github.com>
    ---
     WORKSPACE                                     |    2 +-
     repositories.bzl                              |    4 +-
     rules_java_gapic/java_gapic.bzl               |   30 +-
     rules_java_gapic/java_gapic_pkg.bzl           |    8 +-
     .../resources/gradle/assembly.gradle.tmpl     |    4 +-
     .../resources/gradle/client_grpc.gradle.tmpl  |    4 +-
     .../gradle/client_grpcrest.gradle.tmpl        |   63 +
     .../resources/gradle/client_rest.gradle.tmpl  |    4 +-
     .../resources/gradle/grpc.gradle.tmpl         |    4 +-
     .../resources/gradle/proto.gradle.tmpl        |    4 +-
     .../google/api/generator/gapic/BUILD.bazel    |    1 +
     .../api/generator/gapic/composer/BUILD.bazel  |    1 +
     .../generator/gapic/composer/Composer.java    |   94 +-
     ...ctServiceCallableFactoryClassComposer.java |    2 +-
     ...> AbstractServiceClientClassComposer.java} |  146 ++-
     ...bstractServiceClientTestClassComposer.java |   19 +-
     .../AbstractServiceSettingsClassComposer.java |   76 +-
     .../AbstractServiceStubClassComposer.java     | 1058 +++-------------
     ...tractServiceStubSettingsClassComposer.java |  288 ++++-
     ...ractTransportServiceStubClassComposer.java | 1077 +++++++++++++++++
     .../common/RetrySettingsComposer.java         |   14 +-
     .../common/ServiceStubClassComposer.java      |  283 -----
     .../composer/common/TransportContext.java     |   68 +-
     .../defaultvalue/DefaultValueComposer.java    |   26 +-
     .../gapic/composer/grpc/GrpcContext.java      |   30 +-
     .../grpc/GrpcServiceStubClassComposer.java    |   17 +-
     .../grpc/ServiceClientClassComposer.java      |   30 +
     .../grpc/ServiceClientTestClassComposer.java  |    9 +-
     .../grpc/ServiceStubClassComposer.java        |   30 +
     .../ServiceStubSettingsClassComposer.java     |  117 +-
     .../gapic/composer/grpcrest/BUILD.bazel       |   55 +
     .../composer/grpcrest/GrpcRestContext.java    |   95 ++
     ...ttpJsonServiceClientTestClassComposer.java |   57 +
     .../HttpJsonServiceStubClassComposer.java     |   40 +
     .../grpcrest/ServiceClientClassComposer.java  |   29 +
     .../ServiceSettingsClassComposer.java         |   68 ++
     .../grpcrest/ServiceStubClassComposer.java    |   47 +
     .../ServiceStubSettingsClassComposer.java     |  200 +++
     ...onServiceCallableFactoryClassComposer.java |   16 +-
     .../HttpJsonServiceStubClassComposer.java     |  268 ++--
     .../gapic/composer/rest/RestContext.java      |   33 +-
     .../rest/ServiceClientClassComposer.java      |   30 +
     .../rest/ServiceClientTestClassComposer.java  |   27 +-
     .../rest/ServiceStubClassComposer.java        |   30 +
     .../ServiceStubSettingsClassComposer.java     |  107 +-
     .../ServiceClientSampleCodeComposer.java      |    2 +-
     .../gapic/composer/utils/ClassNames.java      |   53 +-
     .../generator/gapic/model/HttpBindings.java   |    4 +
     .../api/generator/gapic/model/Service.java    |   18 +
     .../api/generator/gapic/model/Transport.java  |    2 -
     .../gapic/protoparser/HttpRuleParser.java     |    1 +
     .../google/api/generator/gapic/BUILD.bazel    |    1 +
     .../gapic/composer/common/BUILD.bazel         |    2 -
     .../common/RetrySettingsComposerTest.java     |    5 +-
     .../generator/gapic/composer/grpc/BUILD.bazel |    2 +
     .../ServiceClientClassComposerTest.java       |   10 +-
     .../ServiceStubClassComposerTest.java         |    3 +-
     .../goldens/BookshopClient.golden             |    0
     .../goldens/DeprecatedServiceClient.golden    |    0
     .../goldens/DeprecatedServiceStub.golden      |    0
     .../goldens/EchoClient.golden                 |    0
     .../{common => grpc}/goldens/EchoStub.golden  |    0
     .../goldens/IdentityClient.golden             |    0
     .../ServiceStubSettingsClassComposerTest.java |    2 +-
     .../goldens/ComplianceStubSettings.golden     |  531 ++------
     .../HttpJsonComplianceCallableFactory.golden  |   16 +-
     .../goldens/HttpJsonComplianceStub.golden     |    3 +-
     .../cloud/compute/v1/AddressesClient.java     |    4 +
     .../compute/v1/RegionOperationsClient.java    |  106 ++
     .../v1/RegionOperationsClientTest.java        |   69 ++
     .../compute/v1/RegionOperationsSettings.java  |   10 +
     .../cloud/compute/v1/gapic_metadata.json      |    3 +
     .../cloud/compute/v1/stub/AddressesStub.java  |    4 -
     .../v1/stub/AddressesStubSettings.java        |    2 +-
     .../v1/stub/HttpJsonAddressesStub.java        |    9 +-
     ...tpJsonRegionOperationsCallableFactory.java |   16 +-
     .../v1/stub/HttpJsonRegionOperationsStub.java |   48 +
     .../compute/v1/stub/RegionOperationsStub.java |   12 +
     .../v1/stub/RegionOperationsStubSettings.java |   30 +-
     79 files changed, 3410 insertions(+), 2173 deletions(-)
     create mode 100644 rules_java_gapic/resources/gradle/client_grpcrest.gradle.tmpl
     rename src/main/java/com/google/api/generator/gapic/composer/common/{ServiceClientClassComposer.java => AbstractServiceClientClassComposer.java} (94%)
     create mode 100644 src/main/java/com/google/api/generator/gapic/composer/common/AbstractTransportServiceStubClassComposer.java
     delete mode 100644 src/main/java/com/google/api/generator/gapic/composer/common/ServiceStubClassComposer.java
     create mode 100644 src/main/java/com/google/api/generator/gapic/composer/grpc/ServiceClientClassComposer.java
     create mode 100644 src/main/java/com/google/api/generator/gapic/composer/grpc/ServiceStubClassComposer.java
     create mode 100644 src/main/java/com/google/api/generator/gapic/composer/grpcrest/BUILD.bazel
     create mode 100644 src/main/java/com/google/api/generator/gapic/composer/grpcrest/GrpcRestContext.java
     create mode 100644 src/main/java/com/google/api/generator/gapic/composer/grpcrest/HttpJsonServiceClientTestClassComposer.java
     create mode 100644 src/main/java/com/google/api/generator/gapic/composer/grpcrest/HttpJsonServiceStubClassComposer.java
     create mode 100644 src/main/java/com/google/api/generator/gapic/composer/grpcrest/ServiceClientClassComposer.java
     create mode 100644 src/main/java/com/google/api/generator/gapic/composer/grpcrest/ServiceSettingsClassComposer.java
     create mode 100644 src/main/java/com/google/api/generator/gapic/composer/grpcrest/ServiceStubClassComposer.java
     create mode 100644 src/main/java/com/google/api/generator/gapic/composer/grpcrest/ServiceStubSettingsClassComposer.java
     create mode 100644 src/main/java/com/google/api/generator/gapic/composer/rest/ServiceClientClassComposer.java
     create mode 100644 src/main/java/com/google/api/generator/gapic/composer/rest/ServiceStubClassComposer.java
     rename src/test/java/com/google/api/generator/gapic/composer/{common => grpc}/ServiceClientClassComposerTest.java (89%)
     rename src/test/java/com/google/api/generator/gapic/composer/{common => grpc}/ServiceStubClassComposerTest.java (94%)
     rename src/test/java/com/google/api/generator/gapic/composer/{common => grpc}/goldens/BookshopClient.golden (100%)
     rename src/test/java/com/google/api/generator/gapic/composer/{common => grpc}/goldens/DeprecatedServiceClient.golden (100%)
     rename src/test/java/com/google/api/generator/gapic/composer/{common => grpc}/goldens/DeprecatedServiceStub.golden (100%)
     rename src/test/java/com/google/api/generator/gapic/composer/{common => grpc}/goldens/EchoClient.golden (100%)
     rename src/test/java/com/google/api/generator/gapic/composer/{common => grpc}/goldens/EchoStub.golden (100%)
     rename src/test/java/com/google/api/generator/gapic/composer/{common => grpc}/goldens/IdentityClient.golden (100%)
    
    diff --git a/WORKSPACE b/WORKSPACE
    index cc406611a9..50cac18478 100644
    --- a/WORKSPACE
    +++ b/WORKSPACE
    @@ -33,7 +33,7 @@ jvm_maven_import_external(
     # which in its turn, prioritizes actual generated clients runtime dependencies
     # over the generator dependencies.
     
    -_gax_java_version = "2.3.0"
    +_gax_java_version = "2.4.0"
     
     http_archive(
         name = "com_google_api_gax_java",
    diff --git a/repositories.bzl b/repositories.bzl
    index f2074f578d..6091b21171 100644
    --- a/repositories.bzl
    +++ b/repositories.bzl
    @@ -70,9 +70,9 @@ def gapic_generator_java_repositories():
         _maybe(
             http_archive,
             name = "com_google_googleapis_discovery",
    -        strip_prefix = "googleapis-discovery-2872d382ff767518e63d59ececf5d6f9224b21b4",
    +        strip_prefix = "googleapis-discovery-bb8a053b93ef8698297c41634aa9201f7e075277",
             urls = [
    -            "https://github.com/vam-google/googleapis-discovery/archive/2872d382ff767518e63d59ececf5d6f9224b21b4.zip",
    +            "https://github.com/vam-google/googleapis-discovery/archive/bb8a053b93ef8698297c41634aa9201f7e075277.zip",
             ],
         )
     
    diff --git a/rules_java_gapic/java_gapic.bzl b/rules_java_gapic/java_gapic.bzl
    index 65cb3617f7..91eb4ddb56 100644
    --- a/rules_java_gapic/java_gapic.bzl
    +++ b/rules_java_gapic/java_gapic.bzl
    @@ -135,7 +135,7 @@ def _java_gapic_srcjar(
     
         if grpc_service_config:
             file_args_dict[grpc_service_config] = "grpc-service-config"
    -    elif transport != "rest":
    +    elif not transport or transport == "grpc":
             for keyword in NO_GRPC_CONFIG_ALLOWLIST:
                 if keyword not in name:
                     fail("Missing a gRPC service config file")
    @@ -230,16 +230,25 @@ def java_gapic_library(
             "@javax_annotation_javax_annotation_api//jar",
         ]
     
    -    if transport == "rest":
    +    if not transport or transport == "grpc":
    +        actual_deps += [
    +            "@com_google_api_gax_java//gax-grpc:gax_grpc",
    +            "@io_grpc_grpc_java//core:core",
    +            "@io_grpc_grpc_java//protobuf:protobuf",
    +        ]
    +    elif transport == "rest":
             actual_deps += [
                 "@com_google_api_gax_java//gax-httpjson:gax_httpjson",
             ]
    -    else:
    +    elif transport == "grpc+rest":
             actual_deps += [
                 "@com_google_api_gax_java//gax-grpc:gax_grpc",
                 "@io_grpc_grpc_java//core:core",
                 "@io_grpc_grpc_java//protobuf:protobuf",
    +            "@com_google_api_gax_java//gax-httpjson:gax_httpjson",
             ]
    +    else:
    +        fail("Unknown transport: %s" % transport)
     
         native.java_library(
             name = name,
    @@ -256,18 +265,29 @@ def java_gapic_library(
             "@junit_junit//jar",
         ]
     
    -    if transport == "rest":
    +    if not transport or transport == "grpc":
    +        actual_test_deps += [
    +            "@com_google_api_gax_java//gax-grpc:gax_grpc_testlib",
    +            "@io_grpc_grpc_java//auth:auth",
    +            "@io_grpc_grpc_netty_shaded//jar",
    +            "@io_grpc_grpc_java//stub:stub",
    +            "@io_opencensus_opencensus_contrib_grpc_metrics//jar",
    +        ]
    +    elif transport == "rest":
             actual_test_deps += [
                 "@com_google_api_gax_java//gax-httpjson:gax_httpjson_testlib",
             ]
    -    else:
    +    elif transport == "grpc+rest":
             actual_test_deps += [
                 "@com_google_api_gax_java//gax-grpc:gax_grpc_testlib",
                 "@io_grpc_grpc_java//auth:auth",
                 "@io_grpc_grpc_netty_shaded//jar",
                 "@io_grpc_grpc_java//stub:stub",
                 "@io_opencensus_opencensus_contrib_grpc_metrics//jar",
    +            "@com_google_api_gax_java//gax-httpjson:gax_httpjson_testlib",
             ]
    +    else:
    +        fail("Unknown transport: %s" % transport)
     
         _append_dep_without_duplicates(actual_test_deps, test_deps)
         _append_dep_without_duplicates(actual_test_deps, actual_deps)
    diff --git a/rules_java_gapic/java_gapic_pkg.bzl b/rules_java_gapic/java_gapic_pkg.bzl
    index a6bca826d2..eb109db524 100644
    --- a/rules_java_gapic/java_gapic_pkg.bzl
    +++ b/rules_java_gapic/java_gapic_pkg.bzl
    @@ -351,10 +351,12 @@ def java_gapic_assembly_gradle_pkg(
             grpc_target_dep = ["%s" % grpc_target]
     
         if client_deps:
    -        if transport == "rest":
    -            template_label = Label("//rules_java_gapic:resources/gradle/client_rest.gradle.tmpl")
    -        else:
    +        if not transport or transport == "grpc":
                 template_label = Label("//rules_java_gapic:resources/gradle/client_grpc.gradle.tmpl")
    +        elif transport == "rest":
    +            template_label = Label("//rules_java_gapic:resources/gradle/client_rest.gradle.tmpl")
    +        elif transport == "grpc+rest":
    +            template_label = Label("//rules_java_gapic:resources/gradle/client_grpcrest.gradle.tmpl")
     
             _java_gapic_gradle_pkg(
                 name = client_target,
    diff --git a/rules_java_gapic/resources/gradle/assembly.gradle.tmpl b/rules_java_gapic/resources/gradle/assembly.gradle.tmpl
    index 3c0e59ee69..336a7a5c05 100644
    --- a/rules_java_gapic/resources/gradle/assembly.gradle.tmpl
    +++ b/rules_java_gapic/resources/gradle/assembly.gradle.tmpl
    @@ -12,8 +12,8 @@ subprojects {
       apply plugin: 'java'
       apply plugin: 'maven'
     
    -  sourceCompatibility = 1.7
    -  targetCompatibility = 1.7
    +  sourceCompatibility = 1.8
    +  targetCompatibility = 1.8
     
       test {
         testLogging {
    diff --git a/rules_java_gapic/resources/gradle/client_grpc.gradle.tmpl b/rules_java_gapic/resources/gradle/client_grpc.gradle.tmpl
    index 137f38d6f2..5ed53f6401 100644
    --- a/rules_java_gapic/resources/gradle/client_grpc.gradle.tmpl
    +++ b/rules_java_gapic/resources/gradle/client_grpc.gradle.tmpl
    @@ -9,8 +9,8 @@ apply plugin: 'java'
     description = 'GAPIC library for {{name}}'
     group = 'com.google.cloud'
     version = (findProperty('version') == 'unspecified') ? '0.0.0-SNAPSHOT' : version
    -sourceCompatibility = 1.7
    -targetCompatibility = 1.7
    +sourceCompatibility = 1.8
    +targetCompatibility = 1.8
     
     repositories {
       mavenCentral()
    diff --git a/rules_java_gapic/resources/gradle/client_grpcrest.gradle.tmpl b/rules_java_gapic/resources/gradle/client_grpcrest.gradle.tmpl
    new file mode 100644
    index 0000000000..fe5aa44622
    --- /dev/null
    +++ b/rules_java_gapic/resources/gradle/client_grpcrest.gradle.tmpl
    @@ -0,0 +1,63 @@
    +buildscript {
    +  repositories {
    +    mavenCentral()
    +  }
    +}
    +
    +apply plugin: 'java'
    +
    +description = 'GAPIC library for {{name}}'
    +group = 'com.google.cloud'
    +version = (findProperty('version') == 'unspecified') ? '0.0.0-SNAPSHOT' : version
    +sourceCompatibility = 1.8
    +targetCompatibility = 1.8
    +
    +repositories {
    +  mavenCentral()
    +  mavenLocal()
    +}
    +
    +compileJava.options.encoding = 'UTF-8'
    +javadoc.options.encoding = 'UTF-8'
    +
    +dependencies {
    +  compile 'com.google.api:gax:{{version.gax}}'
    +  testCompile 'com.google.api:gax:{{version.gax}}:testlib'
    +  compile 'com.google.api:gax-grpc:{{version.gax_grpc}}'
    +  testCompile 'com.google.api:gax-grpc:{{version.gax_grpc}}:testlib'
    +  compile 'com.google.api:gax-httpjson:{{version.gax_httpjson}}'
    +  testCompile 'com.google.api:gax-httpjson:{{version.gax_httpjson}}:testlib'
    +  testCompile 'io.grpc:grpc-netty-shaded:{{version.io_grpc}}'
    +  testCompile '{{maven.junit_junit}}'
    +  {{extra_deps}}
    +}
    +
    +task smokeTest(type: Test) {
    +  filter {
    +    includeTestsMatching "*SmokeTest"
    +    setFailOnNoMatchingTests false
    +  }
    +}
    +
    +test {
    +  exclude "**/*SmokeTest*"
    +}
    +
    +sourceSets {
    +  main {
    +    java {
    +      srcDir 'src/main/java'
    +    }
    +  }
    +}
    +
    +clean {
    +  delete 'all-jars'
    +}
    +
    +task allJars(type: Copy) {
    +  dependsOn test, jar
    +  into 'all-jars'
    +  // Replace with `from configurations.testRuntime, jar` to include test dependencies
    +  from configurations.runtime, jar
    +}
    diff --git a/rules_java_gapic/resources/gradle/client_rest.gradle.tmpl b/rules_java_gapic/resources/gradle/client_rest.gradle.tmpl
    index ef16323736..20fab62963 100644
    --- a/rules_java_gapic/resources/gradle/client_rest.gradle.tmpl
    +++ b/rules_java_gapic/resources/gradle/client_rest.gradle.tmpl
    @@ -9,8 +9,8 @@ apply plugin: 'java'
     description = 'GAPIC library for {{name}}'
     group = 'com.google.cloud'
     version = (findProperty('version') == 'unspecified') ? '0.0.0-SNAPSHOT' : version
    -sourceCompatibility = 1.7
    -targetCompatibility = 1.7
    +sourceCompatibility = 1.8
    +targetCompatibility = 1.8
     
     repositories {
       mavenCentral()
    diff --git a/rules_java_gapic/resources/gradle/grpc.gradle.tmpl b/rules_java_gapic/resources/gradle/grpc.gradle.tmpl
    index d5dfa3f3de..fbae0add76 100644
    --- a/rules_java_gapic/resources/gradle/grpc.gradle.tmpl
    +++ b/rules_java_gapic/resources/gradle/grpc.gradle.tmpl
    @@ -9,8 +9,8 @@ apply plugin: 'java'
     description = 'GRPC library for {{name}}'
     group = 'com.google.api.grpc'
     version = (findProperty('version') == 'unspecified') ? '0.0.0-SNAPSHOT' : version
    -sourceCompatibility = 1.7
    -targetCompatibility = 1.7
    +sourceCompatibility = 1.8
    +targetCompatibility = 1.8
     
     repositories {
       mavenCentral()
    diff --git a/rules_java_gapic/resources/gradle/proto.gradle.tmpl b/rules_java_gapic/resources/gradle/proto.gradle.tmpl
    index ad5e20fc33..27f0bf8448 100644
    --- a/rules_java_gapic/resources/gradle/proto.gradle.tmpl
    +++ b/rules_java_gapic/resources/gradle/proto.gradle.tmpl
    @@ -9,8 +9,8 @@ apply plugin: 'java'
     description = 'PROTO library for {{name}}'
     group = 'com.google.api.grpc'
     version = (findProperty('version') == 'unspecified') ? '0.0.0-SNAPSHOT' : version
    -sourceCompatibility = 1.7
    -targetCompatibility = 1.7
    +sourceCompatibility = 1.8
    +targetCompatibility = 1.8
     
     repositories {
       mavenCentral()
    diff --git a/src/main/java/com/google/api/generator/gapic/BUILD.bazel b/src/main/java/com/google/api/generator/gapic/BUILD.bazel
    index 9f6eb8954e..60cbc46d03 100644
    --- a/src/main/java/com/google/api/generator/gapic/BUILD.bazel
    +++ b/src/main/java/com/google/api/generator/gapic/BUILD.bazel
    @@ -9,6 +9,7 @@ filegroup(
             "//src/main/java/com/google/api/generator/gapic/composer/comment:comment_files",
             "//src/main/java/com/google/api/generator/gapic/composer/defaultvalue:defaultvalue_files",
             "//src/main/java/com/google/api/generator/gapic/composer/grpc:grpc_files",
    +        "//src/main/java/com/google/api/generator/gapic/composer/grpcrest:grpcrest_files",
             "//src/main/java/com/google/api/generator/gapic/composer/resourcename:resourcename_files",
             "//src/main/java/com/google/api/generator/gapic/composer/rest:rest_files",
             "//src/main/java/com/google/api/generator/gapic/composer/samplecode:samplecode_files",
    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 3cfcae2c62..0f09405d04 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,6 +21,7 @@ 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/grpcrest",
             "//src/main/java/com/google/api/generator/gapic/composer/resourcename",
             "//src/main/java/com/google/api/generator/gapic/composer/rest",
             "//src/main/java/com/google/api/generator/gapic/composer/samplecode",
    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 5c191b0a27..4eefc2845a 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
    @@ -15,22 +15,21 @@
     package com.google.api.generator.gapic.composer;
     
     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.ServiceClientClassComposer;
     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.ServiceStubClassComposer;
     import com.google.api.generator.gapic.composer.grpc.ServiceStubSettingsClassComposer;
    +import com.google.api.generator.gapic.composer.grpcrest.HttpJsonServiceClientTestClassComposer;
     import com.google.api.generator.gapic.composer.resourcename.ResourceNameHelperClassComposer;
     import com.google.api.generator.gapic.composer.rest.HttpJsonServiceCallableFactoryClassComposer;
     import com.google.api.generator.gapic.composer.rest.HttpJsonServiceStubClassComposer;
     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.GapicPackageInfo;
     import com.google.api.generator.gapic.model.Service;
    @@ -76,8 +75,10 @@ public static List generateStubClasses(GapicContext context) {
             .services()
             .forEach(
                 s -> {
    -              clazzes.add(ServiceStubClassComposer.instance().generate(context, s));
                   if (context.transport() == Transport.REST) {
    +                clazzes.add(
    +                    com.google.api.generator.gapic.composer.rest.ServiceStubClassComposer.instance()
    +                        .generate(context, s));
                     clazzes.add(
                         com.google.api.generator.gapic.composer.rest.ServiceStubSettingsClassComposer
                             .instance()
    @@ -85,11 +86,30 @@ public static List generateStubClasses(GapicContext context) {
                     clazzes.add(
                         HttpJsonServiceCallableFactoryClassComposer.instance().generate(context, s));
                     clazzes.add(HttpJsonServiceStubClassComposer.instance().generate(context, s));
    -              } else {
    +              } else if (context.transport() == Transport.GRPC) {
    +                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));
    +              } else if (context.transport() == Transport.GRPC_REST) {
    +                clazzes.add(
    +                    com.google.api.generator.gapic.composer.grpcrest.ServiceStubClassComposer
    +                        .instance()
    +                        .generate(context, s));
    +                clazzes.add(
    +                    com.google.api.generator.gapic.composer.grpcrest
    +                        .ServiceStubSettingsClassComposer.instance()
    +                        .generate(context, s));
    +                clazzes.add(
    +                    GrpcServiceCallableFactoryClassComposer.instance().generate(context, s));
    +                clazzes.add(GrpcServiceStubClassComposer.instance().generate(context, s));
    +                clazzes.add(
    +                    HttpJsonServiceCallableFactoryClassComposer.instance().generate(context, s));
    +                clazzes.add(
    +                    com.google.api.generator.gapic.composer.grpcrest
    +                        .HttpJsonServiceStubClassComposer.instance()
    +                        .generate(context, s));
                   }
                 });
         return clazzes;
    @@ -101,14 +121,27 @@ public static List generateClientSettingsClasses(GapicContext contex
             .services()
             .forEach(
                 s -> {
    -              clazzes.add(ServiceClientClassComposer.instance().generate(context, s));
                   if (context.transport() == Transport.REST) {
    +                clazzes.add(
    +                    com.google.api.generator.gapic.composer.rest.ServiceClientClassComposer
    +                        .instance()
    +                        .generate(context, s));
                     clazzes.add(
                         com.google.api.generator.gapic.composer.rest.ServiceSettingsClassComposer
                             .instance()
                             .generate(context, s));
    -              } else {
    +              } else if (context.transport() == Transport.GRPC) {
    +                clazzes.add(ServiceClientClassComposer.instance().generate(context, s));
                     clazzes.add(ServiceSettingsClassComposer.instance().generate(context, s));
    +              } else if (context.transport() == Transport.GRPC_REST) {
    +                clazzes.add(
    +                    com.google.api.generator.gapic.composer.grpcrest.ServiceClientClassComposer
    +                        .instance()
    +                        .generate(context, s));
    +                clazzes.add(
    +                    com.google.api.generator.gapic.composer.grpcrest.ServiceSettingsClassComposer
    +                        .instance()
    +                        .generate(context, s));
                   }
                 });
         return clazzes;
    @@ -120,7 +153,10 @@ public static List generateMockClasses(GapicContext context, List {
               if (context.transport() == Transport.REST) {
                 // REST transport tests donot not use mock services.
    -          } else {
    +          } else if (context.transport() == Transport.GRPC) {
    +            clazzes.add(MockServiceClassComposer.instance().generate(context, s));
    +            clazzes.add(MockServiceImplClassComposer.instance().generate(context, s));
    +          } else if (context.transport() == Transport.GRPC_REST) {
                 clazzes.add(MockServiceClassComposer.instance().generate(context, s));
                 clazzes.add(MockServiceImplClassComposer.instance().generate(context, s));
               }
    @@ -129,35 +165,25 @@ public static List generateMockClasses(GapicContext context, List generateTestClasses(GapicContext context) {
    -    return context.services().stream()
    -        .map(
    +    List clazzes = new ArrayList<>();
    +    context
    +        .services()
    +        .forEach(
                 s -> {
                   if (context.transport() == Transport.REST) {
    -                return com.google.api.generator.gapic.composer.rest.ServiceClientTestClassComposer
    -                    .instance()
    -                    .generate(context, s);
    -              } else {
    -                return ServiceClientTestClassComposer.instance().generate(context, s);
    +                clazzes.add(
    +                    com.google.api.generator.gapic.composer.rest.ServiceClientTestClassComposer
    +                        .instance()
    +                        .generate(context, s));
    +              } else if (context.transport() == Transport.GRPC) {
    +                clazzes.add(ServiceClientTestClassComposer.instance().generate(context, s));
    +              } else if (context.transport() == Transport.GRPC_REST) {
    +                clazzes.add(ServiceClientTestClassComposer.instance().generate(context, s));
    +                clazzes.add(HttpJsonServiceClientTestClassComposer.instance().generate(context, s));
                   }
    -            })
    -        .collect(Collectors.toList());
    -  }
    -
    -  /** ====================== HELPERS ==================== */
    -  // TODO(miraleung): Add method list.
    -  private static GapicClass generateGenericClass(Kind kind, String name, Service service) {
    -    String pakkage = service.pakkage();
    -    if (kind.equals(Kind.STUB)) {
    -      pakkage += ".stub";
    -    }
    +            });
     
    -    ClassDefinition classDef =
    -        ClassDefinition.builder()
    -            .setPackageString(pakkage)
    -            .setName(name)
    -            .setScope(ScopeNode.PUBLIC)
    -            .build();
    -    return GapicClass.create(kind, classDef);
    +    return clazzes;
       }
     
       @VisibleForTesting
    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 ea3898051c..f4e31a962e 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
    @@ -299,7 +299,7 @@ protected MethodDefinition createGenericCallableMethod(
       protected TypeNode getOperationsStubType(Service service) {
         TypeNode opeationsStubType = service.operationServiceStubType();
         if (opeationsStubType == null) {
    -      opeationsStubType = getTransportContext().operationsStubType();
    +      opeationsStubType = getTransportContext().operationsStubTypes().get(0);
         }
         return opeationsStubType;
       }
    diff --git a/src/main/java/com/google/api/generator/gapic/composer/common/ServiceClientClassComposer.java b/src/main/java/com/google/api/generator/gapic/composer/common/AbstractServiceClientClassComposer.java
    similarity index 94%
    rename from src/main/java/com/google/api/generator/gapic/composer/common/ServiceClientClassComposer.java
    rename to src/main/java/com/google/api/generator/gapic/composer/common/AbstractServiceClientClassComposer.java
    index 4f804822f1..6a9ec1b17a 100644
    --- a/src/main/java/com/google/api/generator/gapic/composer/common/ServiceClientClassComposer.java
    +++ b/src/main/java/com/google/api/generator/gapic/composer/common/AbstractServiceClientClassComposer.java
    @@ -85,19 +85,21 @@
     import java.util.Arrays;
     import java.util.Collections;
     import java.util.HashMap;
    +import java.util.HashSet;
    +import java.util.Iterator;
     import java.util.LinkedHashMap;
     import java.util.List;
     import java.util.Map;
     import java.util.Objects;
     import java.util.Optional;
    +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 ServiceClientClassComposer implements ClassComposer {
    -  private static final ServiceClientClassComposer INSTANCE = new ServiceClientClassComposer();
    +public abstract class AbstractServiceClientClassComposer implements ClassComposer {
       private static final String PAGED_RESPONSE_TYPE_NAME_PATTERN = "%sPagedResponse";
       private static final String CALLABLE_NAME_PATTERN = "%sCallable";
       private static final String PAGED_CALLABLE_NAME_PATTERN = "%sPagedCallable";
    @@ -115,10 +117,14 @@ private enum CallableMethodKind {
         PAGED,
       }
     
    -  private ServiceClientClassComposer() {}
    +  private final TransportContext transportContext;
     
    -  public static ServiceClientClassComposer instance() {
    -    return INSTANCE;
    +  protected AbstractServiceClientClassComposer(TransportContext transportContext) {
    +    this.transportContext = transportContext;
    +  }
    +
    +  protected TransportContext getTransportContext() {
    +    return transportContext;
       }
     
       @Override
    @@ -129,7 +135,7 @@ public GapicClass generate(GapicContext context, Service service) {
         String className = ClassNames.getServiceClientClassName(service);
         GapicClass.Kind kind = Kind.MAIN;
         String pakkage = service.pakkage();
    -    boolean hasLroClient = exposeOperationsClient(service);
    +    boolean hasLroClient = service.hasStandardLroMethods();
     
         Map> grpcRpcsToJavaMethodNames = new HashMap<>();
     
    @@ -198,7 +204,7 @@ private static List createClassHeaderComments(
             service, classMethodSampleCode, credentialsSampleCode, endpointSampleCode);
       }
     
    -  private static List createClassMethods(
    +  private List createClassMethods(
           Service service,
           Map messageTypes,
           TypeStore typeStore,
    @@ -216,23 +222,19 @@ private static List createClassMethods(
         return methods;
       }
     
    -  private static boolean exposeOperationsClient(Service service) {
    -    for (Method method : service.methods()) {
    -      if (method.hasLro() && method.lro().operationServiceStubType() == null) {
    -        return true;
    -      }
    -    }
    -    return false;
    -  }
    -
    -  private static List createFieldDeclarations(
    +  private List createFieldDeclarations(
           Service service, TypeStore typeStore, boolean hasLroClient) {
         Map fieldNameToTypes = new HashMap<>();
         fieldNameToTypes.put(
             "settings", typeStore.get(ClassNames.getServiceSettingsClassName(service)));
         fieldNameToTypes.put("stub", typeStore.get(ClassNames.getServiceStubClassName(service)));
         if (hasLroClient) {
    -      fieldNameToTypes.put("operationsClient", typeStore.get("OperationsClient"));
    +      Iterator opClientName = getTransportContext().operationsClientNames().iterator();
    +      Iterator opClientType = getTransportContext().operationsClientTypes().iterator();
    +
    +      while (opClientName.hasNext() && opClientType.hasNext()) {
    +        fieldNameToTypes.put(opClientName.next(), opClientType.next());
    +      }
         }
     
         return fieldNameToTypes.entrySet().stream()
    @@ -352,14 +354,13 @@ private static List createStaticCreatorMethods(
         return methods;
       }
     
    -  private static List createConstructorMethods(
    +  private List createConstructorMethods(
           Service service, TypeStore typeStore, boolean hasLroClient) {
         List methods = new ArrayList<>();
         String thisClientName = ClassNames.getServiceClientClassName(service);
         String settingsName = ClassNames.getServiceSettingsClassName(service);
         TypeNode thisClassType = typeStore.get(thisClientName);
         TypeNode stubSettingsType = typeStore.get(ClassNames.getServiceStubSettingsClassName(service));
    -    TypeNode operationsClientType = typeStore.get("OperationsClient");
         TypeNode exceptionType = typeStore.get("IOException");
     
         TypeNode settingsType = typeStore.get(settingsName);
    @@ -372,9 +373,6 @@ private static List createConstructorMethods(
                     .setType(typeStore.get(ClassNames.getServiceStubClassName(service)))
                     .setName("stub")
                     .build());
    -    VariableExpr operationsClientVarExpr =
    -        VariableExpr.withVariable(
    -            Variable.builder().setType(operationsClientType).setName("operationsClient").build());
     
         // Create the ServiceClient(ServiceSettings settings) ctor.
         List ctorAssignmentExprs = new ArrayList<>();
    @@ -404,25 +402,10 @@ private static List createConstructorMethods(
                         .build())
                 .build());
     
    -    Expr clientArgExpr =
    -        MethodInvocationExpr.builder()
    -            .setExprReferenceExpr(stubVarExpr.toBuilder().setExprReferenceExpr(thisExpr).build())
    -            .setMethodName("getOperationsStub")
    -            .build();
    -    AssignmentExpr operationsClientAssignExpr =
    -        AssignmentExpr.builder()
    -            .setVariableExpr(
    -                operationsClientVarExpr.toBuilder().setExprReferenceExpr(thisExpr).build())
    -            .setValueExpr(
    -                MethodInvocationExpr.builder()
    -                    .setStaticReferenceType(operationsClientType)
    -                    .setMethodName("create")
    -                    .setArguments(clientArgExpr)
    -                    .setReturnType(operationsClientVarExpr.type())
    -                    .build())
    -            .build();
    +    List operationsClientAssignExprs =
    +        createOperationsClientAssignExprs(thisExpr, stubVarExpr);
         if (hasLroClient) {
    -      ctorAssignmentExprs.add(operationsClientAssignExpr);
    +      ctorAssignmentExprs.addAll(operationsClientAssignExprs);
         }
     
         methods.add(
    @@ -453,7 +436,7 @@ private static List createConstructorMethods(
                 .setValueExpr(stubVarExpr)
                 .build());
         if (hasLroClient) {
    -      ctorAssignmentExprs.add(operationsClientAssignExpr);
    +      ctorAssignmentExprs.addAll(operationsClientAssignExprs);
         }
         AnnotationNode betaAnnotation =
             AnnotationNode.builder()
    @@ -476,15 +459,70 @@ private static List createConstructorMethods(
         return methods;
       }
     
    -  private static List createGetterMethods(
    +  private List createOperationsClientAssignExprs(
    +      Expr thisExpr, VariableExpr stubVarExpr) {
    +    List operationsClientAssignExprs = new ArrayList<>();
    +
    +    Iterator opClientTypesIt = getTransportContext().operationsClientTypes().iterator();
    +    Iterator opClientNamesIt = getTransportContext().operationsClientNames().iterator();
    +    Iterator opStubNamesIt =
    +        getTransportContext().transportOperationsStubNames().iterator();
    +
    +    while (opClientTypesIt.hasNext() && opClientNamesIt.hasNext() && opStubNamesIt.hasNext()) {
    +      TypeNode operationsClientType = opClientTypesIt.next();
    +      String opClientName = opClientNamesIt.next();
    +      String opStubName = opStubNamesIt.next();
    +
    +      VariableExpr operationsClientVarExpr =
    +          VariableExpr.withVariable(
    +              Variable.builder().setType(operationsClientType).setName(opClientName).build());
    +
    +      String operationsStubGetterName =
    +          String.format("get%s", JavaStyle.toUpperCamelCase(opStubName));
    +
    +      Expr clientArgExpr =
    +          MethodInvocationExpr.builder()
    +              .setExprReferenceExpr(stubVarExpr.toBuilder().setExprReferenceExpr(thisExpr).build())
    +              .setMethodName(operationsStubGetterName)
    +              .build();
    +
    +      AssignmentExpr operationsClientAssignExpr =
    +          AssignmentExpr.builder()
    +              .setVariableExpr(
    +                  operationsClientVarExpr.toBuilder().setExprReferenceExpr(thisExpr).build())
    +              .setValueExpr(
    +                  MethodInvocationExpr.builder()
    +                      .setStaticReferenceType(operationsClientType)
    +                      .setMethodName("create")
    +                      .setArguments(clientArgExpr)
    +                      .setReturnType(operationsClientVarExpr.type())
    +                      .build())
    +              .build();
    +      operationsClientAssignExprs.add(operationsClientAssignExpr);
    +    }
    +
    +    return operationsClientAssignExprs;
    +  }
    +
    +  private List createGetterMethods(
           Service service, TypeStore typeStore, boolean hasLroClient) {
         Map methodNameToTypes = new LinkedHashMap<>();
         methodNameToTypes.put(
             "getSettings", typeStore.get(ClassNames.getServiceSettingsClassName(service)));
         methodNameToTypes.put("getStub", typeStore.get(ClassNames.getServiceStubClassName(service)));
    -    String getOperationsClientMethodName = "getOperationsClient";
    +
    +    Set getOperationsClientMethodNames = new HashSet<>();
    +
         if (hasLroClient) {
    -      methodNameToTypes.put(getOperationsClientMethodName, typeStore.get("OperationsClient"));
    +      Iterator opClientNamesIt = getTransportContext().operationsClientNames().iterator();
    +      Iterator opClientTypesIt = getTransportContext().operationsClientTypes().iterator();
    +
    +      while (opClientNamesIt.hasNext() && opClientTypesIt.hasNext()) {
    +        String opClientMethodName =
    +            String.format("get%s", JavaStyle.toUpperCamelCase(opClientNamesIt.next()));
    +        getOperationsClientMethodNames.add(opClientMethodName);
    +        methodNameToTypes.put(opClientMethodName, opClientTypesIt.next());
    +      }
         }
         AnnotationNode betaStubAnnotation =
             AnnotationNode.builder()
    @@ -500,7 +538,7 @@ private static List createGetterMethods(
                   TypeNode methodReturnType = e.getValue();
                   String returnVariableName = JavaStyle.toLowerCamelCase(methodName.substring(3));
                   MethodDefinition.Builder methodBuilder = MethodDefinition.builder();
    -              if (methodName.equals(getOperationsClientMethodName)) {
    +              if (getOperationsClientMethodNames.contains(methodName)) {
                     methodBuilder =
                         methodBuilder.setHeaderCommentStatements(
                             ServiceClientCommentComposer.GET_OPERATIONS_CLIENT_METHOD_COMMENT);
    @@ -708,6 +746,7 @@ private static MethodDefinition createMethodDefaultMethod(
             method.isPaged()
                 ? typeStore.get(String.format(PAGED_RESPONSE_TYPE_NAME_PATTERN, method.name()))
                 : method.outputType();
    +    List annotations = new ArrayList<>();
         if (method.hasLro()) {
           LongrunningOperation lro = method.lro();
           methodOutputType =
    @@ -718,6 +757,13 @@ private static MethodDefinition createMethodDefaultMethod(
                       .copyAndSetGenerics(
                           Arrays.asList(
                               lro.responseType().reference(), lro.metadataType().reference())));
    +      if (method.hasLro() && method.lro().operationServiceStubType() != null) {
    +        annotations.add(
    +            AnnotationNode.withTypeAndDescription(
    +                typeStore.get("BetaApi"),
    +                "The surface for long-running operations is not stable yet and may change in the"
    +                    + " future."));
    +      }
         }
     
         // Construct the method that accepts a request proto.
    @@ -759,8 +805,7 @@ private static MethodDefinition createMethodDefaultMethod(
                 .setArguments(Arrays.asList(requestArgVarExpr));
     
         if (method.isDeprecated()) {
    -      methodBuilder =
    -          methodBuilder.setAnnotations(Arrays.asList(AnnotationNode.withType(TypeNode.DEPRECATED)));
    +      annotations.add(AnnotationNode.withType(TypeNode.DEPRECATED));
         }
     
         if (isProtoEmptyType(methodOutputType)) {
    @@ -772,6 +817,9 @@ private static MethodDefinition createMethodDefaultMethod(
           methodBuilder =
               methodBuilder.setReturnExpr(callableMethodExpr).setReturnType(methodOutputType);
         }
    +
    +    methodBuilder.setAnnotations(annotations);
    +
         return methodBuilder.build();
       }
     
    @@ -1681,8 +1729,6 @@ private static void createVaporTypes(Service service, TypeStore typeStore) {
               ClassNames.getServiceClientClassName(service));
         }
     
    -    // LRO Gapic-generated types.
    -    typeStore.put("com.google.longrunning", "OperationsClient");
         // Pagination types.
         typeStore.putAll(
             service.pakkage(),
    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 7d01cfbca3..364dd183b3 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
    @@ -109,12 +109,14 @@ public TransportContext getTransportContext() {
     
       @Override
       public GapicClass generate(GapicContext context, Service service) {
    +    return generate(ClassNames.getServiceClientTestClassName(service), context, service);
    +  }
    +
    +  protected GapicClass generate(String className, GapicContext context, Service service) {
         Map resourceNames = context.helperResourceNames();
    -    Map messageTypes = context.messages();
         String pakkage = service.pakkage();
         TypeStore typeStore = new TypeStore();
         addDynamicTypes(context, service, typeStore);
    -    String className = ClassNames.getServiceClientTestClassName(service);
         GapicClass.Kind kind = Kind.MAIN;
     
         Map classMemberVarExprs =
    @@ -196,7 +198,8 @@ private List createTestAdminMethods(
           TypeStore typeStore) {
         List javaMethods = new ArrayList<>();
         javaMethods.add(
    -        createStartStaticServerMethod(service, context, classMemberVarExprs, typeStore));
    +        createStartStaticServerMethod(
    +            service, context, classMemberVarExprs, typeStore, "newBuilder"));
         javaMethods.add(createStopServerMethod(service, classMemberVarExprs));
         javaMethods.add(createSetUpMethod(service, classMemberVarExprs, typeStore));
         javaMethods.add(createTearDownMethod(service, classMemberVarExprs));
    @@ -207,7 +210,8 @@ protected abstract MethodDefinition createStartStaticServerMethod(
           Service service,
           GapicContext context,
           Map classMemberVarExprs,
    -      TypeStore typeStore);
    +      TypeStore typeStore,
    +      String newBuilderMethod);
     
       protected abstract MethodDefinition createStopServerMethod(
           Service service, Map classMemberVarExprs);
    @@ -470,7 +474,7 @@ private MethodDefinition createRpcTestMethod(
                 VariableExpr.withVariable(
                     Variable.builder().setType(methodArg.type()).setName(methodArgName).build());
             argExprs.add(varExpr);
    -        Expr valExpr = DefaultValueComposer.createDefaultValue(methodArg, resourceNames);
    +        Expr valExpr = createDefaultValue(methodArg, resourceNames);
             methodExprs.add(
                 AssignmentExpr.builder()
                     .setVariableExpr(varExpr.toBuilder().setIsDecl(true).build())
    @@ -735,6 +739,9 @@ protected abstract List createStreamingRpcExceptionTestStatements(
           Map resourceNames,
           Map messageTypes);
     
    +  protected abstract Expr createDefaultValue(
    +      MethodArgument methodArg, Map resourceNames);
    +
       protected List createRpcExceptionTestStatements(
           Method method,
           List methodSignature,
    @@ -766,7 +773,7 @@ protected List createRpcExceptionTestStatements(
                 VariableExpr.withVariable(
                     Variable.builder().setType(methodArg.type()).setName(methodArgName).build());
             argVarExprs.add(varExpr);
    -        Expr valExpr = DefaultValueComposer.createDefaultValue(methodArg, resourceNames);
    +        Expr valExpr = createDefaultValue(methodArg, resourceNames);
             tryBodyExprs.add(
                 AssignmentExpr.builder()
                     .setVariableExpr(varExpr.toBuilder().setIsDecl(true).build())
    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 e59e689bb2..cd4f89cbb9 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
    @@ -62,11 +62,13 @@
     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 com.google.longrunning.Operation;
     import java.io.IOException;
     import java.util.ArrayList;
     import java.util.Arrays;
     import java.util.Collections;
    +import java.util.Iterator;
     import java.util.List;
     import java.util.Optional;
     import java.util.function.BiFunction;
    @@ -172,6 +174,7 @@ private List createClassMethods(Service service, TypeStore typ
         javaMethods.addAll(createSettingsGetterMethods(service, typeStore));
         javaMethods.add(createCreatorMethod(service, typeStore));
         javaMethods.addAll(createDefaultGetterMethods(service, typeStore));
    +    javaMethods.addAll(createNewBuilderMethods(service, typeStore, "newBuilder", "createDefault"));
         javaMethods.addAll(createBuilderHelperMethods(service, typeStore));
         javaMethods.add(createConstructorMethod(service, typeStore));
         return javaMethods;
    @@ -351,12 +354,19 @@ private List createDefaultGetterMethods(Service service, TypeS
                     "defaultCredentialsProviderBuilder",
                     typeMakerFn.apply(GoogleCredentialsProvider.Builder.class)),
                 SettingsCommentComposer.DEFAULT_CREDENTIALS_PROVIDER_BUILDER_METHOD_COMMENT));
    -    javaMethods.add(
    -        methodMakerFn.apply(
    -            methodStarterFn.apply(
    -                getTransportContext().defaultTransportProviderBuilderName(),
    -                typeMakerFn.apply(getTransportContext().instantiatingChannelProviderClass())),
    -            SettingsCommentComposer.DEFAULT_TRANSPORT_PROVIDER_BUILDER_METHOD_COMMENT));
    +
    +    Iterator providerBuilderNamesIt =
    +        getTransportContext().defaultTransportProviderBuilderNames().iterator();
    +    Iterator> channelProviderClassesIt =
    +        getTransportContext().instantiatingChannelProviderBuilderClasses().iterator();
    +    while (providerBuilderNamesIt.hasNext() && channelProviderClassesIt.hasNext()) {
    +      javaMethods.add(
    +          methodMakerFn.apply(
    +              methodStarterFn.apply(
    +                  providerBuilderNamesIt.next(),
    +                  typeMakerFn.apply(channelProviderClassesIt.next())),
    +              SettingsCommentComposer.DEFAULT_TRANSPORT_PROVIDER_BUILDER_METHOD_COMMENT));
    +    }
     
         javaMethods.add(
             methodStarterFn
    @@ -383,23 +393,31 @@ private List createDefaultGetterMethods(Service service, TypeS
         return javaMethods;
       }
     
    -  private static List createBuilderHelperMethods(
    -      Service service, TypeStore typeStore) {
    +  protected List createNewBuilderMethods(
    +      Service service,
    +      TypeStore typeStore,
    +      String newBuilderMethodName,
    +      String createDefaultMethodName) {
         TypeNode builderType = typeStore.get(BUILDER_CLASS_NAME);
    -    MethodDefinition newBuilderMethodOne =
    +    return ImmutableList.of(
             MethodDefinition.builder()
                 .setHeaderCommentStatements(SettingsCommentComposer.NEW_BUILDER_METHOD_COMMENT)
                 .setScope(ScopeNode.PUBLIC)
                 .setIsStatic(true)
                 .setReturnType(builderType)
    -            .setName("newBuilder")
    +            .setName(newBuilderMethodName)
                 .setReturnExpr(
                     MethodInvocationExpr.builder()
                         .setStaticReferenceType(builderType)
    -                    .setMethodName("createDefault")
    +                    .setMethodName(createDefaultMethodName)
                         .setReturnType(builderType)
                         .build())
    -            .build();
    +            .build());
    +  }
    +
    +  private static List createBuilderHelperMethods(
    +      Service service, TypeStore typeStore) {
    +    TypeNode builderType = typeStore.get(BUILDER_CLASS_NAME);
     
         VariableExpr clientContextVarExpr =
             VariableExpr.withVariable(
    @@ -439,10 +457,10 @@ private static List createBuilderHelperMethods(
                         .build())
                 .build();
     
    -    return Arrays.asList(newBuilderMethodOne, newBuilderMethodTwo, toBuilderMethod);
    +    return Arrays.asList(newBuilderMethodTwo, toBuilderMethod);
       }
     
    -  private static ClassDefinition createNestedBuilderClass(Service service, TypeStore typeStore) {
    +  private ClassDefinition createNestedBuilderClass(Service service, TypeStore typeStore) {
         return ClassDefinition.builder()
             .setHeaderCommentStatements(
                 SettingsCommentComposer.createBuilderClassComment(
    @@ -466,11 +484,12 @@ 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));
    -    javaMethods.add(createNestedBuilderCreatorMethod(service, typeStore));
    +    javaMethods.addAll(
    +        createNestedBuilderCreatorMethods(service, typeStore, "newBuilder", "createDefault"));
         javaMethods.add(createNestedBuilderStubSettingsBuilderMethod(service, typeStore));
         javaMethods.add(createNestedBuilderApplyToAllUnaryMethod(service, typeStore));
         javaMethods.addAll(createNestedBuilderSettingsGetterMethods(service, typeStore));
    @@ -557,23 +576,28 @@ private static List createNestedBuilderConstructorMethods(
         return Arrays.asList(noArgCtor, clientContextCtor, settingsCtor, stubSettingsCtor);
       }
     
    -  private static MethodDefinition createNestedBuilderCreatorMethod(
    -      Service service, TypeStore typeStore) {
    +  protected List createNestedBuilderCreatorMethods(
    +      Service service,
    +      TypeStore typeStore,
    +      String newBuilderMethodName,
    +      String createDefaultMethodName) {
         MethodInvocationExpr ctorArg =
             MethodInvocationExpr.builder()
                 .setStaticReferenceType(
                     typeStore.get(ClassNames.getServiceStubSettingsClassName(service)))
    -            .setMethodName("newBuilder")
    +            .setMethodName(newBuilderMethodName)
                 .build();
     
         TypeNode builderType = typeStore.get(BUILDER_CLASS_NAME);
    -    return MethodDefinition.builder()
    -        .setScope(ScopeNode.PRIVATE)
    -        .setIsStatic(true)
    -        .setReturnType(builderType)
    -        .setName("createDefault")
    -        .setReturnExpr(NewObjectExpr.builder().setType(builderType).setArguments(ctorArg).build())
    -        .build();
    +    return ImmutableList.of(
    +        MethodDefinition.builder()
    +            .setScope(ScopeNode.PRIVATE)
    +            .setIsStatic(true)
    +            .setReturnType(builderType)
    +            .setName(createDefaultMethodName)
    +            .setReturnExpr(
    +                NewObjectExpr.builder().setType(builderType).setArguments(ctorArg).build())
    +            .build());
       }
     
       private static MethodDefinition createNestedBuilderStubSettingsBuilderMethod(
    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 8935e0b00c..c54ccbde39 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
    @@ -16,39 +16,27 @@
     
     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.rpc.BidiStreamingCallable;
    -import com.google.api.gax.rpc.ClientContext;
     import com.google.api.gax.rpc.ClientStreamingCallable;
    +import com.google.api.gax.rpc.LongRunningClient;
     import com.google.api.gax.rpc.OperationCallable;
    -import com.google.api.gax.rpc.RequestParamsExtractor;
     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.AssignmentExpr;
     import com.google.api.generator.engine.ast.ClassDefinition;
    -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.Expr;
     import com.google.api.generator.engine.ast.ExprStatement;
    -import com.google.api.generator.engine.ast.JavaDocComment;
     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.ReferenceConstructorExpr;
    +import com.google.api.generator.engine.ast.Reference;
     import com.google.api.generator.engine.ast.ScopeNode;
     import com.google.api.generator.engine.ast.Statement;
    -import com.google.api.generator.engine.ast.ThisObjectValue;
     import com.google.api.generator.engine.ast.ThrowExpr;
    -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.VaporReference;
     import com.google.api.generator.engine.ast.Variable;
     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;
    @@ -57,40 +45,20 @@
     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 com.google.common.collect.ImmutableMap;
     import com.google.longrunning.Operation;
    -import java.io.IOException;
     import java.util.ArrayList;
     import java.util.Arrays;
     import java.util.Collections;
    -import java.util.LinkedHashMap;
    +import java.util.Iterator;
     import java.util.List;
     import java.util.Map;
    -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 abstract class AbstractServiceStubClassComposer implements ClassComposer {
    -  private static final Statement EMPTY_LINE_STATEMENT = EmptyLineStatement.create();
    -
    -  private static final String METHOD_DESCRIPTOR_NAME_PATTERN = "%sMethodDescriptor";
    +  private static final String DOT = ".";
       private static final String PAGED_RESPONSE_TYPE_NAME_PATTERN = "%sPagedResponse";
    -  private static final String PAGED_CALLABLE_CLASS_MEMBER_PATTERN = "%sPagedCallable";
    -
    -  private static final String BACKGROUND_RESOURCES_MEMBER_NAME = "backgroundResources";
    -  private static final String CALLABLE_NAME = "Callable";
    -  private static final String CALLABLE_FACTORY_MEMBER_NAME = "callableFactory";
    -  private static final String CALLABLE_CLASS_MEMBER_PATTERN = "%sCallable";
    -  private static final String OPERATION_CALLABLE_CLASS_MEMBER_PATTERN = "%sOperationCallable";
    -  private static final String OPERATION_CALLABLE_NAME = "OperationCallable";
    -  private static final String OPERATIONS_STUB_MEMBER_NAME = "operationsStub";
    -  private static final String PAGED_CALLABLE_NAME = "PagedCallable";
    -
    -  protected static final TypeStore FIXED_TYPESTORE = createStaticTypes();
     
       private final TransportContext transportContext;
     
    @@ -98,271 +66,38 @@ protected AbstractServiceStubClassComposer(TransportContext transportContext) {
         this.transportContext = transportContext;
       }
     
    -  public TransportContext getTransportContext() {
    +  protected TransportContext getTransportContext() {
         return transportContext;
       }
     
    -  private static TypeStore createStaticTypes() {
    -    List concreteClazzes =
    -        Arrays.asList(
    -            BackgroundResource.class,
    -            BackgroundResourceAggregation.class,
    -            BetaApi.class,
    -            BidiStreamingCallable.class,
    -            ClientContext.class,
    -            ClientStreamingCallable.class,
    -            Generated.class,
    -            ImmutableMap.class,
    -            InterruptedException.class,
    -            IOException.class,
    -            Operation.class,
    -            OperationCallable.class,
    -            RequestParamsExtractor.class,
    -            ServerStreamingCallable.class,
    -            TimeUnit.class,
    -            UnaryCallable.class);
    -    return new TypeStore(concreteClazzes);
    -  }
    -
       @Override
       public GapicClass generate(GapicContext context, Service service) {
    -    String pakkage = service.pakkage() + ".stub";
    -    TypeStore typeStore = createDynamicTypes(service, pakkage);
    -    String className = getTransportContext().classNames().getTransportServiceStubClassName(service);
    -    GapicClass.Kind kind = Kind.STUB;
    -
    -    Map protoMethodNameToDescriptorVarExprs =
    -        createProtoMethodNameToDescriptorClassMembers(
    -            service, getTransportContext().methodDescriptorClass());
    -
    -    Map callableClassMemberVarExprs =
    -        createCallableClassMembers(service, typeStore);
    -
    -    Map classMemberVarExprs = new LinkedHashMap<>();
    -    classMemberVarExprs.put(
    -        BACKGROUND_RESOURCES_MEMBER_NAME,
    -        VariableExpr.withVariable(
    -            Variable.builder()
    -                .setName(BACKGROUND_RESOURCES_MEMBER_NAME)
    -                .setType(FIXED_TYPESTORE.get("BackgroundResource"))
    -                .build()));
    -
    -
    -    TypeNode opeationsStubType = getTransportOperationsStubType(service);
    -    if (opeationsStubType != null) {
    -      classMemberVarExprs.put(
    -          OPERATIONS_STUB_MEMBER_NAME,
    -          VariableExpr.withVariable(
    -              Variable.builder()
    -                  .setName(OPERATIONS_STUB_MEMBER_NAME)
    -                  .setType(opeationsStubType)
    -                  .build()));
    -    }
    -
    -    boolean operationPollingMethod = checkOperationPollingMethod(service);
    -    if(operationPollingMethod) {
    -      VariableExpr longRunningVarExpr = declareLongRunningClient();
    -      if (longRunningVarExpr != null) {
    -        classMemberVarExprs.put("longRunningClient", longRunningVarExpr);
    -      }
    -    }
    -
    -    classMemberVarExprs.put(
    -        CALLABLE_FACTORY_MEMBER_NAME,
    -        VariableExpr.withVariable(
    -            Variable.builder()
    -                .setName(CALLABLE_FACTORY_MEMBER_NAME)
    -                .setType(getTransportContext().stubCallableFactoryType())
    -                .build()));
    -
         Map messageTypes = context.messages();
    -    List classStatements =
    -        createClassStatements(
    -            service,
    -            protoMethodNameToDescriptorVarExprs,
    -            callableClassMemberVarExprs,
    -            classMemberVarExprs,
    -            messageTypes);
    -
    -    StubCommentComposer commentComposer =
    -        new StubCommentComposer(getTransportContext().transportName());
    +    TypeStore typeStore = createTypes(service, messageTypes);
    +    String className = ClassNames.getServiceStubClassName(service);
    +    GapicClass.Kind kind = Kind.STUB;
    +    String pakkage = String.format("%s.stub", service.pakkage());
     
         ClassDefinition classDef =
             ClassDefinition.builder()
                 .setPackageString(pakkage)
                 .setHeaderCommentStatements(
    -                commentComposer.createTransportServiceStubClassHeaderComments(
    +                StubCommentComposer.createServiceStubClassHeaderComments(
                         service.name(), service.isDeprecated()))
    -            .setAnnotations(createClassAnnotations(service))
    -            .setScope(ScopeNode.PUBLIC)
    +            .setAnnotations(createClassAnnotations(service, typeStore))
    +            .setIsAbstract(true)
    +            .setImplementsTypes(createClassImplements(typeStore))
                 .setName(className)
    -            .setExtendsType(
    -                typeStore.get(getTransportContext().classNames().getServiceStubClassName(service)))
    -            .setStatements(classStatements)
    -            .setMethods(
    -                createClassMethods(
    -                    service,
    -                    typeStore,
    -                    classMemberVarExprs,
    -                    callableClassMemberVarExprs,
    -                    protoMethodNameToDescriptorVarExprs))
    +            .setMethods(createClassMethods(service, messageTypes, typeStore))
    +            .setScope(ScopeNode.PUBLIC)
                 .build();
         return GapicClass.create(kind, classDef);
       }
     
    -  protected abstract Statement createMethodDescriptorVariableDecl(
    -      Service service, Method protoMethod, VariableExpr methodDescriptorVarExpr, Map messageTypes);
    -
    -  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 List createClassStatements(
    -      Service service,
    -      Map protoMethodNameToDescriptorVarExprs,
    -      Map callableClassMemberVarExprs,
    -      Map classMemberVarExprs,
    -      Map messageTypes) {
    -    List classStatements = new ArrayList<>();
    -    for (Statement statement :
    -        createMethodDescriptorVariableDecls(service, protoMethodNameToDescriptorVarExprs, messageTypes)) {
    -      classStatements.add(statement);
    -      classStatements.add(EMPTY_LINE_STATEMENT);
    -    }
    -
    -    classStatements.addAll(createClassMemberFieldDeclarations(callableClassMemberVarExprs));
    -    classStatements.add(EMPTY_LINE_STATEMENT);
    -
    -    classStatements.addAll(createClassMemberFieldDeclarations(classMemberVarExprs));
    -    return classStatements;
    -  }
    -
    -  protected List createMethodDescriptorVariableDecls(
    -      Service service, Map protoMethodNameToDescriptorVarExprs, Map messageTypes) {
    -    return service.methods().stream()
    -        .map(
    -            m ->
    -                createMethodDescriptorVariableDecl(
    -                    service, m, protoMethodNameToDescriptorVarExprs.get(m.name()), messageTypes))
    -        .collect(Collectors.toList());
    -  }
    -
    -  private static List createClassMemberFieldDeclarations(
    -      Map fieldNameToVarExprs) {
    -    return fieldNameToVarExprs.values().stream()
    -        .map(
    -            v ->
    -                ExprStatement.withExpr(
    -                    v.toBuilder()
    -                        .setIsDecl(true)
    -                        .setScope(ScopeNode.PRIVATE)
    -                        .setIsFinal(true)
    -                        .build()))
    -        .collect(Collectors.toList());
    -  }
    -
    -  protected Map createProtoMethodNameToDescriptorClassMembers(
    -      Service service, Class descriptorClass) {
    -    return service.methods().stream()
    -        .collect(
    -            Collectors.toMap(
    -                Method::name,
    -                m ->
    -                    VariableExpr.withVariable(
    -                        Variable.builder()
    -                            .setName(
    -                                String.format(
    -                                    METHOD_DESCRIPTOR_NAME_PATTERN,
    -                                    JavaStyle.toLowerCamelCase(m.name())))
    -                            .setType(
    -                                TypeNode.withReference(
    -                                    ConcreteReference.builder()
    -                                        .setClazz(descriptorClass)
    -                                        .setGenerics(
    -                                            Arrays.asList(
    -                                                m.inputType().reference(),
    -                                                m.outputType().reference()))
    -                                        .build()))
    -                            .build()),
    -                (u, v) -> {
    -                  throw new IllegalStateException();
    -                },
    -                LinkedHashMap::new));
    -  }
    -
    -  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.
    -    for (Method protoMethod : service.methods()) {
    -      String javaStyleProtoMethodName = JavaStyle.toLowerCamelCase(protoMethod.name());
    -      String callableName = String.format(CALLABLE_CLASS_MEMBER_PATTERN, javaStyleProtoMethodName);
    -      callableClassMembers.put(
    -          callableName,
    -          VariableExpr.withVariable(
    -              Variable.builder()
    -                  .setName(callableName)
    -                  .setType(getCallableType(protoMethod))
    -                  .build()));
    -      if (protoMethod.hasLro()) {
    -        callableName =
    -            String.format(OPERATION_CALLABLE_CLASS_MEMBER_PATTERN, javaStyleProtoMethodName);
    -        callableClassMembers.put(
    -            callableName,
    -            VariableExpr.withVariable(
    -                Variable.builder()
    -                    .setName(callableName)
    -                    .setType(
    -                        TypeNode.withReference(
    -                            ConcreteReference.builder()
    -                                .setClazz(OperationCallable.class)
    -                                .setGenerics(
    -                                    Arrays.asList(
    -                                        protoMethod.inputType().reference(),
    -                                        protoMethod.lro().responseType().reference(),
    -                                        protoMethod.lro().metadataType().reference()))
    -                                .build()))
    -                    .build()));
    -      }
    -      if (protoMethod.isPaged()) {
    -        callableName = String.format(PAGED_CALLABLE_CLASS_MEMBER_PATTERN, javaStyleProtoMethodName);
    -        callableClassMembers.put(
    -            callableName,
    -            VariableExpr.withVariable(
    -                Variable.builder()
    -                    .setName(callableName)
    -                    .setType(
    -                        TypeNode.withReference(
    -                            getCallableType(protoMethod)
    -                                .reference()
    -                                .copyAndSetGenerics(
    -                                    Arrays.asList(
    -                                        protoMethod.inputType().reference(),
    -                                        typeStore
    -                                            .get(
    -                                                String.format(
    -                                                    PAGED_RESPONSE_TYPE_NAME_PATTERN,
    -                                                    protoMethod.name()))
    -                                            .reference()))))
    -                    .build()));
    -      }
    -    }
    -    return callableClassMembers;
    -  }
    -
    -  protected List createClassAnnotations(Service service) {
    +  private static List createClassAnnotations(Service service, TypeStore typeStore) {
         List annotations = new ArrayList<>();
         if (!PackageChecker.isGaApi(service.pakkage())) {
    -      annotations.add(AnnotationNode.withType(FIXED_TYPESTORE.get("BetaApi")));
    +      annotations.add(AnnotationNode.withType(typeStore.get("BetaApi")));
         }
     
         if (service.isDeprecated()) {
    @@ -371,589 +106,169 @@ protected List createClassAnnotations(Service service) {
     
         annotations.add(
             AnnotationNode.builder()
    -            .setType(FIXED_TYPESTORE.get("Generated"))
    +            .setType(typeStore.get("Generated"))
                 .setDescription("by gapic-generator-java")
                 .build());
         return annotations;
       }
     
    -  protected List createClassMethods(
    -      Service service,
    -      TypeStore typeStore,
    -      Map classMemberVarExprs,
    -      Map callableClassMemberVarExprs,
    -      Map protoMethodNameToDescriptorVarExprs) {
    -    List javaMethods = new ArrayList<>();
    -    javaMethods.addAll(createStaticCreatorMethods(service, typeStore));
    -    javaMethods.addAll(
    -        createConstructorMethods(
    -            service,
    -            typeStore,
    -            classMemberVarExprs,
    -            callableClassMemberVarExprs,
    -            protoMethodNameToDescriptorVarExprs));
    -    javaMethods.addAll(
    -        createGetMethodDescriptorsMethod(service, typeStore, protoMethodNameToDescriptorVarExprs));
    -    javaMethods.addAll(
    -        createOperationsStubGetterMethod(classMemberVarExprs.get(OPERATIONS_STUB_MEMBER_NAME)));
    -    javaMethods.addAll(createCallableGetterMethods(callableClassMemberVarExprs));
    -    javaMethods.addAll(
    -        createStubOverrideMethods(classMemberVarExprs.get(BACKGROUND_RESOURCES_MEMBER_NAME), service));
    -    return javaMethods;
    +  private static List createClassImplements(TypeStore typeStore) {
    +    return Arrays.asList(typeStore.get("BackgroundResource"));
       }
     
    -  private List createStaticCreatorMethods(Service service, TypeStore typeStore) {
    -    TypeNode creatorMethodReturnType =
    -        typeStore.get(getTransportContext().classNames().getTransportServiceStubClassName(service));
    -    Function, MethodDefinition.Builder> creatorMethodStarterFn =
    -        argList ->
    -            MethodDefinition.builder()
    -                .setScope(ScopeNode.PUBLIC)
    -                .setIsStatic(true)
    -                .setIsFinal(true)
    -                .setReturnType(creatorMethodReturnType)
    -                .setName("create")
    -                .setArguments(
    -                    argList.stream()
    -                        .map(v -> v.toBuilder().setIsDecl(true).build())
    -                        .collect(Collectors.toList()))
    -                .setThrowsExceptions(
    -                    Arrays.asList(
    -                        TypeNode.withReference(ConcreteReference.withClazz(IOException.class))));
    -
    -    Function, Expr> instantiatorExprFn =
    -        argList ->
    -            NewObjectExpr.builder().setType(creatorMethodReturnType).setArguments(argList).build();
    -
    -    TypeNode stubSettingsType =
    -        typeStore.get(getTransportContext().classNames().getServiceStubSettingsClassName(service));
    -    VariableExpr settingsVarExpr =
    -        VariableExpr.withVariable(
    -            Variable.builder().setName("settings").setType(stubSettingsType).build());
    -
    -    TypeNode clientContextType = FIXED_TYPESTORE.get("ClientContext");
    -    VariableExpr clientContextVarExpr =
    -        VariableExpr.withVariable(
    -            Variable.builder().setName("clientContext").setType(clientContextType).build());
    -
    -    VariableExpr callableFactoryVarExpr =
    -        VariableExpr.withVariable(
    -            Variable.builder()
    -                .setName("callableFactory")
    -                .setType(getTransportContext().stubCallableFactoryType())
    -                .build());
    -
    -    MethodInvocationExpr clientContextCreateMethodExpr =
    -        MethodInvocationExpr.builder()
    -            .setMethodName("create")
    -            .setStaticReferenceType(clientContextType)
    -            .setArguments(Arrays.asList(settingsVarExpr))
    -            .build();
    -    MethodInvocationExpr settingsBuilderMethodExpr =
    -        MethodInvocationExpr.builder()
    -            .setMethodName("newBuilder")
    -            .setStaticReferenceType(stubSettingsType)
    -            .build();
    -    settingsBuilderMethodExpr =
    -        MethodInvocationExpr.builder()
    -            .setMethodName("build")
    -            .setExprReferenceExpr(settingsBuilderMethodExpr)
    -            .build();
    +  private List createClassMethods(
    +      Service service, Map messageTypes, TypeStore typeStore) {
    +    List methods = new ArrayList<>();
    +    if (service.hasStandardLroMethods()) {
    +      TypeNode operationsStubType = service.operationServiceStubType();
    +      methods.addAll(createOperationsStubGetters(typeStore, operationsStubType));
    +    }
     
    -    return Arrays.asList(
    -        creatorMethodStarterFn
    -            .apply(Arrays.asList(settingsVarExpr))
    -            .setReturnExpr(
    -                instantiatorExprFn.apply(
    -                    Arrays.asList(settingsVarExpr, clientContextCreateMethodExpr)))
    -            .build(),
    -        creatorMethodStarterFn
    -            .apply(Arrays.asList(clientContextVarExpr))
    -            .setReturnExpr(
    -                instantiatorExprFn.apply(
    -                    Arrays.asList(settingsBuilderMethodExpr, clientContextVarExpr)))
    -            .build(),
    -        creatorMethodStarterFn
    -            .apply(Arrays.asList(clientContextVarExpr, callableFactoryVarExpr))
    -            .setReturnExpr(
    -                instantiatorExprFn.apply(
    -                    Arrays.asList(
    -                        settingsBuilderMethodExpr, clientContextVarExpr, callableFactoryVarExpr)))
    -            .build());
    +    if (service.operationPollingMethod() != null) {
    +      methods.addAll(createLongRunningClientGetters(typeStore));
    +     }
    +    methods.addAll(createCallableGetters(service, messageTypes, typeStore));
    +    methods.addAll(createBackgroundResourceMethodOverrides());
    +    return methods;
       }
     
    -  protected List createConstructorMethods(
    -      Service service,
    -      TypeStore typeStore,
    -      Map classMemberVarExprs,
    -      Map callableClassMemberVarExprs,
    -      Map protoMethodNameToDescriptorVarExprs) {
    -    TypeNode stubSettingsType =
    -        typeStore.get(getTransportContext().classNames().getServiceStubSettingsClassName(service));
    -    VariableExpr settingsVarExpr =
    -        VariableExpr.withVariable(
    -            Variable.builder().setName("settings").setType(stubSettingsType).build());
    -
    -    TypeNode clientContextType = FIXED_TYPESTORE.get("ClientContext");
    -    VariableExpr clientContextVarExpr =
    -        VariableExpr.withVariable(
    -            Variable.builder().setName("clientContext").setType(clientContextType).build());
    -
    -    VariableExpr callableFactoryVarExpr =
    -        VariableExpr.withVariable(
    -            Variable.builder()
    -                .setName("callableFactory")
    -                .setType(getTransportContext().stubCallableFactoryType())
    -                .build());
    -
    -    TypeNode thisClassType =
    -        typeStore.get(getTransportContext().classNames().getTransportServiceStubClassName(service));
    -    TypeNode ioExceptionType =
    -        TypeNode.withReference(ConcreteReference.withClazz(IOException.class));
    -
    -    BiFunction, List, MethodDefinition> ctorMakerFn =
    -        (args, body) ->
    -            MethodDefinition.constructorBuilder()
    -                .setScope(ScopeNode.PROTECTED)
    -                .setReturnType(thisClassType)
    -                .setHeaderCommentStatements(Arrays.asList(createProtectedCtorComment(service)))
    -                .setArguments(
    -                    args.stream()
    -                        .map(v -> v.toBuilder().setIsDecl(true).build())
    -                        .collect(Collectors.toList()))
    -                .setThrowsExceptions(Arrays.asList(ioExceptionType))
    -                .setBody(body)
    -                .build();
    -
    -    // First constructor method.
    -    MethodDefinition firstCtor =
    -        ctorMakerFn.apply(
    -            Arrays.asList(settingsVarExpr, clientContextVarExpr),
    -            Arrays.asList(
    -                ExprStatement.withExpr(
    -                    ReferenceConstructorExpr.thisBuilder()
    -                        .setType(thisClassType)
    -                        .setArguments(
    -                            settingsVarExpr,
    -                            clientContextVarExpr,
    -                            NewObjectExpr.builder()
    -                                .setType(
    -                                    typeStore.get(
    -                                        getTransportContext()
    -                                            .classNames()
    -                                            .getTransportServiceCallableFactoryClassName(service)))
    -                                .build())
    -                        .build())));
    -
    -    Expr thisExpr =
    -        ValueExpr.withValue(
    -            ThisObjectValue.withType(
    -                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()
    -                    .setExprReferenceExpr(thisExpr)
    -                    .build())
    -            .setValueExpr(callableFactoryVarExpr)
    -            .build());
    -    VariableExpr operationsStubClassVarExpr = classMemberVarExprs.get(OPERATIONS_STUB_MEMBER_NAME);
    -
    -    TypeNode opeationsStubType = getTransportOperationsStubType(service);
    -    if (opeationsStubType != null) {
    -      secondCtorExprs.add(
    -          AssignmentExpr.builder()
    -              .setVariableExpr(
    -                  operationsStubClassVarExpr.toBuilder().setExprReferenceExpr(thisExpr).build())
    -              .setValueExpr(
    -                  MethodInvocationExpr.builder()
    -                      .setStaticReferenceType(opeationsStubType)
    -                      .setMethodName("create")
    -                      .setArguments(Arrays.asList(clientContextVarExpr, callableFactoryVarExpr))
    -                      .setReturnType(operationsStubClassVarExpr.type())
    -                      .build())
    -              .build());
    +  private List createCallableGetters(
    +      Service service, Map messageTypes, TypeStore typeStore) {
    +    // Use a traditional for-loop since the output cardinality is not necessarily 1:1 with that of
    +    // service.methods().
    +    List javaMethods = new ArrayList<>();
    +    for (Method method : service.methods()) {
    +      if (method.hasLro()) {
    +        javaMethods.add(createOperationCallableGetter(method, typeStore));
    +      }
    +      if (method.isPaged()) {
    +        javaMethods.add(createPagedCallableGetter(method, typeStore));
    +      }
    +      javaMethods.add(createCallableGetter(method, typeStore));
         }
    -    secondCtorStatements.addAll(
    -        secondCtorExprs.stream().map(e -> ExprStatement.withExpr(e)).collect(Collectors.toList()));
    -    secondCtorExprs.clear();
    -    secondCtorStatements.add(EMPTY_LINE_STATEMENT);
    -
    -    // Transport settings local variables.
    -    Map javaStyleMethodNameToTransportSettingsVarExprs =
    -        service.methods().stream()
    -            .collect(
    -                Collectors.toMap(
    -                    m -> JavaStyle.toLowerCamelCase(m.name()),
    -                    m ->
    -                        VariableExpr.withVariable(
    -                            Variable.builder()
    -                                .setName(
    -                                    String.format(
    -                                        "%sTransportSettings",
    -                                        JavaStyle.toLowerCamelCase(m.name())))
    -                                .setType(
    -                                    TypeNode.withReference(
    -                                        ConcreteReference.builder()
    -                                            .setClazz(getTransportContext().callSettingsClass())
    -                                            .setGenerics(
    -                                                Arrays.asList(
    -                                                    m.inputType().reference(),
    -                                                    m.outputType().reference()))
    -                                            .build()))
    -                                .build())));
    -
    -    secondCtorExprs.addAll(
    -        service.methods().stream()
    -            .map(
    -                m ->
    -                    createTransportSettingsInitExpr(
    -                        m,
    -                        javaStyleMethodNameToTransportSettingsVarExprs.get(
    -                            JavaStyle.toLowerCamelCase(m.name())),
    -                        protoMethodNameToDescriptorVarExprs.get(m.name())))
    -            .collect(Collectors.toList()));
    -    secondCtorStatements.addAll(
    -        secondCtorExprs.stream().map(e -> ExprStatement.withExpr(e)).collect(Collectors.toList()));
    -    secondCtorExprs.clear();
    -    secondCtorStatements.add(EMPTY_LINE_STATEMENT);
    -
    -    // Initialize Callable variables.
    -    secondCtorExprs.addAll(
    -        callableClassMemberVarExprs.entrySet().stream()
    -            .map(
    -                e ->
    -                    createCallableInitExpr(
    -                        e.getKey(),
    -                        e.getValue(),
    -                        callableFactoryVarExpr,
    -                        settingsVarExpr,
    -                        clientContextVarExpr,
    -                        operationsStubClassVarExpr,
    -                        thisExpr,
    -                        javaStyleMethodNameToTransportSettingsVarExprs))
    -            .collect(Collectors.toList()));
    -    secondCtorStatements.addAll(
    -        secondCtorExprs.stream().map(e -> ExprStatement.withExpr(e)).collect(Collectors.toList()));
    -    secondCtorExprs.clear();
    -    secondCtorStatements.add(EMPTY_LINE_STATEMENT);
    -
    -
    -    secondCtorStatements.addAll(createLongRunningClient(service, typeStore));
    -
    -    // Instantiate backgroundResources.
    -    MethodInvocationExpr getBackgroundResourcesMethodExpr =
    -        MethodInvocationExpr.builder()
    -            .setExprReferenceExpr(clientContextVarExpr)
    -            .setMethodName("getBackgroundResources")
    -            .build();
    -
    -    VariableExpr backgroundResourcesVarExpr = classMemberVarExprs.get("backgroundResources");
    -    secondCtorExprs.add(
    -        AssignmentExpr.builder()
    -            .setVariableExpr(
    -                backgroundResourcesVarExpr.toBuilder().setExprReferenceExpr(thisExpr).build())
    -            .setValueExpr(
    -                NewObjectExpr.builder()
    -                    .setType(FIXED_TYPESTORE.get("BackgroundResourceAggregation"))
    -                    .setArguments(Arrays.asList(getBackgroundResourcesMethodExpr))
    -                    .build())
    -            .build());
    -    secondCtorStatements.addAll(
    -        secondCtorExprs.stream().map(e -> ExprStatement.withExpr(e)).collect(Collectors.toList()));
    -    secondCtorExprs.clear();
    -
    -    // Second constructor method.
    -    MethodDefinition secondCtor =
    -        ctorMakerFn.apply(
    -            Arrays.asList(settingsVarExpr, clientContextVarExpr, callableFactoryVarExpr),
    -            secondCtorStatements);
    +    return javaMethods;
    +  }
     
    -    return Arrays.asList(firstCtor, secondCtor);
    +  private MethodDefinition createOperationCallableGetter(
    +      Method method, TypeStore typeStore) {
    +    return createCallableGetterHelper(method, typeStore, true, false);
       }
     
    -  protected List createLongRunningClient(Service service, TypeStore typeStore) {
    -    return ImmutableList.of();
    +  private MethodDefinition createPagedCallableGetter(Method method, TypeStore typeStore) {
    +    return createCallableGetterHelper(method, typeStore, false, true);
       }
     
    -  protected VariableExpr declareLongRunningClient() {
    -    return null;
    +  private MethodDefinition createCallableGetter(Method method, TypeStore typeStore) {
    +    return createCallableGetterHelper(method, typeStore, false, false);
       }
     
    -  private static Expr createCallableInitExpr(
    -      String callableVarName,
    -      VariableExpr callableVarExpr,
    -      VariableExpr callableFactoryVarExpr,
    -      VariableExpr settingsVarExpr,
    -      VariableExpr clientContextVarExpr,
    -      VariableExpr operationsStubClassVarExpr,
    -      Expr thisExpr,
    -      Map javaStyleMethodNameToTransportSettingsVarExprs) {
    -    boolean isOperation = callableVarName.endsWith(OPERATION_CALLABLE_NAME);
    -    boolean isPaged = callableVarName.endsWith(PAGED_CALLABLE_NAME);
    -    int sublength = 0;
    -    if (isOperation) {
    -      sublength = OPERATION_CALLABLE_NAME.length();
    -    } else if (isPaged) {
    -      sublength = PAGED_CALLABLE_NAME.length();
    -    } else {
    -      sublength = CALLABLE_NAME.length();
    -    }
    -    String javaStyleMethodName = callableVarName.substring(0, callableVarName.length() - sublength);
    -    List creatorMethodArgVarExprs = null;
    -    Expr transportSettingsVarExpr =
    -        javaStyleMethodNameToTransportSettingsVarExprs.get(javaStyleMethodName);
    -    if (transportSettingsVarExpr == null && isOperation) {
    -      // Try again, in case the name dtection above was inaccurate.
    -      isOperation = false;
    -      sublength = CALLABLE_NAME.length();
    -      javaStyleMethodName = callableVarName.substring(0, callableVarName.length() - sublength);
    -      transportSettingsVarExpr =
    -          javaStyleMethodNameToTransportSettingsVarExprs.get(javaStyleMethodName);
    +  private MethodDefinition createCallableGetterHelper(
    +      Method method, TypeStore typeStore, boolean isLroCallable, boolean isPaged) {
    +    TypeNode returnType;
    +    switch (method.stream()) {
    +      case CLIENT:
    +        returnType = typeStore.get("ClientStreamingCallable");
    +        break;
    +      case SERVER:
    +        returnType = typeStore.get("ServerStreamingCallable");
    +        break;
    +      case BIDI:
    +        returnType = typeStore.get("BidiStreamingCallable");
    +        break;
    +      case NONE:
    +        // Fall through.
    +      default:
    +        returnType = typeStore.get(isLroCallable ? "OperationCallable" : "UnaryCallable");
         }
    -    Preconditions.checkNotNull(
    -        transportSettingsVarExpr,
    +
    +    String methodName =
             String.format(
    -            "No transport settings variable found for method name %s", javaStyleMethodName));
    -    if (isOperation) {
    -      creatorMethodArgVarExprs =
    -          Arrays.asList(
    -              transportSettingsVarExpr,
    -              MethodInvocationExpr.builder()
    -                  .setExprReferenceExpr(settingsVarExpr)
    -                  .setMethodName(String.format("%sOperationSettings", javaStyleMethodName))
    -                  .build(),
    -              clientContextVarExpr,
    -              operationsStubClassVarExpr);
    +            "%s%sCallable",
    +            JavaStyle.toLowerCamelCase(method.name()),
    +            (isLroCallable ? "Operation" : isPaged ? "Paged" : ""));
    +    List genericRefs = new ArrayList<>();
    +    genericRefs.add(method.inputType().reference());
    +    if (method.hasLro() && isLroCallable) {
    +      genericRefs.add(method.lro().responseType().reference());
    +      genericRefs.add(method.lro().metadataType().reference());
    +    } else if (isPaged) {
    +      genericRefs.add(
    +          typeStore
    +              .get(String.format(PAGED_RESPONSE_TYPE_NAME_PATTERN, method.name()))
    +              .reference());
         } else {
    -      creatorMethodArgVarExprs =
    -          Arrays.asList(
    -              transportSettingsVarExpr,
    -              MethodInvocationExpr.builder()
    -                  .setExprReferenceExpr(settingsVarExpr)
    -                  .setMethodName(String.format("%sSettings", javaStyleMethodName))
    -                  .build(),
    -              clientContextVarExpr);
    +      genericRefs.add(method.outputType().reference());
         }
     
    -    String callableCreatorMethodName = getCallableCreatorMethodName(callableVarExpr.type());
    -    return AssignmentExpr.builder()
    -        .setVariableExpr(callableVarExpr.toBuilder().setExprReferenceExpr(thisExpr).build())
    -        .setValueExpr(
    -            MethodInvocationExpr.builder()
    -                .setExprReferenceExpr(callableFactoryVarExpr)
    -                .setMethodName(callableCreatorMethodName)
    -                .setArguments(creatorMethodArgVarExprs)
    -                .setReturnType(callableVarExpr.type())
    -                .build())
    -        .build();
    -  }
    -
    -  private static String getCallableCreatorMethodName(TypeNode callableVarExprType) {
    -    final String typeName = callableVarExprType.reference().name();
    -    String streamName = "Unary";
    +    List annotations =
    +        method.isDeprecated()
    +            ? Arrays.asList(AnnotationNode.withType(TypeNode.DEPRECATED))
    +            : Collections.emptyList();
     
    -    // Special handling for pagination methods.
    -    if (callableVarExprType.reference().generics().size() == 2
    -        && callableVarExprType.reference().generics().get(1).name().endsWith("PagedResponse")) {
    -      streamName = "Paged";
    -    } else {
    -      if (typeName.startsWith("Client")) {
    -        streamName = "ClientStreaming";
    -      } else if (typeName.startsWith("Server")) {
    -        streamName = "ServerStreaming";
    -      } else if (typeName.startsWith("Bidi")) {
    -        streamName = "BidiStreaming";
    -      } else if (typeName.startsWith("Operation")) {
    -        streamName = "Operation";
    -      }
    -    }
    -    return String.format("create%sCallable", streamName);
    -  }
    +    returnType = TypeNode.withReference(returnType.reference().copyAndSetGenerics(genericRefs));
     
    -  private static List createCallableGetterMethods(
    -      Map callableClassMemberVarExprs) {
    -    return callableClassMemberVarExprs.entrySet().stream()
    -        .map(
    -            e ->
    -                MethodDefinition.builder()
    -                    .setIsOverride(true)
    -                    .setScope(ScopeNode.PUBLIC)
    -                    .setReturnType(e.getValue().type())
    -                    .setName(e.getKey())
    -                    .setReturnExpr(e.getValue())
    -                    .build())
    -        .collect(Collectors.toList());
    +    return createCallableGetterMethodDefinition(returnType, methodName, annotations, typeStore);
       }
     
    -  private List createStubOverrideMethods(
    -      VariableExpr backgroundResourcesVarExpr, Service service) {
    -    Function methodMakerStarterFn =
    -        methodName ->
    -            MethodDefinition.builder()
    -                .setIsOverride(true)
    -                .setScope(ScopeNode.PUBLIC)
    -                .setName(methodName);
    -
    -    Function voidMethodMakerFn =
    -        methodName ->
    -            methodMakerStarterFn
    -                .apply(methodName)
    -                .setReturnType(TypeNode.VOID)
    -                .setBody(
    -                    Arrays.asList(
    -                        ExprStatement.withExpr(
    -                            MethodInvocationExpr.builder()
    -                                .setExprReferenceExpr(backgroundResourcesVarExpr)
    -                                .setMethodName(methodName)
    -                                .build())))
    -                .build();
    +  private List createOperationsStubGetters(TypeStore typeStore, TypeNode operationsStubType) {
    +    List getters = new ArrayList<>();
     
    -    Function booleanMethodMakerFn =
    -        methodName ->
    -            methodMakerStarterFn
    -                .apply(methodName)
    -                .setReturnType(TypeNode.BOOLEAN)
    -                .setReturnExpr(
    -                    MethodInvocationExpr.builder()
    -                        .setExprReferenceExpr(backgroundResourcesVarExpr)
    -                        .setMethodName(methodName)
    -                        .setReturnType(TypeNode.BOOLEAN)
    -                        .build())
    -                .build();
    +    Iterator operationStubNameIt =
    +        getTransportContext().transportOperationsStubNames().iterator();
    +    Iterator operationStubTypeIt = getTransportContext().operationsStubTypes().iterator();
     
    -    // Generate the close() method:
    -    //   @Override
    -    //   public final void close() {
    -    //     try {
    -    //       backgroundResources.close();
    -    //     } catch (RuntimeException e) {
    -    //       throw e;
    -    //     } catch (Exception e) {
    -    //       throw new IllegalStateException("Failed to close resource", e);
    -    //     }
    -    //  }
    +    while (operationStubNameIt.hasNext() && operationStubTypeIt.hasNext()) {
    +      String methodName =
    +          String.format("get%s", JavaStyle.toUpperCamelCase(operationStubNameIt.next()));
    +      //TODO: refactor this
    +      TypeNode actualOperationsStubType = operationStubTypeIt.next();
    +      if (operationsStubType != null) {
    +        actualOperationsStubType = operationsStubType;
    +      }
     
    -    VariableExpr catchRuntimeExceptionVarExpr =
    -        VariableExpr.builder()
    -            .setVariable(
    -                Variable.builder()
    -                    .setType(TypeNode.withExceptionClazz(RuntimeException.class))
    -                    .setName("e")
    -                    .build())
    -            .build();
    -    VariableExpr catchExceptionVarExpr =
    -        VariableExpr.builder()
    -            .setVariable(
    -                Variable.builder()
    -                    .setType(TypeNode.withExceptionClazz(Exception.class))
    -                    .setName("e")
    -                    .build())
    -            .build();
    -    List javaMethods = new ArrayList<>();
    -    if (service.operationPollingMethod() != null) {
    -      javaMethods.addAll(createLongRunningClientGetter());
    +      getters.add(createOperationsStubGetterMethodDefinition(actualOperationsStubType, methodName, typeStore));
         }
    -    javaMethods.add(
    -        methodMakerStarterFn
    -            .apply("close")
    -            .setIsFinal(true)
    -            .setReturnType(TypeNode.VOID)
    -            .setBody(
    -                Arrays.asList(
    -                    TryCatchStatement.builder()
    -                        .setTryBody(
    -                            Arrays.asList(
    -                                ExprStatement.withExpr(
    -                                    MethodInvocationExpr.builder()
    -                                        .setExprReferenceExpr(backgroundResourcesVarExpr)
    -                                        .setMethodName("close")
    -                                        .build())))
    -                        .addCatch(
    -                            catchRuntimeExceptionVarExpr.toBuilder().setIsDecl(true).build(),
    -                            Arrays.asList(
    -                                ExprStatement.withExpr(
    -                                    ThrowExpr.builder()
    -                                        .setThrowExpr(catchRuntimeExceptionVarExpr)
    -                                        .build())))
    -                        .addCatch(
    -                            catchExceptionVarExpr.toBuilder().setIsDecl(true).build(),
    -                            Arrays.asList(
    -                                ExprStatement.withExpr(
    -                                    ThrowExpr.builder()
    -                                        .setType(
    -                                            TypeNode.withExceptionClazz(
    -                                                IllegalStateException.class))
    -                                        .setMessageExpr(String.format("Failed to close resource"))
    -                                        .setCauseExpr(catchExceptionVarExpr)
    -                                        .build())))
    -                        .build()))
    -            .build());
    -    javaMethods.add(voidMethodMakerFn.apply("shutdown"));
    -    javaMethods.add(booleanMethodMakerFn.apply("isShutdown"));
    -    javaMethods.add(booleanMethodMakerFn.apply("isTerminated"));
    -    javaMethods.add(voidMethodMakerFn.apply("shutdownNow"));
     
    -    List awaitTerminationArgs =
    -        Arrays.asList(
    -            VariableExpr.withVariable(
    -                Variable.builder().setName("duration").setType(TypeNode.LONG).build()),
    -            VariableExpr.withVariable(
    -                Variable.builder()
    -                    .setName("unit")
    -                    .setType(FIXED_TYPESTORE.get("TimeUnit"))
    -                    .build()));
    -    javaMethods.add(
    -        methodMakerStarterFn
    -            .apply("awaitTermination")
    -            .setReturnType(TypeNode.BOOLEAN)
    -            .setArguments(
    -                awaitTerminationArgs.stream()
    -                    .map(v -> v.toBuilder().setIsDecl(true).build())
    -                    .collect(Collectors.toList()))
    -            .setThrowsExceptions(Arrays.asList(FIXED_TYPESTORE.get("InterruptedException")))
    -            .setReturnExpr(
    -                MethodInvocationExpr.builder()
    -                    .setExprReferenceExpr(backgroundResourcesVarExpr)
    -                    .setMethodName("awaitTermination")
    -                    .setArguments(
    -                        awaitTerminationArgs.stream()
    -                            .map(v -> (Expr) v)
    -                            .collect(Collectors.toList()))
    -                    .setReturnType(TypeNode.BOOLEAN)
    -                    .build())
    -            .build());
    -    return javaMethods;
    +    return getters;
       }
     
    -  private boolean checkOperationPollingMethod(Service service) {
    -    for(Method method : service.methods()) {
    -      if(method.isOperationPollingMethod()) {
    -        return true;
    -      }
    -    }
    -    return false;
    +  private List createLongRunningClientGetters(TypeStore typeStore) {
    +    return ImmutableList.of(createCallableGetterMethodDefinition(
    +        TypeNode.withReference(ConcreteReference.withClazz(LongRunningClient.class)),
    +        "longRunningClient",
    +        ImmutableList.of(AnnotationNode.withType(typeStore.get("BetaApi"))),
    +        typeStore));
       }
     
    -  protected List createLongRunningClientGetter() {
    -    return Collections.emptyList();
    +  private static List createBackgroundResourceMethodOverrides() {
    +    MethodDefinition closeMethod =
    +        MethodDefinition.builder()
    +            .setIsOverride(true)
    +            .setScope(ScopeNode.PUBLIC)
    +            .setIsAbstract(true)
    +            .setReturnType(TypeNode.VOID)
    +            .setName("close")
    +            .build();
    +    return Arrays.asList(closeMethod);
       }
     
    -  private TypeStore createDynamicTypes(Service service, String stubPakkage) {
    -    TypeStore typeStore = new TypeStore();
    -    typeStore.putAll(
    -        stubPakkage,
    +  private static TypeStore createTypes(Service service, Map messageTypes) {
    +    List concreteClazzes =
             Arrays.asList(
    -            getTransportContext().classNames().getTransportServiceStubClassName(service),
    -            getTransportContext().classNames().getServiceStubSettingsClassName(service),
    -            getTransportContext().classNames().getServiceStubClassName(service),
    -            getTransportContext()
    -                .classNames()
    -                .getTransportServiceCallableFactoryClassName(service)));
    +            BackgroundResource.class,
    +            BetaApi.class,
    +            BidiStreamingCallable.class,
    +            ClientStreamingCallable.class,
    +            Generated.class,
    +            Operation.class,
    +            OperationCallable.class,
    +            ServerStreamingCallable.class,
    +            UnaryCallable.class,
    +            UnsupportedOperationException.class);
    +    TypeStore typeStore = new TypeStore(concreteClazzes);
    +
    +    typeStore.put("com.google.longrunning.stub", "OperationsStub");
    +
         // Pagination types.
         typeStore.putAll(
             service.pakkage(),
    @@ -962,68 +277,45 @@ private TypeStore createDynamicTypes(Service service, String stubPakkage) {
                 .map(m -> String.format(PAGED_RESPONSE_TYPE_NAME_PATTERN, m.name()))
                 .collect(Collectors.toList()),
             true,
    -        getTransportContext().classNames().getServiceClientClassName(service));
    -    return typeStore;
    -  }
    +        ClassNames.getServiceClientClassName(service));
     
    -  private static TypeNode getCallableType(Method protoMethod) {
    -    TypeNode callableType = FIXED_TYPESTORE.get("UnaryCallable");
    -    switch (protoMethod.stream()) {
    -      case CLIENT:
    -        callableType = FIXED_TYPESTORE.get("ClientStreamingCallable");
    -        break;
    -      case SERVER:
    -        callableType = FIXED_TYPESTORE.get("ServerStreamingCallable");
    -        break;
    -      case BIDI:
    -        callableType = FIXED_TYPESTORE.get("BidiStreamingCallable");
    -        break;
    -      case NONE:
    -        // Fall through
    -      default:
    -        // Fall through
    -    }
    -
    -    return TypeNode.withReference(
    -        callableType
    -            .reference()
    -            .copyAndSetGenerics(
    -                Arrays.asList(
    -                    protoMethod.inputType().reference(), protoMethod.outputType().reference())));
    +    return typeStore;
       }
     
    -  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.",
    -                getTransportContext().classNames().getTransportServiceStubClassName(service))));
    +  protected MethodDefinition createCallableGetterMethodDefinition(
    +      TypeNode returnType, String methodName, List annotations, TypeStore typeStore) {
    +    return MethodDefinition.builder()
    +        .setScope(ScopeNode.PUBLIC)
    +        .setAnnotations(annotations)
    +        .setName(methodName)
    +        .setReturnType(returnType)
    +        .setBody(
    +            Arrays.asList(
    +                ExprStatement.withExpr(
    +                    ThrowExpr.builder()
    +                        .setType(typeStore.get("UnsupportedOperationException"))
    +                        .setMessageExpr(String.format("Not implemented: %s()", methodName))
    +                        .build())))
    +        .build();
       }
     
    -  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());
    +  protected MethodDefinition createOperationsStubGetterMethodDefinition(
    +      TypeNode returnType, String methodName, TypeStore typeStore) {
    +    return MethodDefinition.builder()
    +        .setScope(ScopeNode.PUBLIC)
    +        .setReturnType(returnType)
    +        .setName(methodName)
    +        .setBody(
    +            Arrays.asList(
    +                ExprStatement.withExpr(
    +                    ThrowExpr.builder()
    +                        .setType(typeStore.get("UnsupportedOperationException"))
    +                        .setMessageExpr(String.format("Not implemented: %s()", methodName))
    +                        .build())))
    +        .build();
       }
     
    -  protected TypeNode getTransportOperationsStubType(Service service) {
    -    TypeNode transportOpeationsStubType = service.operationServiceStubType();
    -    if (transportOpeationsStubType == null) {
    -      transportOpeationsStubType = getTransportContext().transportOperationsStubType();
    -    }
    -    else {
    -      transportOpeationsStubType = TypeNode.withReference(
    -          VaporReference.builder()
    -              .setName("HttpJson" + transportOpeationsStubType.reference().simpleName())
    -              .setPakkage(transportOpeationsStubType.reference().pakkage())
    -              .build());
    -    }
    -
    -    return transportOpeationsStubType;
    +  private static String getClientClassName(Service service) {
    +    return String.format("%sClient", service.overriddenName());
       }
     }
    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 c999fccb9d..d61456e1ad 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
    @@ -105,6 +105,7 @@
     import java.util.Arrays;
     import java.util.Collections;
     import java.util.HashSet;
    +import java.util.Iterator;
     import java.util.LinkedHashMap;
     import java.util.List;
     import java.util.Map;
    @@ -225,11 +226,125 @@ protected MethodDefinition createDefaultCredentialsProviderBuilderMethod() {
             .build();
       }
     
    -  protected abstract MethodDefinition createDefaultTransportTransportProviderBuilderMethod();
    +  protected List createDefaultTransportTransportProviderBuilderMethods() {
    +    // Create the defaultGrpcTransportProviderBuilder method.
    +    Iterator> providerClassIt =
    +        getTransportContext().instantiatingChannelProviderClasses().iterator();
    +    Iterator> providerBuilderClassIt =
    +        getTransportContext().instantiatingChannelProviderBuilderClasses().iterator();
    +    Iterator builderNamesIt =
    +        getTransportContext().defaultTransportProviderBuilderNames().iterator();
    +
    +    List methods = new ArrayList<>();
    +
    +    while (providerClassIt.hasNext()
    +        && providerBuilderClassIt.hasNext()
    +        && builderNamesIt.hasNext()) {
    +      TypeNode returnType =
    +          TypeNode.withReference(ConcreteReference.withClazz(providerBuilderClassIt.next()));
    +      TypeNode channelProviderType =
    +          TypeNode.withReference(ConcreteReference.withClazz(providerClassIt.next()));
    +
    +      MethodInvocationExpr transportChannelProviderBuilderExpr =
    +          MethodInvocationExpr.builder()
    +              .setStaticReferenceType(channelProviderType)
    +              .setMethodName("newBuilder")
    +              .setReturnType(returnType)
    +              .build();
    +      Expr returnExpr =
    +          initializeTransportProviderBuilder(transportChannelProviderBuilderExpr, returnType);
     
    -  protected abstract MethodDefinition createDefaultApiClientHeaderProviderBuilderMethod(
    +      MethodDefinition method =
    +          MethodDefinition.builder()
    +              .setHeaderCommentStatements(
    +                  SettingsCommentComposer.DEFAULT_TRANSPORT_PROVIDER_BUILDER_METHOD_COMMENT)
    +              .setScope(ScopeNode.PUBLIC)
    +              .setIsStatic(true)
    +              .setReturnType(returnType)
    +              .setName(builderNamesIt.next())
    +              .setReturnExpr(returnExpr)
    +              .build();
    +      methods.add(method);
    +    }
    +
    +    return methods;
    +  }
    +
    +  protected Expr initializeTransportProviderBuilder(
    +      MethodInvocationExpr transportChannelProviderBuilderExpr, TypeNode returnType) {
    +    return transportChannelProviderBuilderExpr;
    +  }
    +
    +  protected abstract List createApiClientHeaderProviderBuilderMethods(
           Service service, TypeStore typeStore);
     
    +  protected MethodDefinition createApiClientHeaderProviderBuilderMethod(
    +      Service service,
    +      TypeStore typeStore,
    +      String methodName,
    +      TypeNode gaxPropertiesType,
    +      String getTokenMethodName,
    +      String getVersionMethodName) {
    +    TypeNode 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(gaxPropertiesType)
    +                    .setMethodName(getTokenMethodName)
    +                    .build(),
    +                MethodInvocationExpr.builder()
    +                    .setStaticReferenceType(gaxPropertiesType)
    +                    .setMethodName(getVersionMethodName)
    +                    .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();
    +    return MethodDefinition.builder()
    +        .setAnnotations(Arrays.asList(annotation))
    +        .setScope(ScopeNode.PUBLIC)
    +        .setIsStatic(true)
    +        .setReturnType(returnType)
    +        .setName(methodName)
    +        .setReturnExpr(returnExpr)
    +        .build();
    +  }
    +
       public abstract MethodDefinition createDefaultTransportChannelProviderMethod();
     
       private List createClassAnnotations(Service service) {
    @@ -843,6 +958,7 @@ private List createClassMethods(
             createMethodSettingsGetterMethods(methodSettingsMemberVarExprs, deprecatedSettingVarNames));
         javaMethods.add(createCreateStubMethod(service, typeStore));
         javaMethods.addAll(createDefaultHelperAndGetterMethods(service, typeStore));
    +    javaMethods.addAll(createNewBuilderMethods(service, typeStore, "newBuilder", "createDefault"));
         javaMethods.addAll(createBuilderHelperMethods(service, typeStore));
         javaMethods.add(createClassConstructor(service, methodSettingsMemberVarExprs, typeStore));
         return javaMethods;
    @@ -875,11 +991,7 @@ private static List createMethodSettingsGetterMethods(
     
       private MethodDefinition createCreateStubMethod(Service service, TypeStore typeStore) {
         // Set up the if-statement.
    -    Expr tRansportNameExpr =
    -        MethodInvocationExpr.builder()
    -            .setStaticReferenceType(getTransportContext().transportChannelType())
    -            .setMethodName(getTransportContext().transportGetterName())
    -            .build();
    +    List bodyStatements = new ArrayList<>();
     
         Expr getTransportNameExpr =
             MethodInvocationExpr.builder().setMethodName("getTransportChannelProvider").build();
    @@ -889,31 +1001,48 @@ private MethodDefinition createCreateStubMethod(Service service, TypeStore typeS
                 .setMethodName("getTransportName")
                 .build();
     
    -    Expr ifConditionExpr =
    -        MethodInvocationExpr.builder()
    -            .setExprReferenceExpr(getTransportNameExpr)
    -            .setMethodName("equals")
    -            .setArguments(tRansportNameExpr)
    -            .setReturnType(TypeNode.BOOLEAN)
    -            .build();
    +    Iterator channelTypesIt = getTransportContext().transportChannelTypes().iterator();
    +    Iterator getterNameIt = getTransportContext().transportGetterNames().iterator();
    +    Iterator serivceStubClassNameIt =
    +        getTransportContext().classNames().getTransportServiceStubClassNames(service).iterator();
     
    -    Expr createExpr =
    -        MethodInvocationExpr.builder()
    -            .setStaticReferenceType(
    -                typeStore.get(
    -                    getTransportContext().classNames().getTransportServiceStubClassName(service)))
    -            .setMethodName("create")
    -            .setArguments(
    -                ValueExpr.withValue(
    -                    ThisObjectValue.withType(
    -                        typeStore.get(ClassNames.getServiceStubSettingsClassName(service)))))
    -            .build();
    +    while (channelTypesIt.hasNext() && getterNameIt.hasNext()) {
    +      TypeNode channelType = channelTypesIt.next();
    +      String getterName = getterNameIt.next();
    +      String serivceStubClassName = serivceStubClassNameIt.next();
     
    -    IfStatement ifStatement =
    -        IfStatement.builder()
    -            .setConditionExpr(ifConditionExpr)
    -            .setBody(Arrays.asList(ExprStatement.withExpr(ReturnExpr.withExpr(createExpr))))
    -            .build();
    +      Expr tRansportNameExpr =
    +          MethodInvocationExpr.builder()
    +              .setStaticReferenceType(channelType)
    +              .setMethodName(getterName)
    +              .build();
    +
    +      Expr ifConditionExpr =
    +          MethodInvocationExpr.builder()
    +              .setExprReferenceExpr(getTransportNameExpr)
    +              .setMethodName("equals")
    +              .setArguments(tRansportNameExpr)
    +              .setReturnType(TypeNode.BOOLEAN)
    +              .build();
    +
    +      Expr createExpr =
    +          MethodInvocationExpr.builder()
    +              .setStaticReferenceType(typeStore.get(serivceStubClassName))
    +              .setMethodName("create")
    +              .setArguments(
    +                  ValueExpr.withValue(
    +                      ThisObjectValue.withType(
    +                          typeStore.get(ClassNames.getServiceStubSettingsClassName(service)))))
    +              .build();
    +
    +      IfStatement ifStatement =
    +          IfStatement.builder()
    +              .setConditionExpr(ifConditionExpr)
    +              .setBody(Arrays.asList(ExprStatement.withExpr(ReturnExpr.withExpr(createExpr))))
    +              .build();
    +
    +      bodyStatements.add(ifStatement);
    +    }
     
         // Set up exception throwing.
         Expr errorMessageExpr =
    @@ -930,6 +1059,8 @@ private MethodDefinition createCreateStubMethod(Service service, TypeStore typeS
             ExprStatement.withExpr(
                 ThrowExpr.builder().setType(exceptionType).setMessageExpr(errorMessageExpr).build());
     
    +    bodyStatements.add(throwStatement);
    +
         // Put the method together.
         TypeNode returnType = typeStore.get(ClassNames.getServiceStubClassName(service));
         AnnotationNode annotation =
    @@ -945,7 +1076,7 @@ private MethodDefinition createCreateStubMethod(Service service, TypeStore typeS
             .setReturnType(returnType)
             .setName("createStub")
             .setThrowsExceptions(Arrays.asList(TypeNode.withExceptionClazz(IOException.class)))
    -        .setBody(Arrays.asList(ifStatement, throwStatement))
    +        .setBody(bodyStatements)
             .build();
       }
     
    @@ -1021,33 +1152,40 @@ private List createDefaultHelperAndGetterMethods(
                 .build());
     
         javaMethods.add(createDefaultCredentialsProviderBuilderMethod());
    -    javaMethods.add(createDefaultTransportTransportProviderBuilderMethod());
    +    javaMethods.addAll(createDefaultTransportTransportProviderBuilderMethods());
         javaMethods.add(createDefaultTransportChannelProviderMethod());
    -    javaMethods.add(createDefaultApiClientHeaderProviderBuilderMethod(service, typeStore));
    +    javaMethods.addAll(createApiClientHeaderProviderBuilderMethods(service, typeStore));
     
         return javaMethods;
       }
     
    -  private static List createBuilderHelperMethods(
    -      Service service, TypeStore typeStore) {
    -    List javaMethods = new ArrayList<>();
    +  protected List createNewBuilderMethods(
    +      Service service,
    +      TypeStore typeStore,
    +      String newBuilderMethodName,
    +      String createDefaultMethodName) {
         // Create the newBuilder() method.
         final TypeNode builderReturnType = typeStore.get(NESTED_BUILDER_CLASS_NAME);
    -    javaMethods.add(
    +    return ImmutableList.of(
             MethodDefinition.builder()
                 .setHeaderCommentStatements(SettingsCommentComposer.NEW_BUILDER_METHOD_COMMENT)
                 .setScope(ScopeNode.PUBLIC)
                 .setIsStatic(true)
                 .setReturnType(builderReturnType)
    -            .setName("newBuilder")
    +            .setName(newBuilderMethodName)
                 .setReturnExpr(
                     MethodInvocationExpr.builder()
                         .setStaticReferenceType(builderReturnType)
    -                    .setMethodName("createDefault")
    +                    .setMethodName(createDefaultMethodName)
                         .setReturnType(builderReturnType)
                         .build())
                 .build());
    +  }
     
    +  protected List createBuilderHelperMethods(
    +      Service service, TypeStore typeStore) {
    +    List javaMethods = new ArrayList<>();
    +    final TypeNode builderReturnType = typeStore.get(NESTED_BUILDER_CLASS_NAME);
         // Create the newBuilder(ClientContext) method.
         Function newBuilderFn =
             argExpr -> NewObjectExpr.builder().setType(builderReturnType).setArguments(argExpr).build();
    @@ -1136,7 +1274,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);
    @@ -1236,7 +1374,7 @@ private static List createNestedClassStatements(
         return statements;
       }
     
    -  private static List createNestedClassMethods(
    +  private List createNestedClassMethods(
           Service service,
           GapicServiceConfig serviceConfig,
           TypeNode superType,
    @@ -1247,7 +1385,7 @@ private static List createNestedClassMethods(
         nestedClassMethods.addAll(
             createNestedClassConstructorMethods(
                 service, serviceConfig, nestedMethodSettingsMemberVarExprs, typeStore));
    -    nestedClassMethods.add(createNestedClassCreateDefaultMethod(typeStore));
    +    nestedClassMethods.addAll(createNestedClassCreateDefaultMethods(typeStore));
         nestedClassMethods.add(createNestedClassInitDefaultsMethod(service, serviceConfig, typeStore));
         nestedClassMethods.add(createNestedClassApplyToAllUnaryMethodsMethod(superType, typeStore));
         nestedClassMethods.add(createNestedClassUnaryMethodSettingsBuilderGetterMethod());
    @@ -1258,7 +1396,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);
    @@ -1313,7 +1451,9 @@ private static MethodDefinition createNestedClassInitDefaultsMethod(
                       method,
                       builderVarExpr,
                       NESTED_RETRYABLE_CODE_DEFINITIONS_VAR_EXPR,
    -                  NESTED_RETRY_PARAM_DEFINITIONS_VAR_EXPR)));
    +                  NESTED_RETRY_PARAM_DEFINITIONS_VAR_EXPR,
    +                  getTransportContext().operationResponseTransformerType(),
    +                  getTransportContext().operationMetadataTransformerType())));
           bodyStatements.add(EMPTY_LINE_STATEMENT);
         }
     
    @@ -1583,7 +1723,22 @@ private static List createNestedClassConstructorMethods(
         return ctorMethods;
       }
     
    -  private static MethodDefinition createNestedClassCreateDefaultMethod(TypeStore typeStore) {
    +  protected List createNestedClassCreateDefaultMethods(TypeStore typeStore) {
    +    return Collections.singletonList(
    +        createNestedClassCreateDefaultMethod(
    +            typeStore,
    +            "createDefault",
    +            "defaultTransportChannelProvider",
    +            null,
    +            "defaultApiClientHeaderProviderBuilder"));
    +  }
    +
    +  protected MethodDefinition createNestedClassCreateDefaultMethod(
    +      TypeStore typeStore,
    +      String methodName,
    +      String defaultTransportChannelProvider,
    +      String defaultTransportChannelProviderBuilder,
    +      String defaultApiClientHeaderProviderBuilder) {
         List bodyStatements = new ArrayList<>();
     
         // Initialize the builder: Builder builder = new Builder((ClientContext) null);
    @@ -1608,15 +1763,32 @@ private static MethodDefinition createNestedClassCreateDefaultMethod(TypeStore t
         bodyStatements.add(EMPTY_LINE_STATEMENT);
     
         List bodyExprs = new ArrayList<>();
    -    bodyExprs.add(
    -        MethodInvocationExpr.builder()
    -            .setExprReferenceExpr(builderVarExpr)
    -            .setMethodName("setTransportChannelProvider")
    -            .setArguments(
    -                MethodInvocationExpr.builder()
    -                    .setMethodName("defaultTransportChannelProvider")
    -                    .build())
    -            .build());
    +
    +    if (defaultTransportChannelProvider != null) {
    +      bodyExprs.add(
    +          MethodInvocationExpr.builder()
    +              .setExprReferenceExpr(builderVarExpr)
    +              .setMethodName("setTransportChannelProvider")
    +              .setArguments(
    +                  MethodInvocationExpr.builder()
    +                      .setMethodName(defaultTransportChannelProvider)
    +                      .build())
    +              .build());
    +    } else {
    +      bodyExprs.add(
    +          MethodInvocationExpr.builder()
    +              .setExprReferenceExpr(builderVarExpr)
    +              .setMethodName("setTransportChannelProvider")
    +              .setArguments(
    +                  MethodInvocationExpr.builder()
    +                      .setExprReferenceExpr(
    +                          MethodInvocationExpr.builder()
    +                              .setMethodName(defaultTransportChannelProviderBuilder)
    +                              .build())
    +                      .setMethodName("build")
    +                      .build())
    +              .build());
    +    }
     
         bodyExprs.add(
             MethodInvocationExpr.builder()
    @@ -1640,7 +1812,7 @@ private static MethodDefinition createNestedClassCreateDefaultMethod(TypeStore t
                     MethodInvocationExpr.builder()
                         .setExprReferenceExpr(
                             MethodInvocationExpr.builder()
    -                            .setMethodName("defaultApiClientHeaderProviderBuilder")
    +                            .setMethodName(defaultApiClientHeaderProviderBuilder)
                                 .build())
                         .setMethodName("build")
                         .build())
    @@ -1683,7 +1855,7 @@ private static MethodDefinition createNestedClassCreateDefaultMethod(TypeStore t
             .setScope(ScopeNode.PRIVATE)
             .setIsStatic(true)
             .setReturnType(builderType)
    -        .setName("createDefault")
    +        .setName(methodName)
             .setBody(bodyStatements)
             .setReturnExpr(returnExpr)
             .build();
    @@ -1867,10 +2039,12 @@ private TypeStore createDynamicTypes(Service service, String pakkage) {
             pakkage,
             Arrays.asList(
                 thisClassName,
    -            getTransportContext().classNames().getTransportServiceStubClassName(service),
                 ClassNames.getServiceStubSettingsClassName(service),
                 ClassNames.getServiceStubClassName(service)));
     
    +    typeStore.putAll(
    +        pakkage, getTransportContext().classNames().getTransportServiceStubClassNames(service));
    +
         // Nested builder class.
         typeStore.put(pakkage, NESTED_BUILDER_CLASS_NAME, true, thisClassName);
     
    diff --git a/src/main/java/com/google/api/generator/gapic/composer/common/AbstractTransportServiceStubClassComposer.java b/src/main/java/com/google/api/generator/gapic/composer/common/AbstractTransportServiceStubClassComposer.java
    new file mode 100644
    index 0000000000..3aa79a452f
    --- /dev/null
    +++ b/src/main/java/com/google/api/generator/gapic/composer/common/AbstractTransportServiceStubClassComposer.java
    @@ -0,0 +1,1077 @@
    +// Copyright 2020 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.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.rpc.BidiStreamingCallable;
    +import com.google.api.gax.rpc.ClientContext;
    +import com.google.api.gax.rpc.ClientStreamingCallable;
    +import com.google.api.gax.rpc.LongRunningClient;
    +import com.google.api.gax.rpc.OperationCallable;
    +import com.google.api.gax.rpc.RequestParamsExtractor;
    +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.AssignmentExpr;
    +import com.google.api.generator.engine.ast.ClassDefinition;
    +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.Expr;
    +import com.google.api.generator.engine.ast.ExprStatement;
    +import com.google.api.generator.engine.ast.JavaDocComment;
    +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.ReferenceConstructorExpr;
    +import com.google.api.generator.engine.ast.ScopeNode;
    +import com.google.api.generator.engine.ast.Statement;
    +import com.google.api.generator.engine.ast.ThisObjectValue;
    +import com.google.api.generator.engine.ast.ThrowExpr;
    +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.VaporReference;
    +import com.google.api.generator.engine.ast.Variable;
    +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.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.Message;
    +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 com.google.common.collect.ImmutableMap;
    +import com.google.longrunning.Operation;
    +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.concurrent.TimeUnit;
    +import java.util.function.BiFunction;
    +import java.util.function.Function;
    +import java.util.stream.Collectors;
    +import javax.annotation.Generated;
    +
    +public abstract class AbstractTransportServiceStubClassComposer implements ClassComposer {
    +  private static final Statement EMPTY_LINE_STATEMENT = EmptyLineStatement.create();
    +
    +  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 BACKGROUND_RESOURCES_MEMBER_NAME = "backgroundResources";
    +  private static final String CALLABLE_NAME = "Callable";
    +  private static final String CALLABLE_FACTORY_MEMBER_NAME = "callableFactory";
    +  private static final String CALLABLE_CLASS_MEMBER_PATTERN = "%sCallable";
    +  private static final String OPERATION_CALLABLE_CLASS_MEMBER_PATTERN = "%sOperationCallable";
    +  private static final String OPERATION_CALLABLE_NAME = "OperationCallable";
    +  // private static final String OPERATIONS_STUB_MEMBER_NAME = "operationsStub";
    +  private static final String PAGED_CALLABLE_NAME = "PagedCallable";
    +
    +  protected static final TypeStore FIXED_TYPESTORE = createStaticTypes();
    +
    +  private final TransportContext transportContext;
    +
    +  protected AbstractTransportServiceStubClassComposer(TransportContext transportContext) {
    +    this.transportContext = transportContext;
    +  }
    +
    +  public TransportContext getTransportContext() {
    +    return transportContext;
    +  }
    +
    +  private static TypeStore createStaticTypes() {
    +    List concreteClazzes =
    +        Arrays.asList(
    +            BackgroundResource.class,
    +            BackgroundResourceAggregation.class,
    +            BetaApi.class,
    +            BidiStreamingCallable.class,
    +            ClientContext.class,
    +            ClientStreamingCallable.class,
    +            Generated.class,
    +            ImmutableMap.class,
    +            InterruptedException.class,
    +            IOException.class,
    +            Operation.class,
    +            OperationCallable.class,
    +            RequestParamsExtractor.class,
    +            ServerStreamingCallable.class,
    +            TimeUnit.class,
    +            UnaryCallable.class);
    +    return new TypeStore(concreteClazzes);
    +  }
    +
    +  @Override
    +  public GapicClass generate(GapicContext context, Service service) {
    +    String pakkage = service.pakkage() + ".stub";
    +    TypeStore typeStore = createDynamicTypes(service, pakkage);
    +    String className = getTransportContext().classNames().getTransportServiceStubClassName(service);
    +    GapicClass.Kind kind = Kind.STUB;
    +
    +    Map protoMethodNameToDescriptorVarExprs =
    +        createProtoMethodNameToDescriptorClassMembers(
    +            service, getTransportContext().methodDescriptorClass());
    +
    +    Map callableClassMemberVarExprs =
    +        createCallableClassMembers(service, typeStore);
    +
    +    Map classMemberVarExprs = new LinkedHashMap<>();
    +    classMemberVarExprs.put(
    +        BACKGROUND_RESOURCES_MEMBER_NAME,
    +        VariableExpr.withVariable(
    +            Variable.builder()
    +                .setName(BACKGROUND_RESOURCES_MEMBER_NAME)
    +                .setType(FIXED_TYPESTORE.get("BackgroundResource"))
    +                .build()));
    +    if (generateOperationsStubLogic(service)) {
    +      // Transport-specific service stub may have only one element of the following, thus get(0).
    +      TypeNode opeationsStubType = getTransportOperationsStubType(service);
    +      classMemberVarExprs.put(
    +          getTransportContext().transportOperationsStubNames().get(0),
    +          VariableExpr.withVariable(
    +              Variable.builder()
    +                  .setName(getTransportContext().transportOperationsStubNames().get(0))
    +                  .setType(opeationsStubType)
    +                  .build()));
    +    }
    +
    +    boolean operationPollingMethod = checkOperationPollingMethod(service);
    +    if(operationPollingMethod) {
    +      VariableExpr longRunningVarExpr = declareLongRunningClient();
    +      if (longRunningVarExpr != null) {
    +        classMemberVarExprs.put("longRunningClient", longRunningVarExpr);
    +      }
    +    }
    +
    +    classMemberVarExprs.put(
    +        CALLABLE_FACTORY_MEMBER_NAME,
    +        VariableExpr.withVariable(
    +            Variable.builder()
    +                .setName(CALLABLE_FACTORY_MEMBER_NAME)
    +                .setType(getTransportContext().stubCallableFactoryType())
    +                .build()));
    +
    +    Map messageTypes = context.messages();
    +    List classStatements =
    +        createClassStatements(
    +            service,
    +            protoMethodNameToDescriptorVarExprs,
    +            callableClassMemberVarExprs,
    +            classMemberVarExprs,
    +            messageTypes);
    +
    +    StubCommentComposer commentComposer =
    +        new StubCommentComposer(getTransportContext().transportName());
    +
    +    ClassDefinition classDef =
    +        ClassDefinition.builder()
    +            .setPackageString(pakkage)
    +            .setHeaderCommentStatements(
    +                commentComposer.createTransportServiceStubClassHeaderComments(
    +                    service.name(), service.isDeprecated()))
    +            .setAnnotations(createClassAnnotations(service))
    +            .setScope(ScopeNode.PUBLIC)
    +            .setName(className)
    +            .setExtendsType(
    +                typeStore.get(getTransportContext().classNames().getServiceStubClassName(service)))
    +            .setStatements(classStatements)
    +            .setMethods(
    +                createClassMethods(
    +                    service,
    +                    typeStore,
    +                    classMemberVarExprs,
    +                    callableClassMemberVarExprs,
    +                    protoMethodNameToDescriptorVarExprs))
    +            .build();
    +    return GapicClass.create(kind, classDef);
    +  }
    +
    +  protected abstract Statement createMethodDescriptorVariableDecl(
    +      Service service, Method protoMethod, VariableExpr methodDescriptorVarExpr, Map messageTypes);
    +
    +  protected boolean generateOperationsStubLogic(Service service) {
    +    return true;
    +  }
    +
    +  protected List createOperationsStubGetterMethod(
    +      Service service, VariableExpr operationsStubVarExpr) {
    +    if (!generateOperationsStubLogic(service)) {
    +      return Collections.emptyList();
    +    }
    +
    +    String methodName =
    +        String.format(
    +            "get%s",
    +            JavaStyle.toUpperCamelCase(getTransportContext().transportOperationsStubNames().get(0)));
    +
    +    return Arrays.asList(
    +        MethodDefinition.builder()
    +            .setScope(ScopeNode.PUBLIC)
    +            .setReturnType(operationsStubVarExpr.type())
    +            .setName(methodName)
    +            .setReturnExpr(operationsStubVarExpr)
    +            .build());
    +  }
    +
    +  protected abstract Expr createTransportSettingsInitExpr(
    +      Method method, VariableExpr transportSettingsVarExpr, VariableExpr methodDescriptorVarExpr);
    +
    +  protected List createGetMethodDescriptorsMethod(
    +      Service service,
    +      TypeStore typeStore,
    +      Map protoMethodNameToDescriptorVarExprs) {
    +    return Arrays.asList();
    +  }
    +
    +  protected List createClassStatements(
    +      Service service,
    +      Map protoMethodNameToDescriptorVarExprs,
    +      Map callableClassMemberVarExprs,
    +      Map classMemberVarExprs,
    +      Map messageTypes) {
    +    List classStatements = new ArrayList<>();
    +    for (Statement statement :
    +        createMethodDescriptorVariableDecls(service, protoMethodNameToDescriptorVarExprs, messageTypes)) {
    +      classStatements.add(statement);
    +      classStatements.add(EMPTY_LINE_STATEMENT);
    +    }
    +
    +    classStatements.addAll(createClassMemberFieldDeclarations(callableClassMemberVarExprs));
    +    classStatements.add(EMPTY_LINE_STATEMENT);
    +
    +    classStatements.addAll(createClassMemberFieldDeclarations(classMemberVarExprs));
    +    return classStatements;
    +  }
    +
    +  protected List createMethodDescriptorVariableDecls(
    +      Service service, Map protoMethodNameToDescriptorVarExprs, Map messageTypes) {
    +    return service.methods().stream()
    +        .map(
    +            m ->
    +                createMethodDescriptorVariableDecl(
    +                    service, m, protoMethodNameToDescriptorVarExprs.get(m.name()), messageTypes))
    +        .collect(Collectors.toList());
    +  }
    +
    +  private static List createClassMemberFieldDeclarations(
    +      Map fieldNameToVarExprs) {
    +    return fieldNameToVarExprs.values().stream()
    +        .map(
    +            v ->
    +                ExprStatement.withExpr(
    +                    v.toBuilder()
    +                        .setIsDecl(true)
    +                        .setScope(ScopeNode.PRIVATE)
    +                        .setIsFinal(true)
    +                        .build()))
    +        .collect(Collectors.toList());
    +  }
    +
    +  protected Map createProtoMethodNameToDescriptorClassMembers(
    +      Service service, Class descriptorClass) {
    +    return service.methods().stream()
    +        .collect(
    +            Collectors.toMap(
    +                Method::name,
    +                m ->
    +                    VariableExpr.withVariable(
    +                        Variable.builder()
    +                            .setName(
    +                                String.format(
    +                                    METHOD_DESCRIPTOR_NAME_PATTERN,
    +                                    JavaStyle.toLowerCamelCase(m.name())))
    +                            .setType(
    +                                TypeNode.withReference(
    +                                    ConcreteReference.builder()
    +                                        .setClazz(descriptorClass)
    +                                        .setGenerics(
    +                                            Arrays.asList(
    +                                                m.inputType().reference(),
    +                                                m.outputType().reference()))
    +                                        .build()))
    +                            .build()),
    +                (u, v) -> {
    +                  throw new IllegalStateException();
    +                },
    +                LinkedHashMap::new));
    +  }
    +
    +  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.
    +    for (Method protoMethod : service.methods()) {
    +      String javaStyleProtoMethodName = JavaStyle.toLowerCamelCase(protoMethod.name());
    +      String callableName = String.format(CALLABLE_CLASS_MEMBER_PATTERN, javaStyleProtoMethodName);
    +      callableClassMembers.put(
    +          callableName,
    +          VariableExpr.withVariable(
    +              Variable.builder()
    +                  .setName(callableName)
    +                  .setType(getCallableType(protoMethod))
    +                  .build()));
    +      if (protoMethod.hasLro()) {
    +        callableName =
    +            String.format(OPERATION_CALLABLE_CLASS_MEMBER_PATTERN, javaStyleProtoMethodName);
    +        callableClassMembers.put(
    +            callableName,
    +            VariableExpr.withVariable(
    +                Variable.builder()
    +                    .setName(callableName)
    +                    .setType(
    +                        TypeNode.withReference(
    +                            ConcreteReference.builder()
    +                                .setClazz(OperationCallable.class)
    +                                .setGenerics(
    +                                    Arrays.asList(
    +                                        protoMethod.inputType().reference(),
    +                                        protoMethod.lro().responseType().reference(),
    +                                        protoMethod.lro().metadataType().reference()))
    +                                .build()))
    +                    .build()));
    +      }
    +      if (protoMethod.isPaged()) {
    +        callableName = String.format(PAGED_CALLABLE_CLASS_MEMBER_PATTERN, javaStyleProtoMethodName);
    +        callableClassMembers.put(
    +            callableName,
    +            VariableExpr.withVariable(
    +                Variable.builder()
    +                    .setName(callableName)
    +                    .setType(
    +                        TypeNode.withReference(
    +                            getCallableType(protoMethod)
    +                                .reference()
    +                                .copyAndSetGenerics(
    +                                    Arrays.asList(
    +                                        protoMethod.inputType().reference(),
    +                                        typeStore
    +                                            .get(
    +                                                String.format(
    +                                                    PAGED_RESPONSE_TYPE_NAME_PATTERN,
    +                                                    protoMethod.name()))
    +                                            .reference()))))
    +                    .build()));
    +      }
    +    }
    +    return callableClassMembers;
    +  }
    +
    +  protected List createClassAnnotations(Service service) {
    +    List annotations = new ArrayList<>();
    +    if (!PackageChecker.isGaApi(service.pakkage())) {
    +      annotations.add(AnnotationNode.withType(FIXED_TYPESTORE.get("BetaApi")));
    +    }
    +
    +    if (service.isDeprecated()) {
    +      annotations.add(AnnotationNode.withType(TypeNode.DEPRECATED));
    +    }
    +
    +    annotations.add(
    +        AnnotationNode.builder()
    +            .setType(FIXED_TYPESTORE.get("Generated"))
    +            .setDescription("by gapic-generator-java")
    +            .build());
    +    return annotations;
    +  }
    +
    +  protected List createClassMethods(
    +      Service service,
    +      TypeStore typeStore,
    +      Map classMemberVarExprs,
    +      Map callableClassMemberVarExprs,
    +      Map protoMethodNameToDescriptorVarExprs) {
    +    List javaMethods = new ArrayList<>();
    +    javaMethods.addAll(createStaticCreatorMethods(service, typeStore, "newBuilder"));
    +    javaMethods.addAll(
    +        createConstructorMethods(
    +            service,
    +            typeStore,
    +            classMemberVarExprs,
    +            callableClassMemberVarExprs,
    +            protoMethodNameToDescriptorVarExprs));
    +    javaMethods.addAll(
    +        createGetMethodDescriptorsMethod(service, typeStore, protoMethodNameToDescriptorVarExprs));
    +    javaMethods.addAll(
    +        createOperationsStubGetterMethod(
    +            service, classMemberVarExprs.get(getTransportContext().transportOperationsStubNames().get(0))));
    +    javaMethods.addAll(createCallableGetterMethods(callableClassMemberVarExprs));
    +    javaMethods.addAll(
    +        createStubOverrideMethods(classMemberVarExprs.get(BACKGROUND_RESOURCES_MEMBER_NAME), service));
    +    return javaMethods;
    +  }
    +
    +  protected List createStaticCreatorMethods(Service service, TypeStore typeStore, String newBuilderMethod) {
    +    TypeNode creatorMethodReturnType =
    +        typeStore.get(getTransportContext().classNames().getTransportServiceStubClassName(service));
    +    Function, MethodDefinition.Builder> creatorMethodStarterFn =
    +        argList ->
    +            MethodDefinition.builder()
    +                .setScope(ScopeNode.PUBLIC)
    +                .setIsStatic(true)
    +                .setIsFinal(true)
    +                .setReturnType(creatorMethodReturnType)
    +                .setName("create")
    +                .setArguments(
    +                    argList.stream()
    +                        .map(v -> v.toBuilder().setIsDecl(true).build())
    +                        .collect(Collectors.toList()))
    +                .setThrowsExceptions(
    +                    Arrays.asList(
    +                        TypeNode.withReference(ConcreteReference.withClazz(IOException.class))));
    +
    +    Function, Expr> instantiatorExprFn =
    +        argList ->
    +            NewObjectExpr.builder().setType(creatorMethodReturnType).setArguments(argList).build();
    +
    +    TypeNode stubSettingsType =
    +        typeStore.get(getTransportContext().classNames().getServiceStubSettingsClassName(service));
    +    VariableExpr settingsVarExpr =
    +        VariableExpr.withVariable(
    +            Variable.builder().setName("settings").setType(stubSettingsType).build());
    +
    +    TypeNode clientContextType = FIXED_TYPESTORE.get("ClientContext");
    +    VariableExpr clientContextVarExpr =
    +        VariableExpr.withVariable(
    +            Variable.builder().setName("clientContext").setType(clientContextType).build());
    +
    +    VariableExpr callableFactoryVarExpr =
    +        VariableExpr.withVariable(
    +            Variable.builder()
    +                .setName("callableFactory")
    +                .setType(getTransportContext().stubCallableFactoryType())
    +                .build());
    +
    +    MethodInvocationExpr clientContextCreateMethodExpr =
    +        MethodInvocationExpr.builder()
    +            .setMethodName("create")
    +            .setStaticReferenceType(clientContextType)
    +            .setArguments(Arrays.asList(settingsVarExpr))
    +            .build();
    +    MethodInvocationExpr settingsBuilderMethodExpr =
    +        MethodInvocationExpr.builder()
    +            .setMethodName(newBuilderMethod)
    +            .setStaticReferenceType(stubSettingsType)
    +            .build();
    +    settingsBuilderMethodExpr =
    +        MethodInvocationExpr.builder()
    +            .setMethodName("build")
    +            .setExprReferenceExpr(settingsBuilderMethodExpr)
    +            .build();
    +
    +    return Arrays.asList(
    +        creatorMethodStarterFn
    +            .apply(Arrays.asList(settingsVarExpr))
    +            .setReturnExpr(
    +                instantiatorExprFn.apply(
    +                    Arrays.asList(settingsVarExpr, clientContextCreateMethodExpr)))
    +            .build(),
    +        creatorMethodStarterFn
    +            .apply(Arrays.asList(clientContextVarExpr))
    +            .setReturnExpr(
    +                instantiatorExprFn.apply(
    +                    Arrays.asList(settingsBuilderMethodExpr, clientContextVarExpr)))
    +            .build(),
    +        creatorMethodStarterFn
    +            .apply(Arrays.asList(clientContextVarExpr, callableFactoryVarExpr))
    +            .setReturnExpr(
    +                instantiatorExprFn.apply(
    +                    Arrays.asList(
    +                        settingsBuilderMethodExpr, clientContextVarExpr, callableFactoryVarExpr)))
    +            .build());
    +  }
    +
    +  protected List createConstructorMethods(
    +      Service service,
    +      TypeStore typeStore,
    +      Map classMemberVarExprs,
    +      Map callableClassMemberVarExprs,
    +      Map protoMethodNameToDescriptorVarExprs) {
    +    TypeNode stubSettingsType =
    +        typeStore.get(getTransportContext().classNames().getServiceStubSettingsClassName(service));
    +    VariableExpr settingsVarExpr =
    +        VariableExpr.withVariable(
    +            Variable.builder().setName("settings").setType(stubSettingsType).build());
    +
    +    TypeNode clientContextType = FIXED_TYPESTORE.get("ClientContext");
    +    VariableExpr clientContextVarExpr =
    +        VariableExpr.withVariable(
    +            Variable.builder().setName("clientContext").setType(clientContextType).build());
    +
    +    VariableExpr callableFactoryVarExpr =
    +        VariableExpr.withVariable(
    +            Variable.builder()
    +                .setName("callableFactory")
    +                .setType(getTransportContext().stubCallableFactoryType())
    +                .build());
    +
    +    TypeNode thisClassType =
    +        typeStore.get(getTransportContext().classNames().getTransportServiceStubClassName(service));
    +    TypeNode ioExceptionType =
    +        TypeNode.withReference(ConcreteReference.withClazz(IOException.class));
    +
    +    BiFunction, List, MethodDefinition> ctorMakerFn =
    +        (args, body) ->
    +            MethodDefinition.constructorBuilder()
    +                .setScope(ScopeNode.PROTECTED)
    +                .setReturnType(thisClassType)
    +                .setHeaderCommentStatements(Arrays.asList(createProtectedCtorComment(service)))
    +                .setArguments(
    +                    args.stream()
    +                        .map(v -> v.toBuilder().setIsDecl(true).build())
    +                        .collect(Collectors.toList()))
    +                .setThrowsExceptions(Arrays.asList(ioExceptionType))
    +                .setBody(body)
    +                .build();
    +
    +    // First constructor method.
    +    MethodDefinition firstCtor =
    +        ctorMakerFn.apply(
    +            Arrays.asList(settingsVarExpr, clientContextVarExpr),
    +            Arrays.asList(
    +                ExprStatement.withExpr(
    +                    ReferenceConstructorExpr.thisBuilder()
    +                        .setType(thisClassType)
    +                        .setArguments(
    +                            settingsVarExpr,
    +                            clientContextVarExpr,
    +                            NewObjectExpr.builder()
    +                                .setType(
    +                                    typeStore.get(
    +                                        getTransportContext()
    +                                            .classNames()
    +                                            .getTransportServiceCallableFactoryClassName(service)))
    +                                .build())
    +                        .build())));
    +
    +    Expr thisExpr =
    +        ValueExpr.withValue(
    +            ThisObjectValue.withType(
    +                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()
    +                    .setExprReferenceExpr(thisExpr)
    +                    .build())
    +            .setValueExpr(callableFactoryVarExpr)
    +            .build());
    +    VariableExpr operationsStubClassVarExpr = classMemberVarExprs.get(getTransportContext().transportOperationsStubNames().get(0));
    +    //TODO: refactor this
    +    if (generateOperationsStubLogic(service)) {
    +      TypeNode opeationsStubType = getTransportOperationsStubType(service);
    +      secondCtorExprs.add(
    +          AssignmentExpr.builder()
    +              .setVariableExpr(
    +                  operationsStubClassVarExpr.toBuilder().setExprReferenceExpr(thisExpr).build())
    +              .setValueExpr(
    +                  MethodInvocationExpr.builder()
    +                      .setStaticReferenceType(opeationsStubType)
    +                      .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();
    +    secondCtorStatements.add(EMPTY_LINE_STATEMENT);
    +
    +    // Transport settings local variables.
    +    Map javaStyleMethodNameToTransportSettingsVarExprs =
    +        service.methods().stream()
    +            .collect(
    +                Collectors.toMap(
    +                    m -> JavaStyle.toLowerCamelCase(m.name()),
    +                    m ->
    +                        VariableExpr.withVariable(
    +                            Variable.builder()
    +                                .setName(
    +                                    String.format(
    +                                        "%sTransportSettings",
    +                                        JavaStyle.toLowerCamelCase(m.name())))
    +                                .setType(
    +                                    TypeNode.withReference(
    +                                        ConcreteReference.builder()
    +                                            .setClazz(getTransportContext().callSettingsClass())
    +                                            .setGenerics(
    +                                                Arrays.asList(
    +                                                    m.inputType().reference(),
    +                                                    m.outputType().reference()))
    +                                            .build()))
    +                                .build())));
    +
    +    secondCtorExprs.addAll(
    +        service.methods().stream()
    +            .map(
    +                m ->
    +                    createTransportSettingsInitExpr(
    +                        m,
    +                        javaStyleMethodNameToTransportSettingsVarExprs.get(
    +                            JavaStyle.toLowerCamelCase(m.name())),
    +                        protoMethodNameToDescriptorVarExprs.get(m.name())))
    +            .collect(Collectors.toList()));
    +    secondCtorStatements.addAll(
    +        secondCtorExprs.stream().map(e -> ExprStatement.withExpr(e)).collect(Collectors.toList()));
    +    secondCtorExprs.clear();
    +    secondCtorStatements.add(EMPTY_LINE_STATEMENT);
    +
    +    // Initialize Callable variables.
    +    secondCtorExprs.addAll(
    +        callableClassMemberVarExprs.entrySet().stream()
    +            .map(
    +                e ->
    +                    createCallableInitExpr(
    +                        e.getKey(),
    +                        e.getValue(),
    +                        callableFactoryVarExpr,
    +                        settingsVarExpr,
    +                        clientContextVarExpr,
    +                        operationsStubClassVarExpr,
    +                        thisExpr,
    +                        javaStyleMethodNameToTransportSettingsVarExprs))
    +            .collect(Collectors.toList()));
    +    secondCtorStatements.addAll(
    +        secondCtorExprs.stream().map(e -> ExprStatement.withExpr(e)).collect(Collectors.toList()));
    +    secondCtorExprs.clear();
    +    secondCtorStatements.add(EMPTY_LINE_STATEMENT);
    +
    +
    +    secondCtorStatements.addAll(createLongRunningClient(service, typeStore));
    +
    +    // Instantiate backgroundResources.
    +    MethodInvocationExpr getBackgroundResourcesMethodExpr =
    +        MethodInvocationExpr.builder()
    +            .setExprReferenceExpr(clientContextVarExpr)
    +            .setMethodName("getBackgroundResources")
    +            .build();
    +
    +    VariableExpr backgroundResourcesVarExpr = classMemberVarExprs.get("backgroundResources");
    +    secondCtorExprs.add(
    +        AssignmentExpr.builder()
    +            .setVariableExpr(
    +                backgroundResourcesVarExpr.toBuilder().setExprReferenceExpr(thisExpr).build())
    +            .setValueExpr(
    +                NewObjectExpr.builder()
    +                    .setType(FIXED_TYPESTORE.get("BackgroundResourceAggregation"))
    +                    .setArguments(Arrays.asList(getBackgroundResourcesMethodExpr))
    +                    .build())
    +            .build());
    +    secondCtorStatements.addAll(
    +        secondCtorExprs.stream().map(e -> ExprStatement.withExpr(e)).collect(Collectors.toList()));
    +    secondCtorExprs.clear();
    +
    +    // Second constructor method.
    +    MethodDefinition secondCtor =
    +        ctorMakerFn.apply(
    +            Arrays.asList(settingsVarExpr, clientContextVarExpr, callableFactoryVarExpr),
    +            secondCtorStatements);
    +
    +    return Arrays.asList(firstCtor, secondCtor);
    +  }
    +
    +  protected List createLongRunningClient(Service service, TypeStore typeStore) {
    +    return ImmutableList.of();
    +  }
    +
    +  protected VariableExpr declareLongRunningClient() {
    +    return null;
    +  }
    +
    +  private Expr createCallableInitExpr(
    +      String callableVarName,
    +      VariableExpr callableVarExpr,
    +      VariableExpr callableFactoryVarExpr,
    +      VariableExpr settingsVarExpr,
    +      VariableExpr clientContextVarExpr,
    +      VariableExpr operationsStubClassVarExpr,
    +      Expr thisExpr,
    +      Map javaStyleMethodNameToTransportSettingsVarExprs) {
    +    boolean isOperation = callableVarName.endsWith(OPERATION_CALLABLE_NAME);
    +    boolean isPaged = callableVarName.endsWith(PAGED_CALLABLE_NAME);
    +    int sublength = 0;
    +    if (isOperation) {
    +      sublength = OPERATION_CALLABLE_NAME.length();
    +    } else if (isPaged) {
    +      sublength = PAGED_CALLABLE_NAME.length();
    +    } else {
    +      sublength = CALLABLE_NAME.length();
    +    }
    +    String javaStyleMethodName = callableVarName.substring(0, callableVarName.length() - sublength);
    +    List creatorMethodArgVarExprs = null;
    +    Expr transportSettingsVarExpr =
    +        javaStyleMethodNameToTransportSettingsVarExprs.get(javaStyleMethodName);
    +    if (transportSettingsVarExpr == null && isOperation) {
    +      // Try again, in case the name dtection above was inaccurate.
    +      isOperation = false;
    +      sublength = CALLABLE_NAME.length();
    +      javaStyleMethodName = callableVarName.substring(0, callableVarName.length() - sublength);
    +      transportSettingsVarExpr =
    +          javaStyleMethodNameToTransportSettingsVarExprs.get(javaStyleMethodName);
    +    }
    +    Preconditions.checkNotNull(
    +        transportSettingsVarExpr,
    +        String.format(
    +            "No transport settings variable found for method name %s", javaStyleMethodName));
    +    if (isOperation) {
    +      creatorMethodArgVarExprs =
    +          Arrays.asList(
    +              transportSettingsVarExpr,
    +              MethodInvocationExpr.builder()
    +                  .setExprReferenceExpr(settingsVarExpr)
    +                  .setMethodName(String.format("%sOperationSettings", javaStyleMethodName))
    +                  .build(),
    +              clientContextVarExpr,
    +              operationsStubClassVarExpr);
    +    } else {
    +      creatorMethodArgVarExprs =
    +          Arrays.asList(
    +              transportSettingsVarExpr,
    +              MethodInvocationExpr.builder()
    +                  .setExprReferenceExpr(settingsVarExpr)
    +                  .setMethodName(String.format("%sSettings", javaStyleMethodName))
    +                  .build(),
    +              clientContextVarExpr);
    +    }
    +
    +    Optional callableCreatorMethodName =
    +        getCallableCreatorMethodName(callableVarExpr.type());
    +
    +    Expr initExpr;
    +    if (callableCreatorMethodName.isPresent()) {
    +      initExpr =
    +          MethodInvocationExpr.builder()
    +              .setExprReferenceExpr(callableFactoryVarExpr)
    +              .setMethodName(callableCreatorMethodName.get())
    +              .setArguments(creatorMethodArgVarExprs)
    +              .setReturnType(callableVarExpr.type())
    +              .build();
    +    } else {
    +      initExpr = ValueExpr.createNullExpr();
    +    }
    +
    +    return AssignmentExpr.builder()
    +        .setVariableExpr(callableVarExpr.toBuilder().setExprReferenceExpr(thisExpr).build())
    +        .setValueExpr(initExpr)
    +        .build();
    +  }
    +
    +  protected Optional getCallableCreatorMethodName(TypeNode callableVarExprType) {
    +    final String typeName = callableVarExprType.reference().name();
    +    String streamName = "Unary";
    +
    +    // Special handling for pagination methods.
    +    if (callableVarExprType.reference().generics().size() == 2
    +        && callableVarExprType.reference().generics().get(1).name().endsWith("PagedResponse")) {
    +      streamName = "Paged";
    +    } else {
    +      if (typeName.startsWith("Client")) {
    +        streamName = "ClientStreaming";
    +      } else if (typeName.startsWith("Server")) {
    +        streamName = "ServerStreaming";
    +      } else if (typeName.startsWith("Bidi")) {
    +        streamName = "BidiStreaming";
    +      } else if (typeName.startsWith("Operation")) {
    +        streamName = "Operation";
    +      }
    +    }
    +    return Optional.of(String.format("create%sCallable", streamName));
    +  }
    +
    +  private static List createCallableGetterMethods(
    +      Map callableClassMemberVarExprs) {
    +    return callableClassMemberVarExprs.entrySet().stream()
    +        .map(
    +            e ->
    +                MethodDefinition.builder()
    +                    .setIsOverride(true)
    +                    .setScope(ScopeNode.PUBLIC)
    +                    .setReturnType(e.getValue().type())
    +                    .setName(e.getKey())
    +                    .setReturnExpr(e.getValue())
    +                    .build())
    +        .collect(Collectors.toList());
    +  }
    +
    +  private List createStubOverrideMethods(
    +      VariableExpr backgroundResourcesVarExpr, Service service) {
    +    Function methodMakerStarterFn =
    +        methodName ->
    +            MethodDefinition.builder()
    +                .setIsOverride(true)
    +                .setScope(ScopeNode.PUBLIC)
    +                .setName(methodName);
    +
    +    Function voidMethodMakerFn =
    +        methodName ->
    +            methodMakerStarterFn
    +                .apply(methodName)
    +                .setReturnType(TypeNode.VOID)
    +                .setBody(
    +                    Arrays.asList(
    +                        ExprStatement.withExpr(
    +                            MethodInvocationExpr.builder()
    +                                .setExprReferenceExpr(backgroundResourcesVarExpr)
    +                                .setMethodName(methodName)
    +                                .build())))
    +                .build();
    +
    +    Function booleanMethodMakerFn =
    +        methodName ->
    +            methodMakerStarterFn
    +                .apply(methodName)
    +                .setReturnType(TypeNode.BOOLEAN)
    +                .setReturnExpr(
    +                    MethodInvocationExpr.builder()
    +                        .setExprReferenceExpr(backgroundResourcesVarExpr)
    +                        .setMethodName(methodName)
    +                        .setReturnType(TypeNode.BOOLEAN)
    +                        .build())
    +                .build();
    +
    +    // Generate the close() method:
    +    //   @Override
    +    //   public final void close() {
    +    //     try {
    +    //       backgroundResources.close();
    +    //     } catch (RuntimeException e) {
    +    //       throw e;
    +    //     } catch (Exception e) {
    +    //       throw new IllegalStateException("Failed to close resource", e);
    +    //     }
    +    //  }
    +
    +    VariableExpr catchRuntimeExceptionVarExpr =
    +        VariableExpr.builder()
    +            .setVariable(
    +                Variable.builder()
    +                    .setType(TypeNode.withExceptionClazz(RuntimeException.class))
    +                    .setName("e")
    +                    .build())
    +            .build();
    +    VariableExpr catchExceptionVarExpr =
    +        VariableExpr.builder()
    +            .setVariable(
    +                Variable.builder()
    +                    .setType(TypeNode.withExceptionClazz(Exception.class))
    +                    .setName("e")
    +                    .build())
    +            .build();
    +    List javaMethods = new ArrayList<>();
    +    if (service.operationPollingMethod() != null) {
    +      javaMethods.addAll(createLongRunningClientGetters());
    +    }
    +    javaMethods.add(
    +        methodMakerStarterFn
    +            .apply("close")
    +            .setIsFinal(true)
    +            .setReturnType(TypeNode.VOID)
    +            .setBody(
    +                Arrays.asList(
    +                    TryCatchStatement.builder()
    +                        .setTryBody(
    +                            Arrays.asList(
    +                                ExprStatement.withExpr(
    +                                    MethodInvocationExpr.builder()
    +                                        .setExprReferenceExpr(backgroundResourcesVarExpr)
    +                                        .setMethodName("close")
    +                                        .build())))
    +                        .addCatch(
    +                            catchRuntimeExceptionVarExpr.toBuilder().setIsDecl(true).build(),
    +                            Arrays.asList(
    +                                ExprStatement.withExpr(
    +                                    ThrowExpr.builder()
    +                                        .setThrowExpr(catchRuntimeExceptionVarExpr)
    +                                        .build())))
    +                        .addCatch(
    +                            catchExceptionVarExpr.toBuilder().setIsDecl(true).build(),
    +                            Arrays.asList(
    +                                ExprStatement.withExpr(
    +                                    ThrowExpr.builder()
    +                                        .setType(
    +                                            TypeNode.withExceptionClazz(
    +                                                IllegalStateException.class))
    +                                        .setMessageExpr(String.format("Failed to close resource"))
    +                                        .setCauseExpr(catchExceptionVarExpr)
    +                                        .build())))
    +                        .build()))
    +            .build());
    +    javaMethods.add(voidMethodMakerFn.apply("shutdown"));
    +    javaMethods.add(booleanMethodMakerFn.apply("isShutdown"));
    +    javaMethods.add(booleanMethodMakerFn.apply("isTerminated"));
    +    javaMethods.add(voidMethodMakerFn.apply("shutdownNow"));
    +
    +    List awaitTerminationArgs =
    +        Arrays.asList(
    +            VariableExpr.withVariable(
    +                Variable.builder().setName("duration").setType(TypeNode.LONG).build()),
    +            VariableExpr.withVariable(
    +                Variable.builder()
    +                    .setName("unit")
    +                    .setType(FIXED_TYPESTORE.get("TimeUnit"))
    +                    .build()));
    +    javaMethods.add(
    +        methodMakerStarterFn
    +            .apply("awaitTermination")
    +            .setReturnType(TypeNode.BOOLEAN)
    +            .setArguments(
    +                awaitTerminationArgs.stream()
    +                    .map(v -> v.toBuilder().setIsDecl(true).build())
    +                    .collect(Collectors.toList()))
    +            .setThrowsExceptions(Arrays.asList(FIXED_TYPESTORE.get("InterruptedException")))
    +            .setReturnExpr(
    +                MethodInvocationExpr.builder()
    +                    .setExprReferenceExpr(backgroundResourcesVarExpr)
    +                    .setMethodName("awaitTermination")
    +                    .setArguments(
    +                        awaitTerminationArgs.stream()
    +                            .map(v -> (Expr) v)
    +                            .collect(Collectors.toList()))
    +                    .setReturnType(TypeNode.BOOLEAN)
    +                    .build())
    +            .build());
    +    return javaMethods;
    +  }
    +
    +  private boolean checkOperationPollingMethod(Service service) {
    +    for(Method method : service.methods()) {
    +      if(method.isOperationPollingMethod()) {
    +        return true;
    +      }
    +    }
    +    return false;
    +  }
    +
    +  protected List createLongRunningClientGetters() {
    +    VariableExpr longRunningClient =
    +        VariableExpr.withVariable(
    +            Variable.builder()
    +                .setName("longRunningClient")
    +                .setType(
    +                    TypeNode.withReference(ConcreteReference.withClazz(LongRunningClient.class)))
    +                .build());
    +
    +    return ImmutableList.of(
    +        MethodDefinition.builder()
    +            .setName("longRunningClient")
    +            .setScope(ScopeNode.PUBLIC)
    +            .setIsOverride(true)
    +            .setReturnType(
    +                TypeNode.withReference(ConcreteReference.withClazz(LongRunningClient.class)))
    +            .setReturnExpr(longRunningClient)
    +            .build());
    +  }
    +
    +  private TypeStore createDynamicTypes(Service service, String stubPakkage) {
    +    TypeStore typeStore = new TypeStore();
    +    typeStore.putAll(
    +        stubPakkage,
    +        Arrays.asList(
    +            getTransportContext().classNames().getTransportServiceStubClassName(service),
    +            getTransportContext().classNames().getServiceStubSettingsClassName(service),
    +            getTransportContext().classNames().getServiceStubClassName(service),
    +            getTransportContext()
    +                .classNames()
    +                .getTransportServiceCallableFactoryClassName(service)));
    +    // Pagination types.
    +    typeStore.putAll(
    +        service.pakkage(),
    +        service.methods().stream()
    +            .filter(m -> m.isPaged())
    +            .map(m -> String.format(PAGED_RESPONSE_TYPE_NAME_PATTERN, m.name()))
    +            .collect(Collectors.toList()),
    +        true,
    +        getTransportContext().classNames().getServiceClientClassName(service));
    +    return typeStore;
    +  }
    +
    +  private static TypeNode getCallableType(Method protoMethod) {
    +    TypeNode callableType = FIXED_TYPESTORE.get("UnaryCallable");
    +    switch (protoMethod.stream()) {
    +      case CLIENT:
    +        callableType = FIXED_TYPESTORE.get("ClientStreamingCallable");
    +        break;
    +      case SERVER:
    +        callableType = FIXED_TYPESTORE.get("ServerStreamingCallable");
    +        break;
    +      case BIDI:
    +        callableType = FIXED_TYPESTORE.get("BidiStreamingCallable");
    +        break;
    +      case NONE:
    +        // Fall through
    +      default:
    +        // Fall through
    +    }
    +
    +    return TypeNode.withReference(
    +        callableType
    +            .reference()
    +            .copyAndSetGenerics(
    +                Arrays.asList(
    +                    protoMethod.inputType().reference(), protoMethod.outputType().reference())));
    +  }
    +
    +  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.",
    +                getTransportContext().classNames().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());
    +  }
    +
    +  protected TypeNode getTransportOperationsStubType(Service service) {
    +    TypeNode transportOpeationsStubType = service.operationServiceStubType();
    +    if (transportOpeationsStubType == null) {
    +      transportOpeationsStubType = getTransportContext().transportOperationsStubTypes().get(0);
    +    }
    +    else {
    +      transportOpeationsStubType = TypeNode.withReference(
    +          VaporReference.builder()
    +              .setName("HttpJson" + transportOpeationsStubType.reference().simpleName())
    +              .setPakkage(transportOpeationsStubType.reference().pakkage())
    +              .build());
    +    }
    +
    +    return transportOpeationsStubType;
    +  }
    +}
    \ No newline at end of file
    diff --git a/src/main/java/com/google/api/generator/gapic/composer/common/RetrySettingsComposer.java b/src/main/java/com/google/api/generator/gapic/composer/common/RetrySettingsComposer.java
    index 4a20961399..4497495d67 100644
    --- a/src/main/java/com/google/api/generator/gapic/composer/common/RetrySettingsComposer.java
    +++ b/src/main/java/com/google/api/generator/gapic/composer/common/RetrySettingsComposer.java
    @@ -248,7 +248,9 @@ public static Expr createLroSettingsBuilderExpr(
           Method method,
           VariableExpr builderVarExpr,
           VariableExpr retryableCodeDefsVarExpr,
    -      VariableExpr retryParamDefsVarExpr) {
    +      VariableExpr retryParamDefsVarExpr,
    +      TypeNode operationResponseTransformer,
    +      TypeNode operationMetadataTransformer) {
         Preconditions.checkState(
             method.hasLro(),
             String.format(
    @@ -325,10 +327,7 @@ public static Expr createLroSettingsBuilderExpr(
                 .setMethodName("setResponseTransformer")
                 .setArguments(
                     MethodInvocationExpr.builder()
    -                    .setStaticReferenceType(
    -                        TypeNode.withReference(
    -                            ConcreteReference.withClazz(
    -                                ProtoOperationTransformers.ResponseTransformer.class)))
    +                    .setStaticReferenceType(operationResponseTransformer)
                         .setMethodName("create")
                         .setArguments(classFieldRefFn.apply(method.lro().responseType()))
                         .build())
    @@ -339,10 +338,7 @@ public static Expr createLroSettingsBuilderExpr(
                 .setMethodName("setMetadataTransformer")
                 .setArguments(
                     MethodInvocationExpr.builder()
    -                    .setStaticReferenceType(
    -                        TypeNode.withReference(
    -                            ConcreteReference.withClazz(
    -                                ProtoOperationTransformers.MetadataTransformer.class)))
    +                    .setStaticReferenceType(operationMetadataTransformer)
                         .setMethodName("create")
                         .setArguments(classFieldRefFn.apply(method.lro().metadataType()))
                         .build())
    diff --git a/src/main/java/com/google/api/generator/gapic/composer/common/ServiceStubClassComposer.java b/src/main/java/com/google/api/generator/gapic/composer/common/ServiceStubClassComposer.java
    deleted file mode 100644
    index 1c8bed3ccb..0000000000
    --- a/src/main/java/com/google/api/generator/gapic/composer/common/ServiceStubClassComposer.java
    +++ /dev/null
    @@ -1,283 +0,0 @@
    -// Copyright 2020 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.common;
    -
    -import com.google.api.core.BetaApi;
    -import com.google.api.gax.core.BackgroundResource;
    -import com.google.api.gax.rpc.BidiStreamingCallable;
    -import com.google.api.gax.rpc.ClientStreamingCallable;
    -import com.google.api.gax.rpc.OperationCallable;
    -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.ClassDefinition;
    -import com.google.api.generator.engine.ast.ExprStatement;
    -import com.google.api.generator.engine.ast.MethodDefinition;
    -import com.google.api.generator.engine.ast.Reference;
    -import com.google.api.generator.engine.ast.ScopeNode;
    -import com.google.api.generator.engine.ast.Statement;
    -import com.google.api.generator.engine.ast.ThrowExpr;
    -import com.google.api.generator.engine.ast.TypeNode;
    -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.Message;
    -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.longrunning.Operation;
    -import java.util.ArrayList;
    -import java.util.Arrays;
    -import java.util.Collections;
    -import java.util.List;
    -import java.util.Map;
    -import java.util.stream.Collectors;
    -import javax.annotation.Generated;
    -
    -public class ServiceStubClassComposer implements ClassComposer {
    -  private static final ServiceStubClassComposer INSTANCE = new ServiceStubClassComposer();
    -  private static final String DOT = ".";
    -  private static final String PAGED_RESPONSE_TYPE_NAME_PATTERN = "%sPagedResponse";
    -
    -  private ServiceStubClassComposer() {}
    -
    -  public static ServiceStubClassComposer instance() {
    -    return INSTANCE;
    -  }
    -
    -  @Override
    -  public GapicClass generate(GapicContext context, Service service) {
    -    Map messageTypes = context.messages();
    -    TypeStore typeStore = createTypes(service, messageTypes);
    -    String className = ClassNames.getServiceStubClassName(service);
    -    GapicClass.Kind kind = Kind.STUB;
    -    String pakkage = String.format("%s.stub", service.pakkage());
    -
    -    ClassDefinition classDef =
    -        ClassDefinition.builder()
    -            .setPackageString(pakkage)
    -            .setHeaderCommentStatements(
    -                StubCommentComposer.createServiceStubClassHeaderComments(
    -                    service.name(), service.isDeprecated()))
    -            .setAnnotations(createClassAnnotations(service, typeStore))
    -            .setIsAbstract(true)
    -            .setImplementsTypes(createClassImplements(typeStore))
    -            .setName(className)
    -            .setMethods(createClassMethods(service, messageTypes, typeStore))
    -            .setScope(ScopeNode.PUBLIC)
    -            .build();
    -    return GapicClass.create(kind, classDef);
    -  }
    -
    -  private static List createClassAnnotations(Service service, TypeStore typeStore) {
    -    List annotations = new ArrayList<>();
    -    if (!PackageChecker.isGaApi(service.pakkage())) {
    -      annotations.add(AnnotationNode.withType(typeStore.get("BetaApi")));
    -    }
    -
    -    if (service.isDeprecated()) {
    -      annotations.add(AnnotationNode.withType(TypeNode.DEPRECATED));
    -    }
    -
    -    annotations.add(
    -        AnnotationNode.builder()
    -            .setType(typeStore.get("Generated"))
    -            .setDescription("by gapic-generator-java")
    -            .build());
    -    return annotations;
    -  }
    -
    -  private static List createClassImplements(TypeStore typeStore) {
    -    return Arrays.asList(typeStore.get("BackgroundResource"));
    -  }
    -
    -  private static List createClassMethods(
    -      Service service, Map messageTypes, TypeStore typeStore) {
    -    boolean hasLroClient = hasLroMethods(service);
    -    List methods = new ArrayList<>();
    -    if (hasLroClient) {
    -      TypeNode operationsStubType = service.operationServiceStubType();
    -      if (operationsStubType == null) {
    -        operationsStubType = typeStore.get("OperationsStub");
    -      }
    -      methods.add(createOperationsStubGetter(typeStore, operationsStubType));
    -    }
    -    methods.addAll(createCallableGetters(service, messageTypes, typeStore));
    -    methods.addAll(createBackgroundResourceMethodOverrides());
    -    return methods;
    -  }
    -
    -  private static List createCallableGetters(
    -      Service service, Map messageTypes, TypeStore typeStore) {
    -    // Use a traditional for-loop since the output cardinality is not necessarily 1:1 with that of
    -    // service.methods().
    -    List javaMethods = new ArrayList<>();
    -    for (Method method : service.methods()) {
    -      if (method.hasLro()) {
    -        javaMethods.add(createOperationCallableGetter(method, typeStore));
    -      }
    -      if (method.isPaged()) {
    -        javaMethods.add(createPagedCallableGetter(method, typeStore));
    -      }
    -      javaMethods.add(createCallableGetter(method, typeStore));
    -    }
    -    return javaMethods;
    -  }
    -
    -  private static MethodDefinition createOperationCallableGetter(
    -      Method method, TypeStore typeStore) {
    -    return createCallableGetterHelper(method, typeStore, true, false);
    -  }
    -
    -  private static MethodDefinition createPagedCallableGetter(Method method, TypeStore typeStore) {
    -    return createCallableGetterHelper(method, typeStore, false, true);
    -  }
    -
    -  private static MethodDefinition createCallableGetter(Method method, TypeStore typeStore) {
    -    return createCallableGetterHelper(method, typeStore, false, false);
    -  }
    -
    -  private static MethodDefinition createCallableGetterHelper(
    -      Method method, TypeStore typeStore, boolean isLroCallable, boolean isPaged) {
    -    TypeNode returnType;
    -    switch (method.stream()) {
    -      case CLIENT:
    -        returnType = typeStore.get("ClientStreamingCallable");
    -        break;
    -      case SERVER:
    -        returnType = typeStore.get("ServerStreamingCallable");
    -        break;
    -      case BIDI:
    -        returnType = typeStore.get("BidiStreamingCallable");
    -        break;
    -      case NONE:
    -        // Fall through.
    -      default:
    -        returnType = typeStore.get(isLroCallable ? "OperationCallable" : "UnaryCallable");
    -    }
    -
    -    String methodName =
    -        String.format(
    -            "%s%sCallable",
    -            JavaStyle.toLowerCamelCase(method.name()),
    -            (isLroCallable ? "Operation" : isPaged ? "Paged" : ""));
    -    List genericRefs = new ArrayList<>();
    -    genericRefs.add(method.inputType().reference());
    -    if (method.hasLro() && isLroCallable) {
    -      genericRefs.add(method.lro().responseType().reference());
    -      genericRefs.add(method.lro().metadataType().reference());
    -    } else if (isPaged) {
    -      genericRefs.add(
    -          typeStore
    -              .get(String.format(PAGED_RESPONSE_TYPE_NAME_PATTERN, method.name()))
    -              .reference());
    -    } else {
    -      genericRefs.add(method.outputType().reference());
    -    }
    -
    -    List annotations =
    -        method.isDeprecated()
    -            ? Arrays.asList(AnnotationNode.withType(TypeNode.DEPRECATED))
    -            : Collections.emptyList();
    -
    -    returnType = TypeNode.withReference(returnType.reference().copyAndSetGenerics(genericRefs));
    -
    -    return MethodDefinition.builder()
    -        .setAnnotations(annotations)
    -        .setScope(ScopeNode.PUBLIC)
    -        .setReturnType(returnType)
    -        .setName(methodName)
    -        .setBody(createThrowUOEBody(methodName, typeStore))
    -        .build();
    -  }
    -
    -  private static MethodDefinition createOperationsStubGetter(TypeStore typeStore, TypeNode operationsStubType) {
    -    String methodName = "getOperationsStub";
    -    return MethodDefinition.builder()
    -        .setScope(ScopeNode.PUBLIC)
    -        .setReturnType(operationsStubType)
    -        .setName(methodName)
    -        .setBody(createThrowUOEBody(methodName, typeStore))
    -        .build();
    -  }
    -
    -  private static List createBackgroundResourceMethodOverrides() {
    -    MethodDefinition closeMethod =
    -        MethodDefinition.builder()
    -            .setIsOverride(true)
    -            .setScope(ScopeNode.PUBLIC)
    -            .setIsAbstract(true)
    -            .setReturnType(TypeNode.VOID)
    -            .setName("close")
    -            .build();
    -    return Arrays.asList(closeMethod);
    -  }
    -
    -  private static boolean hasLroMethods(Service service) {
    -    for (Method method : service.methods()) {
    -      if (method.hasLro()) {
    -        return true;
    -      }
    -    }
    -    return false;
    -  }
    -
    -  private static TypeStore createTypes(Service service, Map messageTypes) {
    -    List concreteClazzes =
    -        Arrays.asList(
    -            BackgroundResource.class,
    -            BetaApi.class,
    -            BidiStreamingCallable.class,
    -            ClientStreamingCallable.class,
    -            Generated.class,
    -            Operation.class,
    -            OperationCallable.class,
    -            ServerStreamingCallable.class,
    -            UnaryCallable.class,
    -            UnsupportedOperationException.class);
    -    TypeStore typeStore = new TypeStore(concreteClazzes);
    -
    -    typeStore.put("com.google.longrunning.stub", "OperationsStub");
    -
    -    // Pagination types.
    -    typeStore.putAll(
    -        service.pakkage(),
    -        service.methods().stream()
    -            .filter(m -> m.isPaged())
    -            .map(m -> String.format(PAGED_RESPONSE_TYPE_NAME_PATTERN, m.name()))
    -            .collect(Collectors.toList()),
    -        true,
    -        ClassNames.getServiceClientClassName(service));
    -
    -    return typeStore;
    -  }
    -
    -  private static List createThrowUOEBody(String methodName, TypeStore typeStore) {
    -    return Arrays.asList(
    -        ExprStatement.withExpr(
    -            ThrowExpr.builder()
    -                .setType(typeStore.get("UnsupportedOperationException"))
    -                .setMessageExpr(String.format("Not implemented: %s()", methodName))
    -                .build()));
    -  }
    -
    -  private static String getClientClassName(Service service) {
    -    return String.format("%sClient", service.overriddenName());
    -  }
    -}
    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 4058fbafbf..507ff662ca 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 java.util.List;
     import javax.annotation.Nullable;
     
     @AutoValue
    @@ -29,36 +30,57 @@ public abstract class TransportContext {
       // For AbstractServiceStubClassComposer
       public abstract Transport transport();
     
    +  @Nullable
       public abstract String transportName();
     
    +  @Nullable
       public abstract Class callSettingsClass();
     
    +  @Nullable
       public abstract TypeNode stubCallableFactoryType();
     
    +  @Nullable
       public abstract Class methodDescriptorClass();
     
    -  @Nullable
    -  public abstract TypeNode transportOperationsStubType();
    +  public abstract List transportOperationsStubTypes();
    +
    +  public abstract List transportOperationsStubNames();
     
       // For AbstractServiceSettingsClassComposer
    -  public abstract Class instantiatingChannelProviderClass();
    +  public abstract List> instantiatingChannelProviderClasses();
     
    -  public abstract String defaultTransportProviderBuilderName();
    +  public abstract List> instantiatingChannelProviderBuilderClasses();
    +
    +  public abstract List defaultTransportProviderBuilderNames();
    +
    +  public abstract List transportApiClientHeaderProviderBuilderNames();
     
       // For AbstractServiceStubSettingsClassComposer
    -  public abstract TypeNode transportChannelType();
    +  public abstract List transportChannelTypes();
     
    -  public abstract String transportGetterName();
    +  public abstract List transportGetterNames();
     
       // For AbstractServiceCallableFactoryClassComposer
    +  @Nullable
       public abstract TypeNode transportCallSettingsType();
     
    +  @Nullable
       public abstract TypeNode transportCallableFactoryType();
     
    -  public abstract TypeNode operationsStubType();
    +  public abstract List operationsStubTypes();
     
    +  @Nullable
       public abstract String transportCallSettingsName();
     
    +  // For RetrySettingsComposer
    +  public abstract TypeNode operationResponseTransformerType();
    +
    +  public abstract TypeNode operationMetadataTransformerType();
    +
    +  public abstract List operationsClientTypes();
    +
    +  public abstract List operationsClientNames();
    +
       protected static TypeNode classToType(Class clazz) {
         return TypeNode.withReference(ConcreteReference.withClazz(clazz));
       }
    @@ -82,15 +104,21 @@ public abstract static class Builder {
     
         public abstract Builder setMethodDescriptorClass(Class methodDescriptorClass);
     
    -    public abstract Builder setInstantiatingChannelProviderClass(
    -        Class instantiatingChannelProviderClass);
    +    public abstract Builder setInstantiatingChannelProviderClasses(
    +        List> instantiatingChannelProviderClasses);
    +
    +    public abstract Builder setInstantiatingChannelProviderBuilderClasses(
    +        List> instantiatingChannelProviderBuilderClasses);
    +
    +    public abstract Builder setDefaultTransportProviderBuilderNames(
    +        List defaultTransportProviderBuilderNames);
     
    -    public abstract Builder setDefaultTransportProviderBuilderName(
    -        String defaultTransportProviderBuilderName);
    +    public abstract Builder setTransportApiClientHeaderProviderBuilderNames(
    +        List transportApiClientHeaderProviderBuilderNames);
     
    -    public abstract Builder setTransportChannelType(TypeNode transportChannelType);
    +    public abstract Builder setTransportChannelTypes(List transportChannelTypes);
     
    -    public abstract Builder setTransportGetterName(String transportGetterName);
    +    public abstract Builder setTransportGetterNames(List transportGetterNames);
     
         public abstract Builder setTransportCallSettingsType(TypeNode transportCallSettingsType);
     
    @@ -98,9 +126,19 @@ public abstract Builder setDefaultTransportProviderBuilderName(
     
         public abstract Builder setTransportCallSettingsName(String transportCallSettingsName);
     
    -    public abstract Builder setTransportOperationsStubType(TypeNode transportOperationsStubType);
    +    public abstract Builder setTransportOperationsStubTypes(List transportOperationsStubTypes);
    +
    +    public abstract Builder setTransportOperationsStubNames(List transportOperationsStubNames);
    +
    +    public abstract Builder setOperationsStubTypes(List operationsStubType);
    +
    +    public abstract Builder setOperationResponseTransformerType(TypeNode operationResponseTransformerType);
    +
    +    public abstract Builder setOperationMetadataTransformerType(TypeNode operationMetadataTransformerType);
    +
    +    public abstract Builder setOperationsClientTypes(List operationsClientTypes);
     
    -    public abstract Builder setOperationsStubType(TypeNode operationsStubType);
    +    public abstract Builder setOperationsClientNames(List operationsClientNames);
     
         public abstract TransportContext build();
       }
    diff --git a/src/main/java/com/google/api/generator/gapic/composer/defaultvalue/DefaultValueComposer.java b/src/main/java/com/google/api/generator/gapic/composer/defaultvalue/DefaultValueComposer.java
    index 75562d680c..5af2722fd7 100644
    --- a/src/main/java/com/google/api/generator/gapic/composer/defaultvalue/DefaultValueComposer.java
    +++ b/src/main/java/com/google/api/generator/gapic/composer/defaultvalue/DefaultValueComposer.java
    @@ -58,8 +58,11 @@ public class DefaultValueComposer {
           TypeNode.withReference(ConcreteReference.withClazz(ByteString.class));
     
       public static Expr createDefaultValue(
    -      MethodArgument methodArg, Map resourceNames) {
    -    if (methodArg.isResourceNameHelper()) {
    +      MethodArgument methodArg,
    +      Map resourceNames,
    +      boolean forceResourceNameInitializer) {
    +    if (methodArg.isResourceNameHelper()
    +        || (forceResourceNameInitializer && methodArg.field().hasResourceReference())) {
           Preconditions.checkState(
               methodArg.field().hasResourceReference(),
               String.format(
    @@ -72,10 +75,21 @@ public static Expr createDefaultValue(
               String.format(
                   "No resource name found for reference %s",
                   methodArg.field().resourceReference().resourceTypeString()));
    -      return createDefaultValue(
    -          resourceName,
    -          resourceNames.values().stream().collect(Collectors.toList()),
    -          methodArg.field().name());
    +      Expr defValue =
    +          createDefaultValue(
    +              resourceName,
    +              resourceNames.values().stream().collect(Collectors.toList()),
    +              methodArg.field().name());
    +
    +      if (!methodArg.isResourceNameHelper() && methodArg.field().hasResourceReference()) {
    +        defValue =
    +            MethodInvocationExpr.builder()
    +                .setExprReferenceExpr(defValue)
    +                .setMethodName("toString")
    +                .setReturnType(TypeNode.STRING)
    +                .build();
    +      }
    +      return defValue;
         }
     
         if (methodArg.type().equals(methodArg.field().type())) {
    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 9a291669e2..5f9b27963e 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,9 +19,12 @@
     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.gax.grpc.ProtoOperationTransformers;
     import com.google.api.generator.gapic.composer.common.TransportContext;
     import com.google.api.generator.gapic.composer.utils.ClassNames;
     import com.google.api.generator.gapic.model.Transport;
    +import com.google.common.collect.ImmutableList;
    +import com.google.longrunning.OperationsClient;
     import com.google.longrunning.stub.GrpcOperationsStub;
     import com.google.longrunning.stub.OperationsStub;
     import io.grpc.MethodDescriptor;
    @@ -36,18 +39,33 @@ public abstract class GrpcContext extends TransportContext {
               .setCallSettingsClass(GrpcCallSettings.class)
               .setStubCallableFactoryType(classToType(GrpcStubCallableFactory.class))
               .setMethodDescriptorClass(MethodDescriptor.class)
    -          .setTransportOperationsStubType(classToType(GrpcOperationsStub.class))
    +          .setTransportOperationsStubTypes(ImmutableList.of(classToType(GrpcOperationsStub.class)))
    +          .setTransportOperationsStubNames(ImmutableList.of("operationsStub"))
               // For grpc.ServiceSettingsClassComposer
    -          .setInstantiatingChannelProviderClass(InstantiatingGrpcChannelProvider.Builder.class)
    -          .setDefaultTransportProviderBuilderName("defaultGrpcTransportProviderBuilder")
    +          .setInstantiatingChannelProviderClasses(
    +              ImmutableList.of(InstantiatingGrpcChannelProvider.class))
    +          .setInstantiatingChannelProviderBuilderClasses(
    +              ImmutableList.of(InstantiatingGrpcChannelProvider.Builder.class))
    +          .setDefaultTransportProviderBuilderNames(
    +              ImmutableList.of("defaultGrpcTransportProviderBuilder"))
    +          .setTransportApiClientHeaderProviderBuilderNames(
    +              ImmutableList.of("defaultGrpcApiClientHeaderProviderBuilder"))
               // For grpc.ServiceStubSettingsClassComposer
    -          .setTransportChannelType(classToType(GrpcTransportChannel.class))
    -          .setTransportGetterName("getGrpcTransportName")
    +          .setTransportChannelTypes(ImmutableList.of(classToType(GrpcTransportChannel.class)))
    +          .setTransportGetterNames(ImmutableList.of("getGrpcTransportName"))
               // For grpc.GrpcServiceCallableFactoryClassComposer
               .setTransportCallSettingsType(classToType(GrpcCallSettings.class))
               .setTransportCallableFactoryType(classToType(GrpcCallableFactory.class))
    -          .setOperationsStubType(classToType(OperationsStub.class))
    +          .setOperationsStubTypes(ImmutableList.of(classToType(OperationsStub.class)))
               .setTransportCallSettingsName("grpcCallSettings")
    +          // For RetrySettingsComposer
    +          .setOperationResponseTransformerType(
    +              classToType(ProtoOperationTransformers.ResponseTransformer.class))
    +          .setOperationMetadataTransformerType(
    +              classToType(ProtoOperationTransformers.MetadataTransformer.class))
    +          // For ServiceClientClassComposer
    +          .setOperationsClientTypes(ImmutableList.of(classToType(OperationsClient.class)))
    +          .setOperationsClientNames(ImmutableList.of("operationsClient"))
               .build();
     
       public static TransportContext instance() {
    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 3fc25a95b2..f3ad194c51 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
    @@ -22,7 +22,6 @@
     import com.google.api.generator.engine.ast.Expr;
     import com.google.api.generator.engine.ast.ExprStatement;
     import com.google.api.generator.engine.ast.LambdaExpr;
    -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;
    @@ -31,7 +30,7 @@
     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.common.AbstractTransportServiceStubClassComposer;
     import com.google.api.generator.gapic.composer.store.TypeStore;
     import com.google.api.generator.gapic.model.HttpBindings.HttpBinding;
     import com.google.api.generator.gapic.model.Message;
    @@ -53,7 +52,7 @@
     import java.util.function.Function;
     import java.util.stream.Collectors;
     
    -public class GrpcServiceStubClassComposer extends AbstractServiceStubClassComposer {
    +public class GrpcServiceStubClassComposer extends AbstractTransportServiceStubClassComposer {
       private static final GrpcServiceStubClassComposer INSTANCE = new GrpcServiceStubClassComposer();
     
       // Legacy support for the original reroute_to_grpc_interface option in gapic.yaml. These two APIs
    @@ -193,18 +192,6 @@ protected EnumRefExpr getMethodDescriptorMethodTypeExpr(Method protoMethod) {
             .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) {
    diff --git a/src/main/java/com/google/api/generator/gapic/composer/grpc/ServiceClientClassComposer.java b/src/main/java/com/google/api/generator/gapic/composer/grpc/ServiceClientClassComposer.java
    new file mode 100644
    index 0000000000..9b95e9c280
    --- /dev/null
    +++ b/src/main/java/com/google/api/generator/gapic/composer/grpc/ServiceClientClassComposer.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
    + *
    + *     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.composer.grpc;
    +
    +import com.google.api.generator.gapic.composer.common.AbstractServiceClientClassComposer;
    +
    +public class ServiceClientClassComposer extends AbstractServiceClientClassComposer {
    +  private static final ServiceClientClassComposer INSTANCE = new ServiceClientClassComposer();
    +
    +  protected ServiceClientClassComposer() {
    +    super(GrpcContext.instance());
    +  }
    +
    +  public static ServiceClientClassComposer instance() {
    +    return INSTANCE;
    +  }
    +}
    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 15b05ee765..75bd4c0133 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
    @@ -143,7 +143,8 @@ protected MethodDefinition createStartStaticServerMethod(
           Service service,
           GapicContext context,
           Map classMemberVarExprs,
    -      TypeStore typeStore) {
    +      TypeStore typeStore,
    +      String newBuilderMethod) {
         VariableExpr serviceHelperVarExpr = classMemberVarExprs.get(SERVICE_HELPER_VAR_NAME);
         Function serviceToVarExprFn =
             s -> classMemberVarExprs.get(getMockServiceVarName(s));
    @@ -1055,6 +1056,12 @@ protected List createStreamingRpcExceptionTestStatements(
         return statements;
       }
     
    +  @Override
    +  protected Expr createDefaultValue(
    +      MethodArgument methodArg, Map resourceNames) {
    +    return DefaultValueComposer.createDefaultValue(methodArg, resourceNames, false);
    +  }
    +
       @Override
       protected List createRpcLroExceptionTestCatchBody(
           VariableExpr exceptionExpr, boolean isStreaming) {
    diff --git a/src/main/java/com/google/api/generator/gapic/composer/grpc/ServiceStubClassComposer.java b/src/main/java/com/google/api/generator/gapic/composer/grpc/ServiceStubClassComposer.java
    new file mode 100644
    index 0000000000..1e11c5087d
    --- /dev/null
    +++ b/src/main/java/com/google/api/generator/gapic/composer/grpc/ServiceStubClassComposer.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
    + *
    + *     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.composer.grpc;
    +
    +import com.google.api.generator.gapic.composer.common.AbstractServiceStubClassComposer;
    +
    +public class ServiceStubClassComposer extends AbstractServiceStubClassComposer {
    +  private static final ServiceStubClassComposer INSTANCE = new ServiceStubClassComposer();
    +
    +  protected ServiceStubClassComposer() {
    +    super(GrpcContext.instance());
    +  }
    +
    +  public static ServiceStubClassComposer 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 6d0b8e221d..a80feffcd5 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
    @@ -18,14 +18,12 @@
     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.Expr;
     import com.google.api.generator.engine.ast.MethodDefinition;
     import com.google.api.generator.engine.ast.MethodInvocationExpr;
     import com.google.api.generator.engine.ast.PrimitiveValue;
     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;
    @@ -33,9 +31,9 @@
     import com.google.api.generator.gapic.composer.comment.SettingsCommentComposer;
     import com.google.api.generator.gapic.composer.common.AbstractServiceStubSettingsClassComposer;
     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;
    +import java.util.Collections;
     import java.util.List;
     
     public class ServiceStubSettingsClassComposer extends AbstractServiceStubSettingsClassComposer {
    @@ -62,37 +60,17 @@ private static TypeStore createStaticTypes() {
       }
     
       @Override
    -  protected MethodDefinition createDefaultTransportTransportProviderBuilderMethod() {
    -    // Create the defaultGrpcTransportProviderBuilder method.
    -    TypeNode returnType =
    -        TypeNode.withReference(
    -            ConcreteReference.withClazz(InstantiatingGrpcChannelProvider.Builder.class));
    -    MethodInvocationExpr transportChannelProviderBuilderExpr =
    -        MethodInvocationExpr.builder()
    -            .setStaticReferenceType(
    -                FIXED_GRPC_TYPESTORE.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)
    +  protected Expr initializeTransportProviderBuilder(
    +      MethodInvocationExpr transportChannelProviderBuilderExpr, TypeNode returnType) {
    +    return 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)
    -        .setName("defaultGrpcTransportProviderBuilder")
    -        .setReturnExpr(transportChannelProviderBuilderExpr)
             .build();
       }
     
    @@ -138,69 +116,16 @@ protected MethodDefinition createDefaultCredentialsProviderBuilderMethod() {
       }
     
       @Override
    -  protected MethodDefinition createDefaultApiClientHeaderProviderBuilderMethod(
    +  protected List createApiClientHeaderProviderBuilderMethods(
           Service service, TypeStore typeStore) {
    -    // Create the defaultApiClientHeaderProviderBuilder method.
    -    TypeNode 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_GRPC_TYPESTORE.get(GaxGrpcProperties.class.getSimpleName()))
    -                    .setMethodName("getGrpcTokenName")
    -                    .build(),
    -                MethodInvocationExpr.builder()
    -                    .setStaticReferenceType(
    -                        FIXED_GRPC_TYPESTORE.get(GaxGrpcProperties.class.getSimpleName()))
    -                    .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();
    -    return MethodDefinition.builder()
    -        .setAnnotations(Arrays.asList(annotation))
    -        .setScope(ScopeNode.PUBLIC)
    -        .setIsStatic(true)
    -        .setReturnType(returnType)
    -        .setName("defaultApiClientHeaderProviderBuilder")
    -        .setReturnExpr(returnExpr)
    -        .build();
    +    return Collections.singletonList(
    +        createApiClientHeaderProviderBuilderMethod(
    +            service,
    +            typeStore,
    +            "defaultApiClientHeaderProviderBuilder",
    +            FIXED_GRPC_TYPESTORE.get(GaxGrpcProperties.class.getSimpleName()),
    +            "getGrpcTokenName",
    +            "getGrpcVersion"));
       }
     
       @Override
    diff --git a/src/main/java/com/google/api/generator/gapic/composer/grpcrest/BUILD.bazel b/src/main/java/com/google/api/generator/gapic/composer/grpcrest/BUILD.bazel
    new file mode 100644
    index 0000000000..ea77aab100
    --- /dev/null
    +++ b/src/main/java/com/google/api/generator/gapic/composer/grpcrest/BUILD.bazel
    @@ -0,0 +1,55 @@
    +load("@rules_java//java:defs.bzl", "java_library")
    +
    +package(default_visibility = ["//visibility:public"])
    +
    +filegroup(
    +    name = "grpcrest_files",
    +    srcs = glob(["*.java"]),
    +)
    +
    +java_library(
    +    name = "grpcrest",
    +    srcs = [
    +        ":grpcrest_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/rest",
    +        "//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_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/grpcrest/GrpcRestContext.java b/src/main/java/com/google/api/generator/gapic/composer/grpcrest/GrpcRestContext.java
    new file mode 100644
    index 0000000000..3f84bf3c97
    --- /dev/null
    +++ b/src/main/java/com/google/api/generator/gapic/composer/grpcrest/GrpcRestContext.java
    @@ -0,0 +1,95 @@
    +// 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.grpcrest;
    +
    +import com.google.api.gax.core.BackgroundResource;
    +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.httpjson.HttpJsonTransportChannel;
    +import com.google.api.gax.httpjson.InstantiatingHttpJsonChannelProvider;
    +import com.google.api.gax.httpjson.longrunning.stub.HttpJsonOperationsStub;
    +import com.google.api.generator.gapic.composer.common.TransportContext;
    +import com.google.api.generator.gapic.composer.utils.ClassNames;
    +import com.google.api.generator.gapic.model.Transport;
    +import com.google.common.collect.ImmutableList;
    +import com.google.longrunning.OperationsClient;
    +import com.google.longrunning.stub.GrpcOperationsStub;
    +import com.google.longrunning.stub.OperationsStub;
    +
    +public abstract class GrpcRestContext extends TransportContext {
    +  private static final TransportContext INSTANCE =
    +      GrpcRestContext.builder()
    +          .setClassNames(new ClassNames("Grpc", "HttpJson"))
    +          .setTransport(Transport.GRPC_REST)
    +          .setTransportName(null)
    +          // For grpcrest.GrpcServiceStubClassComposer
    +          .setCallSettingsClass(null)
    +          .setStubCallableFactoryType(null)
    +          .setMethodDescriptorClass(null)
    +          .setTransportOperationsStubTypes(
    +              ImmutableList.of(
    +                  classToType(GrpcOperationsStub.class), classToType(HttpJsonOperationsStub.class)))
    +          .setTransportOperationsStubNames(
    +              ImmutableList.of("operationsStub", "httpJsonOperationsStub"))
    +          // For grpcrest.ServiceSettingsClassComposer
    +          .setInstantiatingChannelProviderClasses(
    +              ImmutableList.of(
    +                  InstantiatingGrpcChannelProvider.class,
    +                  InstantiatingHttpJsonChannelProvider.class))
    +          .setInstantiatingChannelProviderBuilderClasses(
    +              ImmutableList.of(
    +                  InstantiatingGrpcChannelProvider.Builder.class,
    +                  InstantiatingHttpJsonChannelProvider.Builder.class))
    +          .setDefaultTransportProviderBuilderNames(
    +              ImmutableList.of(
    +                  "defaultGrpcTransportProviderBuilder", "defaultHttpJsonTransportProviderBuilder"))
    +          .setTransportApiClientHeaderProviderBuilderNames(
    +              ImmutableList.of(
    +                  "defaultGrpcApiClientHeaderProviderBuilder",
    +                  "defaultHttpJsonApiClientHeaderProviderBuilder"))
    +          // For grpcrest.ServiceStubSettingsClassComposer
    +          .setTransportChannelTypes(
    +              ImmutableList.of(
    +                  classToType(GrpcTransportChannel.class),
    +                  classToType(HttpJsonTransportChannel.class)))
    +          .setTransportGetterNames(
    +              ImmutableList.of("getGrpcTransportName", "getHttpJsonTransportName"))
    +          // For grpcrest.GrpcServiceCallableFactoryClassComposer
    +          .setTransportCallSettingsType(null)
    +          .setTransportCallableFactoryType(null)
    +          .setOperationsStubTypes(
    +              ImmutableList.of(
    +                  classToType(OperationsStub.class), classToType(BackgroundResource.class)))
    +          .setTransportCallSettingsName(null)
    +          // For RetrySettingsComposer
    +          // TODO: fix when LRO for REST RE FIXED
    +          .setOperationResponseTransformerType(
    +              classToType(ProtoOperationTransformers.ResponseTransformer.class))
    +          .setOperationMetadataTransformerType(
    +              classToType(ProtoOperationTransformers.MetadataTransformer.class))
    +          // For ServiceClientClassComposer
    +          .setOperationsClientTypes(
    +              ImmutableList.of(
    +                  classToType(OperationsClient.class),
    +                  classToType(com.google.api.gax.httpjson.longrunning.OperationsClient.class)))
    +          .setOperationsClientNames(
    +              ImmutableList.of("operationsClient", "httpJsonOperationsClient"))
    +          .build();
    +
    +  public static TransportContext instance() {
    +    return INSTANCE;
    +  }
    +}
    diff --git a/src/main/java/com/google/api/generator/gapic/composer/grpcrest/HttpJsonServiceClientTestClassComposer.java b/src/main/java/com/google/api/generator/gapic/composer/grpcrest/HttpJsonServiceClientTestClassComposer.java
    new file mode 100644
    index 0000000000..9f9bbafc05
    --- /dev/null
    +++ b/src/main/java/com/google/api/generator/gapic/composer/grpcrest/HttpJsonServiceClientTestClassComposer.java
    @@ -0,0 +1,57 @@
    +// 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.grpcrest;
    +
    +import com.google.api.generator.engine.ast.MethodDefinition;
    +import com.google.api.generator.engine.ast.VariableExpr;
    +import com.google.api.generator.gapic.composer.common.AbstractServiceClientTestClassComposer;
    +import com.google.api.generator.gapic.composer.rest.ServiceClientTestClassComposer;
    +import com.google.api.generator.gapic.composer.store.TypeStore;
    +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 java.util.Map;
    +
    +public class HttpJsonServiceClientTestClassComposer extends ServiceClientTestClassComposer {
    +  private static final HttpJsonServiceClientTestClassComposer INSTANCE =
    +      new HttpJsonServiceClientTestClassComposer();
    +
    +  protected HttpJsonServiceClientTestClassComposer() {
    +    super();
    +  }
    +
    +  public static AbstractServiceClientTestClassComposer instance() {
    +    return INSTANCE;
    +  }
    +
    +  @Override
    +  protected GapicClass generate(String className, GapicContext context, Service service) {
    +    return super.generate(
    +        getTransportContext().classNames().getServiceClientTestClassNames(service).get(0),
    +        context,
    +        service);
    +  }
    +
    +  @Override
    +  protected MethodDefinition createStartStaticServerMethod(
    +      Service service,
    +      GapicContext context,
    +      Map classMemberVarExprs,
    +      TypeStore typeStore,
    +      String newBuilderMethod) {
    +    return super.createStartStaticServerMethod(
    +        service, context, classMemberVarExprs, typeStore, "newHttpJsonBuilder");
    +  }
    +}
    diff --git a/src/main/java/com/google/api/generator/gapic/composer/grpcrest/HttpJsonServiceStubClassComposer.java b/src/main/java/com/google/api/generator/gapic/composer/grpcrest/HttpJsonServiceStubClassComposer.java
    new file mode 100644
    index 0000000000..7f99c81287
    --- /dev/null
    +++ b/src/main/java/com/google/api/generator/gapic/composer/grpcrest/HttpJsonServiceStubClassComposer.java
    @@ -0,0 +1,40 @@
    +// 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.grpcrest;
    +
    +import com.google.api.generator.engine.ast.MethodDefinition;
    +import com.google.api.generator.gapic.composer.store.TypeStore;
    +import com.google.api.generator.gapic.model.Service;
    +import java.util.List;
    +
    +public class HttpJsonServiceStubClassComposer
    +    extends com.google.api.generator.gapic.composer.rest.HttpJsonServiceStubClassComposer {
    +  private static final HttpJsonServiceStubClassComposer INSTANCE =
    +      new HttpJsonServiceStubClassComposer();
    +
    +  protected HttpJsonServiceStubClassComposer() {
    +    super();
    +  }
    +
    +  public static HttpJsonServiceStubClassComposer instance() {
    +    return INSTANCE;
    +  }
    +
    +  @Override
    +  protected List createStaticCreatorMethods(
    +      Service service, TypeStore typeStore, String newBuilderMethod) {
    +    return super.createStaticCreatorMethods(service, typeStore, "newHttpJsonBuilder");
    +  }
    +}
    diff --git a/src/main/java/com/google/api/generator/gapic/composer/grpcrest/ServiceClientClassComposer.java b/src/main/java/com/google/api/generator/gapic/composer/grpcrest/ServiceClientClassComposer.java
    new file mode 100644
    index 0000000000..7529b002cf
    --- /dev/null
    +++ b/src/main/java/com/google/api/generator/gapic/composer/grpcrest/ServiceClientClassComposer.java
    @@ -0,0 +1,29 @@
    +// 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.grpcrest;
    +
    +import com.google.api.generator.gapic.composer.common.AbstractServiceClientClassComposer;
    +
    +public class ServiceClientClassComposer extends AbstractServiceClientClassComposer {
    +  private static final ServiceClientClassComposer INSTANCE = new ServiceClientClassComposer();
    +
    +  protected ServiceClientClassComposer() {
    +    super(GrpcRestContext.instance());
    +  }
    +
    +  public static ServiceClientClassComposer instance() {
    +    return INSTANCE;
    +  }
    +}
    diff --git a/src/main/java/com/google/api/generator/gapic/composer/grpcrest/ServiceSettingsClassComposer.java b/src/main/java/com/google/api/generator/gapic/composer/grpcrest/ServiceSettingsClassComposer.java
    new file mode 100644
    index 0000000000..03ff5dc54a
    --- /dev/null
    +++ b/src/main/java/com/google/api/generator/gapic/composer/grpcrest/ServiceSettingsClassComposer.java
    @@ -0,0 +1,68 @@
    +// 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.grpcrest;
    +
    +import com.google.api.generator.engine.ast.MethodDefinition;
    +import com.google.api.generator.gapic.composer.common.AbstractServiceSettingsClassComposer;
    +import com.google.api.generator.gapic.composer.store.TypeStore;
    +import com.google.api.generator.gapic.model.Service;
    +import java.util.ArrayList;
    +import java.util.List;
    +
    +public class ServiceSettingsClassComposer extends AbstractServiceSettingsClassComposer {
    +  private static final ServiceSettingsClassComposer INSTANCE = new ServiceSettingsClassComposer();
    +
    +  protected ServiceSettingsClassComposer() {
    +    super(GrpcRestContext.instance());
    +  }
    +
    +  public static ServiceSettingsClassComposer instance() {
    +    return INSTANCE;
    +  }
    +
    +  @Override
    +  protected List createNestedBuilderCreatorMethods(
    +      Service service,
    +      TypeStore typeStore,
    +      String newBuilderMethodName,
    +      String createDefaultMethodName) {
    +    List methods = new ArrayList<>();
    +
    +    methods.addAll(
    +        super.createNestedBuilderCreatorMethods(service, typeStore, "newBuilder", "createDefault"));
    +    methods.addAll(
    +        super.createNestedBuilderCreatorMethods(
    +            service, typeStore, "newHttpJsonBuilder", "createHttpJsonDefault"));
    +
    +    return methods;
    +  }
    +
    +  @Override
    +  protected List createNewBuilderMethods(
    +      Service service,
    +      TypeStore typeStore,
    +      String newBuilderMethodName,
    +      String createDefaultMethodName) {
    +    List methods = new ArrayList<>();
    +
    +    methods.addAll(
    +        super.createNewBuilderMethods(service, typeStore, "newBuilder", "createDefault"));
    +    methods.addAll(
    +        super.createNewBuilderMethods(
    +            service, typeStore, "newHttpJsonBuilder", "createHttpJsonDefault"));
    +
    +    return methods;
    +  }
    +}
    diff --git a/src/main/java/com/google/api/generator/gapic/composer/grpcrest/ServiceStubClassComposer.java b/src/main/java/com/google/api/generator/gapic/composer/grpcrest/ServiceStubClassComposer.java
    new file mode 100644
    index 0000000000..6be0ef7ac2
    --- /dev/null
    +++ b/src/main/java/com/google/api/generator/gapic/composer/grpcrest/ServiceStubClassComposer.java
    @@ -0,0 +1,47 @@
    +/*
    + * 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.composer.grpcrest;
    +
    +import com.google.api.generator.engine.ast.MethodDefinition;
    +import com.google.api.generator.engine.ast.ReturnExpr;
    +import com.google.api.generator.engine.ast.ScopeNode;
    +import com.google.api.generator.engine.ast.TypeNode;
    +import com.google.api.generator.engine.ast.ValueExpr;
    +import com.google.api.generator.gapic.composer.common.AbstractServiceStubClassComposer;
    +import com.google.api.generator.gapic.composer.store.TypeStore;
    +
    +public class ServiceStubClassComposer extends AbstractServiceStubClassComposer {
    +  private static final ServiceStubClassComposer INSTANCE = new ServiceStubClassComposer();
    +
    +  protected ServiceStubClassComposer() {
    +    super(GrpcRestContext.instance());
    +  }
    +
    +  public static ServiceStubClassComposer instance() {
    +    return INSTANCE;
    +  }
    +
    +  @Override
    +  protected MethodDefinition createOperationsStubGetterMethodDefinition(
    +      TypeNode returnType, String methodName, TypeStore typeStore) {
    +    return MethodDefinition.builder()
    +        .setScope(ScopeNode.PUBLIC)
    +        .setReturnType(returnType)
    +        .setName(methodName)
    +        .setReturnExpr(ReturnExpr.withExpr(ValueExpr.createNullExpr()))
    +        .build();
    +  }
    +}
    diff --git a/src/main/java/com/google/api/generator/gapic/composer/grpcrest/ServiceStubSettingsClassComposer.java b/src/main/java/com/google/api/generator/gapic/composer/grpcrest/ServiceStubSettingsClassComposer.java
    new file mode 100644
    index 0000000000..6f65ced39c
    --- /dev/null
    +++ b/src/main/java/com/google/api/generator/gapic/composer/grpcrest/ServiceStubSettingsClassComposer.java
    @@ -0,0 +1,200 @@
    +// 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.grpcrest;
    +
    +import com.google.api.gax.core.GoogleCredentialsProvider;
    +import com.google.api.gax.grpc.GaxGrpcProperties;
    +import com.google.api.gax.httpjson.GaxHttpJsonProperties;
    +import com.google.api.gax.rpc.ApiClientHeaderProvider;
    +import com.google.api.generator.engine.ast.ConcreteReference;
    +import com.google.api.generator.engine.ast.Expr;
    +import com.google.api.generator.engine.ast.MethodDefinition;
    +import com.google.api.generator.engine.ast.MethodInvocationExpr;
    +import com.google.api.generator.engine.ast.PrimitiveValue;
    +import com.google.api.generator.engine.ast.ScopeNode;
    +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.comment.SettingsCommentComposer;
    +import com.google.api.generator.gapic.composer.common.AbstractServiceStubSettingsClassComposer;
    +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 com.google.common.collect.ImmutableList;
    +import java.util.ArrayList;
    +import java.util.List;
    +
    +public class ServiceStubSettingsClassComposer extends AbstractServiceStubSettingsClassComposer {
    +  private static final ServiceStubSettingsClassComposer INSTANCE =
    +      new ServiceStubSettingsClassComposer();
    +
    +  public static ServiceStubSettingsClassComposer instance() {
    +    return INSTANCE;
    +  }
    +
    +  protected ServiceStubSettingsClassComposer() {
    +    super(GrpcRestContext.instance());
    +  }
    +
    +  @Override
    +  protected Expr initializeTransportProviderBuilder(
    +      MethodInvocationExpr transportChannelProviderBuilderExpr, TypeNode returnType) {
    +    if (!returnType.reference().isFromPackage("com.google.api.gax.grpc")) {
    +      return transportChannelProviderBuilderExpr;
    +    }
    +
    +    return 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();
    +  }
    +
    +  @Override
    +  protected MethodDefinition createDefaultCredentialsProviderBuilderMethod() {
    +    TypeNode returnType =
    +        TypeNode.withReference(
    +            ConcreteReference.withClazz(GoogleCredentialsProvider.Builder.class));
    +    MethodInvocationExpr credsProviderBuilderExpr =
    +        MethodInvocationExpr.builder()
    +            .setStaticReferenceType(FIXED_TYPESTORE.get("GoogleCredentialsProvider"))
    +            .setMethodName("newBuilder")
    +            .build();
    +    credsProviderBuilderExpr =
    +        MethodInvocationExpr.builder()
    +            .setExprReferenceExpr(credsProviderBuilderExpr)
    +            .setMethodName("setScopesToApply")
    +            .setArguments(DEFAULT_SERVICE_SCOPES_VAR_EXPR)
    +            .setReturnType(returnType)
    +            .build();
    +
    +    // This section is specific to GAPIC clients. It sets UseJwtAccessWithScope value to true to
    +    // enable self signed JWT feature.
    +    credsProviderBuilderExpr =
    +        MethodInvocationExpr.builder()
    +            .setExprReferenceExpr(credsProviderBuilderExpr)
    +            .setMethodName("setUseJwtAccessWithScope")
    +            .setArguments(
    +                ValueExpr.withValue(
    +                    PrimitiveValue.builder().setType(TypeNode.BOOLEAN).setValue("true").build()))
    +            .setReturnType(returnType)
    +            .build();
    +
    +    return MethodDefinition.builder()
    +        .setHeaderCommentStatements(
    +            SettingsCommentComposer.DEFAULT_CREDENTIALS_PROVIDER_BUILDER_METHOD_COMMENT)
    +        .setScope(ScopeNode.PUBLIC)
    +        .setIsStatic(true)
    +        .setReturnType(returnType)
    +        .setName("defaultCredentialsProviderBuilder")
    +        .setReturnExpr(credsProviderBuilderExpr)
    +        .build();
    +  }
    +
    +  @Override
    +  protected List createApiClientHeaderProviderBuilderMethods(
    +      Service service, TypeStore typeStore) {
    +
    +    TypeNode returnType =
    +        TypeNode.withReference(ConcreteReference.withClazz(ApiClientHeaderProvider.Builder.class));
    +
    +    return ImmutableList.of(
    +        createApiClientHeaderProviderBuilderMethod(
    +            service,
    +            typeStore,
    +            "defaultGrpcApiClientHeaderProviderBuilder",
    +            TypeNode.withReference(ConcreteReference.withClazz(GaxGrpcProperties.class)),
    +            "getGrpcTokenName",
    +            "getGrpcVersion"),
    +        createApiClientHeaderProviderBuilderMethod(
    +            service,
    +            typeStore,
    +            "defaultHttpJsonApiClientHeaderProviderBuilder",
    +            TypeNode.withReference(ConcreteReference.withClazz(GaxHttpJsonProperties.class)),
    +            "getHttpJsonTokenName",
    +            "getHttpJsonVersion"),
    +        MethodDefinition.builder()
    +            .setScope(ScopeNode.PUBLIC)
    +            .setIsStatic(true)
    +            .setReturnType(returnType)
    +            .setName("defaultApiClientHeaderProviderBuilder")
    +            .setReturnExpr(
    +                MethodInvocationExpr.builder()
    +                    .setStaticReferenceType(
    +                        typeStore.get(ClassNames.getServiceStubSettingsClassName(service)))
    +                    .setMethodName("defaultGrpcApiClientHeaderProviderBuilder")
    +                    .setReturnType(returnType)
    +                    .build())
    +            .build());
    +  }
    +
    +  @Override
    +  public MethodDefinition createDefaultTransportChannelProviderMethod() {
    +    TypeNode returnType = FIXED_TYPESTORE.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();
    +  }
    +
    +  @Override
    +  protected List createNestedClassCreateDefaultMethods(TypeStore typeStore) {
    +    return ImmutableList.of(
    +        createNestedClassCreateDefaultMethod(
    +            typeStore,
    +            "createDefault",
    +            "defaultTransportChannelProvider",
    +            null,
    +            "defaultApiClientHeaderProviderBuilder"),
    +        createNestedClassCreateDefaultMethod(
    +            typeStore,
    +            "createHttpJsonDefault",
    +            null,
    +            "defaultHttpJsonTransportProviderBuilder",
    +            "defaultHttpJsonApiClientHeaderProviderBuilder"));
    +  }
    +
    +  @Override
    +  protected List createNewBuilderMethods(
    +      Service service,
    +      TypeStore typeStore,
    +      String newBuilderMethodName,
    +      String createDefaultMethodName) {
    +    List methods = new ArrayList<>();
    +    methods.addAll(
    +        super.createNewBuilderMethods(service, typeStore, "newBuilder", "createDefault"));
    +    methods.addAll(
    +        super.createNewBuilderMethods(
    +            service, typeStore, "newHttpJsonBuilder", "createHttpJsonDefault"));
    +    return methods;
    +  }
    +}
    diff --git a/src/main/java/com/google/api/generator/gapic/composer/rest/HttpJsonServiceCallableFactoryClassComposer.java b/src/main/java/com/google/api/generator/gapic/composer/rest/HttpJsonServiceCallableFactoryClassComposer.java
    index 7f8a966859..a7b525239e 100644
    --- a/src/main/java/com/google/api/generator/gapic/composer/rest/HttpJsonServiceCallableFactoryClassComposer.java
    +++ b/src/main/java/com/google/api/generator/gapic/composer/rest/HttpJsonServiceCallableFactoryClassComposer.java
    @@ -27,13 +27,14 @@
     import com.google.api.generator.engine.ast.NewObjectExpr;
     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.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.AbstractServiceCallableFactoryClassComposer;
     import com.google.api.generator.gapic.composer.store.TypeStore;
     import com.google.api.generator.gapic.model.Service;
    -import com.google.longrunning.Operation;
    +import com.google.common.collect.ImmutableList;
     import java.util.ArrayList;
     import java.util.Arrays;
     import java.util.List;
    @@ -45,7 +46,7 @@ public class HttpJsonServiceCallableFactoryClassComposer
           new HttpJsonServiceCallableFactoryClassComposer();
     
       private static final TypeNode DEFAULT_OPERATION_TYPE =
    -      TypeNode.withReference(ConcreteReference.withClazz(Operation.class));
    +      TypeNode.withReference(ConcreteReference.withClazz(Object.class));
     
       private HttpJsonServiceCallableFactoryClassComposer() {
         super(RestContext.instance());
    @@ -127,7 +128,16 @@ protected MethodDefinition createOperationCallableMethod(Service service, TypeSt
                     .collect(Collectors.toList()),
                 Arrays.asList(betaAnnotation));
     
    -    List createOperationCallableBody = new ArrayList(2);
    +    List createOperationCallableBody = new ArrayList<>();
    +    if (service.operationServiceStubType() == null) {
    +      // It is an Operation polling service, it cannot contain LRO methods
    +      return method
    +          .toBuilder()
    +          .setBody(ImmutableList.of())
    +          .setReturnExpr(ValueExpr.createNullExpr())
    +          .build();
    +    }
    +
         List arguments = new ArrayList<>(method.arguments());
     
         Variable httpJsonCallSettingsVar = arguments.get(0).variable();
    diff --git a/src/main/java/com/google/api/generator/gapic/composer/rest/HttpJsonServiceStubClassComposer.java b/src/main/java/com/google/api/generator/gapic/composer/rest/HttpJsonServiceStubClassComposer.java
    index 39974fe44a..fb45703936 100644
    --- a/src/main/java/com/google/api/generator/gapic/composer/rest/HttpJsonServiceStubClassComposer.java
    +++ b/src/main/java/com/google/api/generator/gapic/composer/rest/HttpJsonServiceStubClassComposer.java
    @@ -49,8 +49,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.AbstractServiceStubClassComposer;
    -import com.google.api.generator.gapic.composer.common.TransportContext;
    +import com.google.api.generator.gapic.composer.common.AbstractTransportServiceStubClassComposer;
     import com.google.api.generator.gapic.composer.store.TypeStore;
     import com.google.api.generator.gapic.model.HttpBindings.HttpBinding;
     import com.google.api.generator.gapic.model.Message;
    @@ -66,12 +65,13 @@
     import java.util.HashMap;
     import java.util.List;
     import java.util.Map;
    +import java.util.Optional;
     import java.util.Set;
     import java.util.function.BiFunction;
     import java.util.function.Function;
     import java.util.stream.Collectors;
     
    -public class HttpJsonServiceStubClassComposer extends AbstractServiceStubClassComposer {
    +public class HttpJsonServiceStubClassComposer extends AbstractTransportServiceStubClassComposer {
       private static final HttpJsonServiceStubClassComposer INSTANCE =
           new HttpJsonServiceStubClassComposer();
     
    @@ -101,6 +101,11 @@ private static TypeStore createStaticTypes() {
                 ProtoRestSerializer.class));
       }
     
    +  @Override
    +  protected boolean generateOperationsStubLogic(Service service) {
    +    return service.hasLroMethods();
    +  }
    +
       @Override
       protected Statement createMethodDescriptorVariableDecl(
           Service service,
    @@ -172,12 +177,11 @@ protected Statement createMethodDescriptorVariableDecl(
     
       @Override
       protected List createOperationsStubGetterMethod(
    -      VariableExpr operationsStubVarExpr) {
    -    return Collections.emptyList();
    -  }
    -
    -  public HttpJsonServiceStubClassComposer(TransportContext transportContext) {
    -    super(transportContext);
    +      Service service, VariableExpr operationsStubVarExpr) {
    +    if (!service.hasStandardLroMethods()) {
    +      return Collections.emptyList();
    +    }
    +    return super.createOperationsStubGetterMethod(service, operationsStubVarExpr);
       }
     
       @Override
    @@ -348,16 +352,20 @@ private List getRequestFormatterExpr(Method protoMethod) {
                 .apply(expr);
     
         extractorVarType = TypeNode.STRING;
    +    boolean asteriskBody = protoMethod.httpBindings().isAsteriskBody();
         expr =
             methodMaker
                 .apply(
                     "setRequestBodyExtractor",
                     Arrays.asList(
    -                    createFieldsExtractorClassInstance(
    +                    createBodyFieldsExtractorClassInstance(
                             protoMethod,
                             extractorVarType,
    -                        protoMethod.httpBindings().bodyParameters(),
    -                        "toBody")))
    +                        asteriskBody
    +                            ? protoMethod.httpBindings().pathParameters()
    +                            : protoMethod.httpBindings().bodyParameters(),
    +                        "toBody",
    +                        asteriskBody)))
                 .apply(expr);
         expr = methodMaker.apply("build", Collections.emptyList()).apply(expr);
     
    @@ -699,71 +707,148 @@ private List setPollingRequestFactoryExpr(
                 .build());
       }
     
    -  private Expr createFieldsExtractorClassInstance(
    +  private Expr createBodyFieldsExtractorClassInstance(
           Method method,
           TypeNode extractorReturnType,
           Set httpBindingFieldNames,
    -      String serializerMethodName) {
    +      String serializerMethodName,
    +      boolean asteriskBody) {
         List bodyStatements = new ArrayList<>();
     
         Expr returnExpr = null;
    -    VariableExpr fieldsVarExpr = null;
    -    Expr serializerExpr = null;
    -    if (extractorReturnType.isProtoPrimitiveType()) {
    -      serializerExpr =
    +    Expr serializerExpr =
    +        MethodInvocationExpr.builder()
    +            .setMethodName("create")
    +            .setStaticReferenceType(
    +                FIXED_REST_TYPESTORE.get(ProtoRestSerializer.class.getSimpleName()))
    +            .build();
    +
    +    VariableExpr requestVarExpr =
    +        VariableExpr.withVariable(
    +            Variable.builder().setType(method.inputType()).setName("request").build());
    +    Expr bodyRequestExpr = requestVarExpr;
    +    String requestMethodPrefix = "get";
    +    String bodyParamName = null;
    +
    +    if (asteriskBody) {
    +      bodyRequestExpr =
               MethodInvocationExpr.builder()
    -              .setMethodName("create")
    -              .setStaticReferenceType(
    -                  FIXED_REST_TYPESTORE.get(ProtoRestSerializer.class.getSimpleName()))
    +              .setExprReferenceExpr(requestVarExpr)
    +              .setMethodName("toBuilder")
                   .build();
    -      if (httpBindingFieldNames.isEmpty()) {
    -        returnExpr = ValueExpr.createNullExpr();
    +      // In case of `body: "*"` case we send the whole request message as a body, minus the fields
    +      // in the path, therefore the "clear" prefix here.
    +      requestMethodPrefix = "clear";
    +    }
    +
    +    Expr prevExpr = bodyRequestExpr;
    +    for (HttpBinding httpBindingFieldName : httpBindingFieldNames) {
    +      // Handle foo.bar cases by descending into the subfields.
    +      MethodInvocationExpr.Builder requestFieldMethodExprBuilder =
    +          MethodInvocationExpr.builder().setExprReferenceExpr(prevExpr);
    +      bodyParamName = JavaStyle.toLowerCamelCase(httpBindingFieldName.name());
    +      String[] descendantFields = httpBindingFieldName.name().split("\\.");
    +      if (asteriskBody && descendantFields.length > 1) {
    +        // This is the `body: "*"` case, do not clean nested body fields as it a very rare, not
    +        // well-defined case, and it is generally safer to send more than less in such case.
    +        continue;
           }
     
    +      for (int i = 0; i < descendantFields.length; i++) {
    +        String currFieldName = descendantFields[i];
    +        String bindingFieldMethodName =
    +            String.format("%s%s", requestMethodPrefix, JavaStyle.toUpperCamelCase(currFieldName));
    +        requestFieldMethodExprBuilder =
    +            requestFieldMethodExprBuilder.setMethodName(bindingFieldMethodName);
    +
    +        if (i < descendantFields.length - 1) {
    +          requestFieldMethodExprBuilder =
    +              MethodInvocationExpr.builder()
    +                  .setExprReferenceExpr(requestFieldMethodExprBuilder.build());
    +        }
    +      }
    +      prevExpr = requestFieldMethodExprBuilder.build();
    +    }
    +
    +    if (httpBindingFieldNames.isEmpty() && !asteriskBody) {
    +      returnExpr = ValueExpr.createNullExpr();
         } else {
    -      fieldsVarExpr =
    -          VariableExpr.withVariable(
    -              Variable.builder().setName("fields").setType(extractorReturnType).build());
    -      Expr fieldsAssignExpr =
    -          AssignmentExpr.builder()
    -              .setVariableExpr(fieldsVarExpr.toBuilder().setIsDecl(true).build())
    -              .setValueExpr(
    -                  NewObjectExpr.builder()
    -                      .setType(FIXED_REST_TYPESTORE.get(HashMap.class.getSimpleName()))
    -                      .setIsGeneric(true)
    -                      .build())
    +      ImmutableList.Builder paramsPutArgs = ImmutableList.builder();
    +      if (asteriskBody) {
    +        prevExpr =
    +            MethodInvocationExpr.builder()
    +                .setExprReferenceExpr(prevExpr)
    +                .setMethodName("build")
    +                .build();
    +        bodyParamName = "*";
    +      }
    +      paramsPutArgs.add(ValueExpr.withValue(StringObjectValue.withValue(bodyParamName)));
    +      paramsPutArgs.add(prevExpr);
    +
    +      returnExpr =
    +          MethodInvocationExpr.builder()
    +              .setExprReferenceExpr(serializerExpr)
    +              .setMethodName(serializerMethodName)
    +              .setArguments(paramsPutArgs.build())
    +              .setReturnType(extractorReturnType)
                   .build();
    +    }
    +
    +    // Overrides FieldsExtractor
    +    // (https://github.com/googleapis/gax-java/blob/12b18ee255d3fabe13bb3969df40753b29f830d5/gax-httpjson/src/main/java/com/google/api/gax/httpjson/FieldsExtractor.java).
    +    return LambdaExpr.builder()
    +        .setArguments(requestVarExpr.toBuilder().setIsDecl(true).build())
    +        .setBody(bodyStatements)
    +        .setReturnExpr(returnExpr)
    +        .build();
    +  }
     
    -      bodyStatements.add(ExprStatement.withExpr(fieldsAssignExpr));
    -      returnExpr = fieldsVarExpr;
    +  private Expr createFieldsExtractorClassInstance(
    +      Method method,
    +      TypeNode extractorReturnType,
    +      Set httpBindingFieldNames,
    +      String serializerMethodName) {
    +    List bodyStatements = new ArrayList<>();
     
    -      TypeNode serializerVarType =
    -          TypeNode.withReference(
    -              ConcreteReference.builder()
    -                  .setClazz(ProtoRestSerializer.class)
    -                  .setGenerics(method.inputType().reference())
    -                  .build());
    +    VariableExpr fieldsVarExpr =
    +        VariableExpr.withVariable(
    +            Variable.builder().setName("fields").setType(extractorReturnType).build());
    +    Expr fieldsAssignExpr =
    +        AssignmentExpr.builder()
    +            .setVariableExpr(fieldsVarExpr.toBuilder().setIsDecl(true).build())
    +            .setValueExpr(
    +                NewObjectExpr.builder()
    +                    .setType(FIXED_REST_TYPESTORE.get(HashMap.class.getSimpleName()))
    +                    .setIsGeneric(true)
    +                    .build())
    +            .build();
     
    -      VariableExpr serializerVarExpr =
    -          VariableExpr.withVariable(
    -              Variable.builder().setName("serializer").setType(serializerVarType).build());
    +    bodyStatements.add(ExprStatement.withExpr(fieldsAssignExpr));
     
    -      Expr serializerAssignExpr =
    -          AssignmentExpr.builder()
    -              .setVariableExpr(serializerVarExpr.toBuilder().setIsDecl(true).build())
    -              .setValueExpr(
    -                  MethodInvocationExpr.builder()
    -                      .setStaticReferenceType(
    -                          FIXED_REST_TYPESTORE.get(ProtoRestSerializer.class.getSimpleName()))
    -                      .setMethodName("create")
    -                      .setReturnType(serializerVarType)
    -                      .build())
    -              .build();
    +    TypeNode serializerVarType =
    +        TypeNode.withReference(
    +            ConcreteReference.builder()
    +                .setClazz(ProtoRestSerializer.class)
    +                .setGenerics(method.inputType().reference())
    +                .build());
     
    -      serializerExpr = serializerVarExpr;
    +    VariableExpr serializerVarExpr =
    +        VariableExpr.withVariable(
    +            Variable.builder().setName("serializer").setType(serializerVarType).build());
     
    -      bodyStatements.add(ExprStatement.withExpr(serializerAssignExpr));
    -    }
    +    Expr serializerAssignExpr =
    +        AssignmentExpr.builder()
    +            .setVariableExpr(serializerVarExpr.toBuilder().setIsDecl(true).build())
    +            .setValueExpr(
    +                MethodInvocationExpr.builder()
    +                    .setStaticReferenceType(
    +                        FIXED_REST_TYPESTORE.get(ProtoRestSerializer.class.getSimpleName()))
    +                    .setMethodName("create")
    +                    .setReturnType(serializerVarType)
    +                    .build())
    +            .build();
    +
    +    bodyStatements.add(ExprStatement.withExpr(serializerAssignExpr));
     
         VariableExpr requestVarExpr =
             VariableExpr.withVariable(
    @@ -806,9 +891,9 @@ private Expr createFieldsExtractorClassInstance(
           MethodInvocationExpr requestHasExpr = requestFieldHasExprBuilder.build();
     
           ImmutableList.Builder paramsPutArgs = ImmutableList.builder();
    -      if (fieldsVarExpr != null) {
    -        paramsPutArgs.add(fieldsVarExpr);
    -      }
    +
    +      paramsPutArgs.add(fieldsVarExpr);
    +
           paramsPutArgs.add(
               ValueExpr.withValue(
                   StringObjectValue.withValue(
    @@ -817,24 +902,20 @@ private Expr createFieldsExtractorClassInstance(
     
           Expr paramsPutExpr =
               MethodInvocationExpr.builder()
    -              .setExprReferenceExpr(serializerExpr)
    +              .setExprReferenceExpr(serializerVarExpr)
                   .setMethodName(serializerMethodName)
                   .setArguments(paramsPutArgs.build())
                   .setReturnType(extractorReturnType)
                   .build();
     
    -      if (fieldsVarExpr == null) {
    -        returnExpr = paramsPutExpr;
    +      if (httpBindingFieldName.isOptional()) {
    +        bodyStatements.add(
    +            IfStatement.builder()
    +                .setConditionExpr(requestHasExpr)
    +                .setBody(Arrays.asList(ExprStatement.withExpr(paramsPutExpr)))
    +                .build());
           } else {
    -        if (httpBindingFieldName.isOptional()) {
    -          bodyStatements.add(
    -              IfStatement.builder()
    -                  .setConditionExpr(requestHasExpr)
    -                  .setBody(Arrays.asList(ExprStatement.withExpr(paramsPutExpr)))
    -                  .build());
    -        } else {
    -          bodyStatements.add(ExprStatement.withExpr(paramsPutExpr));
    -        }
    +        bodyStatements.add(ExprStatement.withExpr(paramsPutExpr));
           }
         }
     
    @@ -843,7 +924,7 @@ private Expr createFieldsExtractorClassInstance(
         return LambdaExpr.builder()
             .setArguments(requestVarExpr.toBuilder().setIsDecl(true).build())
             .setBody(bodyStatements)
    -        .setReturnExpr(returnExpr)
    +        .setReturnExpr(fieldsVarExpr)
             .build();
       }
     
    @@ -942,24 +1023,25 @@ protected VariableExpr declareLongRunningClient() {
                 .build());
       }
     
    -  @Override
    -  protected List createLongRunningClientGetter() {
    -    VariableExpr longRunningClient =
    -        VariableExpr.withVariable(
    -            Variable.builder()
    -                .setName("longRunningClient")
    -                .setType(
    -                    TypeNode.withReference(ConcreteReference.withClazz(LongRunningClient.class)))
    -                .build());
    +  protected Optional getCallableCreatorMethodName(TypeNode callableVarExprType) {
    +    final String typeName = callableVarExprType.reference().name();
    +    String streamName = "Unary";
     
    -    return ImmutableList.of(
    -        MethodDefinition.builder()
    -            .setName("longRunningClient")
    -            .setScope(ScopeNode.PUBLIC)
    -            .setIsOverride(true)
    -            .setReturnType(
    -                TypeNode.withReference(ConcreteReference.withClazz(LongRunningClient.class)))
    -            .setReturnExpr(longRunningClient)
    -            .build());
    +    // Special handling for pagination methods.
    +    if (callableVarExprType.reference().generics().size() == 2
    +        && callableVarExprType.reference().generics().get(1).name().endsWith("PagedResponse")) {
    +      streamName = "Paged";
    +    } else {
    +      if (typeName.startsWith("Client")) {
    +        return Optional.empty(); // not supported in REST transport
    +      } else if (typeName.startsWith("Server")) {
    +        return Optional.empty(); // not supported in REST transport (for now)
    +      } else if (typeName.startsWith("Bidi")) {
    +        return Optional.empty(); // not supported in REST transport
    +      } else if (typeName.startsWith("Operation")) {
    +        streamName = "Operation";
    +      }
    +    }
    +    return Optional.of(String.format("create%sCallable", streamName));
       }
     }
    diff --git a/src/main/java/com/google/api/generator/gapic/composer/rest/RestContext.java b/src/main/java/com/google/api/generator/gapic/composer/rest/RestContext.java
    index fc5b385427..eab59215bf 100644
    --- a/src/main/java/com/google/api/generator/gapic/composer/rest/RestContext.java
    +++ b/src/main/java/com/google/api/generator/gapic/composer/rest/RestContext.java
    @@ -21,9 +21,13 @@
     import com.google.api.gax.httpjson.HttpJsonStubCallableFactory;
     import com.google.api.gax.httpjson.HttpJsonTransportChannel;
     import com.google.api.gax.httpjson.InstantiatingHttpJsonChannelProvider;
    +import com.google.api.gax.httpjson.ProtoOperationTransformers;
    +import com.google.api.gax.httpjson.longrunning.OperationsClient;
    +import com.google.api.gax.httpjson.longrunning.stub.HttpJsonOperationsStub;
     import com.google.api.generator.gapic.composer.common.TransportContext;
     import com.google.api.generator.gapic.composer.utils.ClassNames;
     import com.google.api.generator.gapic.model.Transport;
    +import com.google.common.collect.ImmutableList;
     
     public abstract class RestContext extends TransportContext {
       private static final TransportContext INSTANCE =
    @@ -35,18 +39,35 @@ public abstract class RestContext extends TransportContext {
               .setCallSettingsClass(HttpJsonCallSettings.class)
               .setStubCallableFactoryType(classToType(HttpJsonStubCallableFactory.class))
               .setMethodDescriptorClass(ApiMethodDescriptor.class)
    -          .setTransportOperationsStubType(null)
    +          .setTransportOperationsStubTypes(
    +              ImmutableList.of(classToType(HttpJsonOperationsStub.class)))
    +          .setTransportOperationsStubNames(ImmutableList.of("httpJsonOperationsStub"))
               // For httpjson.ServiceSettingsClassComposer
    -          .setInstantiatingChannelProviderClass(InstantiatingHttpJsonChannelProvider.Builder.class)
    -          .setDefaultTransportProviderBuilderName("defaultHttpJsonTransportProviderBuilder")
    +          .setInstantiatingChannelProviderClasses(
    +              ImmutableList.of(InstantiatingHttpJsonChannelProvider.class))
    +          .setInstantiatingChannelProviderBuilderClasses(
    +              ImmutableList.of(InstantiatingHttpJsonChannelProvider.Builder.class))
    +          .setDefaultTransportProviderBuilderNames(
    +              ImmutableList.of("defaultHttpJsonTransportProviderBuilder"))
    +          .setTransportApiClientHeaderProviderBuilderNames(
    +              ImmutableList.of("defaultHttpJsonApiClientHeaderProviderBuilder"))
               // For httpjson.ServiceStubSettingsClassComposer
    -          .setTransportChannelType(classToType(HttpJsonTransportChannel.class))
    -          .setTransportGetterName("getHttpJsonTransportName")
    +          .setTransportChannelTypes(ImmutableList.of(classToType(HttpJsonTransportChannel.class)))
    +          .setTransportGetterNames(ImmutableList.of("getHttpJsonTransportName"))
               // For httpjson.HttpJsonServiceCallableFactoryClassComposer
               .setTransportCallSettingsType(classToType(HttpJsonCallSettings.class))
               .setTransportCallableFactoryType(classToType(HttpJsonCallableFactory.class))
    -          .setOperationsStubType(classToType(BackgroundResource.class))
    +          // TODO: set to com.google.api.gax.httpjson.longrunning.stub.OperationsStub.class
    +          .setOperationsStubTypes(ImmutableList.of(classToType(BackgroundResource.class)))
               .setTransportCallSettingsName("httpJsonCallSettings")
    +          // For RetrySettingsComposer
    +          .setOperationResponseTransformerType(
    +              classToType(ProtoOperationTransformers.ResponseTransformer.class))
    +          .setOperationMetadataTransformerType(
    +              classToType(ProtoOperationTransformers.MetadataTransformer.class))
    +          // For ServiceClientClassComposer
    +          .setOperationsClientTypes(ImmutableList.of(classToType(OperationsClient.class)))
    +          .setOperationsClientNames(ImmutableList.of("httpJsonOperationsClient"))
               .build();
     
       public static TransportContext instance() {
    diff --git a/src/main/java/com/google/api/generator/gapic/composer/rest/ServiceClientClassComposer.java b/src/main/java/com/google/api/generator/gapic/composer/rest/ServiceClientClassComposer.java
    new file mode 100644
    index 0000000000..9b5f996db7
    --- /dev/null
    +++ b/src/main/java/com/google/api/generator/gapic/composer/rest/ServiceClientClassComposer.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
    + *
    + *     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.composer.rest;
    +
    +import com.google.api.generator.gapic.composer.common.AbstractServiceClientClassComposer;
    +
    +public class ServiceClientClassComposer extends AbstractServiceClientClassComposer {
    +  private static final ServiceClientClassComposer INSTANCE = new ServiceClientClassComposer();
    +
    +  protected ServiceClientClassComposer() {
    +    super(RestContext.instance());
    +  }
    +
    +  public static ServiceClientClassComposer instance() {
    +    return INSTANCE;
    +  }
    +}
    diff --git a/src/main/java/com/google/api/generator/gapic/composer/rest/ServiceClientTestClassComposer.java b/src/main/java/com/google/api/generator/gapic/composer/rest/ServiceClientTestClassComposer.java
    index 5eed17f8f2..893777e057 100644
    --- a/src/main/java/com/google/api/generator/gapic/composer/rest/ServiceClientTestClassComposer.java
    +++ b/src/main/java/com/google/api/generator/gapic/composer/rest/ServiceClientTestClassComposer.java
    @@ -39,6 +39,7 @@
     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.GapicContext;
    @@ -72,7 +73,7 @@ protected ServiceClientTestClassComposer() {
         super(RestContext.instance());
       }
     
    -  public static ServiceClientTestClassComposer instance() {
    +  public static AbstractServiceClientTestClassComposer instance() {
         return INSTANCE;
       }
     
    @@ -125,7 +126,8 @@ protected MethodDefinition createStartStaticServerMethod(
           Service service,
           GapicContext context,
           Map classMemberVarExprs,
    -      TypeStore typeStore) {
    +      TypeStore typeStore,
    +      String newBuilderMethod) {
     
         VariableExpr mockServiceVarExpr = classMemberVarExprs.get(MOCK_SERVICE_VAR_NAME);
         VariableExpr clientVarExpr = classMemberVarExprs.get(CLIENT_VAR_NAME);
    @@ -167,7 +169,7 @@ protected MethodDefinition createStartStaticServerMethod(
         Expr settingsBuilderExpr =
             MethodInvocationExpr.builder()
                 .setStaticReferenceType(settingsType)
    -            .setMethodName("newBuilder")
    +            .setMethodName(newBuilderMethod)
                 .build();
     
         Expr transportChannelProviderExpr =
    @@ -420,7 +422,18 @@ protected MethodDefinition createStreamingRpcTestMethod(
           Map classMemberVarExprs,
           Map resourceNames,
           Map messageTypes) {
    -    return null;
    +    // Add some actual statements once implemented
    +    List methodStatements = new ArrayList<>();
    +
    +    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
    @@ -513,6 +526,12 @@ protected List createStreamingRpcExceptionTestStatements(
         return Collections.emptyList();
       }
     
    +  @Override
    +  protected Expr createDefaultValue(
    +      MethodArgument methodArg, Map resourceNames) {
    +    return DefaultValueComposer.createDefaultValue(methodArg, resourceNames, true);
    +  }
    +
       @Override
       protected List createRpcLroExceptionTestCatchBody(
           VariableExpr exceptionExpr, boolean isStreaming) {
    diff --git a/src/main/java/com/google/api/generator/gapic/composer/rest/ServiceStubClassComposer.java b/src/main/java/com/google/api/generator/gapic/composer/rest/ServiceStubClassComposer.java
    new file mode 100644
    index 0000000000..704fac96b6
    --- /dev/null
    +++ b/src/main/java/com/google/api/generator/gapic/composer/rest/ServiceStubClassComposer.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
    + *
    + *     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.composer.rest;
    +
    +import com.google.api.generator.gapic.composer.common.AbstractServiceStubClassComposer;
    +
    +public class ServiceStubClassComposer extends AbstractServiceStubClassComposer {
    +  private static final ServiceStubClassComposer INSTANCE = new ServiceStubClassComposer();
    +
    +  protected ServiceStubClassComposer() {
    +    super(RestContext.instance());
    +  }
    +
    +  public static ServiceStubClassComposer instance() {
    +    return INSTANCE;
    +  }
    +}
    diff --git a/src/main/java/com/google/api/generator/gapic/composer/rest/ServiceStubSettingsClassComposer.java b/src/main/java/com/google/api/generator/gapic/composer/rest/ServiceStubSettingsClassComposer.java
    index 9375399546..b12528ec3f 100644
    --- a/src/main/java/com/google/api/generator/gapic/composer/rest/ServiceStubSettingsClassComposer.java
    +++ b/src/main/java/com/google/api/generator/gapic/composer/rest/ServiceStubSettingsClassComposer.java
    @@ -17,23 +17,16 @@
     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.comment.SettingsCommentComposer;
     import com.google.api.generator.gapic.composer.common.AbstractServiceStubSettingsClassComposer;
     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;
    +import java.util.Collections;
    +import java.util.List;
     
     public class ServiceStubSettingsClassComposer extends AbstractServiceStubSettingsClassComposer {
       private static final ServiceStubSettingsClassComposer INSTANCE =
    @@ -58,94 +51,16 @@ private static TypeStore createStaticTypes() {
       }
     
       @Override
    -  protected MethodDefinition createDefaultTransportTransportProviderBuilderMethod() {
    -    // Create the defaultHttpJsonTransportProviderBuilder method.
    -    TypeNode returnType =
    -        TypeNode.withReference(
    -            ConcreteReference.withClazz(InstantiatingHttpJsonChannelProvider.Builder.class));
    -    MethodInvocationExpr transportChannelProviderBuilderExpr =
    -        MethodInvocationExpr.builder()
    -            .setStaticReferenceType(
    -                FIXED_REST_TYPESTORE.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(
    +  protected List createApiClientHeaderProviderBuilderMethods(
           Service service, TypeStore typeStore) {
    -    // Create the defaultApiClientHeaderProviderBuilder method.
    -    TypeNode 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_REST_TYPESTORE.get(GaxHttpJsonProperties.class.getSimpleName()))
    -                    .setMethodName("getHttpJsonTokenName")
    -                    .build(),
    -                MethodInvocationExpr.builder()
    -                    .setStaticReferenceType(
    -                        FIXED_REST_TYPESTORE.get(GaxHttpJsonProperties.class.getSimpleName()))
    -                    .setMethodName("getHttpJsonVersion")
    -                    .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();
    -    return MethodDefinition.builder()
    -        .setAnnotations(Arrays.asList(annotation))
    -        .setScope(ScopeNode.PUBLIC)
    -        .setIsStatic(true)
    -        .setReturnType(returnType)
    -        .setName("defaultApiClientHeaderProviderBuilder")
    -        .setReturnExpr(returnExpr)
    -        .build();
    +    return Collections.singletonList(
    +        createApiClientHeaderProviderBuilderMethod(
    +            service,
    +            typeStore,
    +            "defaultApiClientHeaderProviderBuilder",
    +            FIXED_REST_TYPESTORE.get(GaxHttpJsonProperties.class.getSimpleName()),
    +            "getHttpJsonTokenName",
    +            "getHttpJsonVersion"));
       }
     
       @Override
    diff --git a/src/main/java/com/google/api/generator/gapic/composer/samplecode/ServiceClientSampleCodeComposer.java b/src/main/java/com/google/api/generator/gapic/composer/samplecode/ServiceClientSampleCodeComposer.java
    index ac8d805b59..5572bde8e3 100644
    --- a/src/main/java/com/google/api/generator/gapic/composer/samplecode/ServiceClientSampleCodeComposer.java
    +++ b/src/main/java/com/google/api/generator/gapic/composer/samplecode/ServiceClientSampleCodeComposer.java
    @@ -1310,7 +1310,7 @@ private static List createRpcMethodArgumentDefaultValueExprs(
             .map(
                 arg ->
                     !isStringTypedResourceName(arg, resourceNames)
    -                    ? DefaultValueComposer.createDefaultValue(arg, resourceNames)
    +                    ? DefaultValueComposer.createDefaultValue(arg, resourceNames, false)
                         : stringResourceNameDefaultValueExpr.apply(arg))
             .collect(Collectors.toList());
       }
    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 f1abb45a4c..c0b717fc0a 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
    @@ -15,6 +15,9 @@
     package com.google.api.generator.gapic.composer.utils;
     
     import com.google.api.generator.gapic.model.Service;
    +import java.util.Arrays;
    +import java.util.List;
    +import java.util.stream.Collectors;
     
     /** Provides Gapic class names. */
     public class ClassNames {
    @@ -23,6 +26,7 @@ public class ClassNames {
       private static final String MOCK_SERVICE_IMPL_CLASS_NAME_PATTERN = "Mock%sImpl";
       private static final String SERVICE_CLIENT_CLASS_NAME_PATTERN = "%sClient";
       private static final String SERVICE_CLIENT_TEST_CLASS_NAME_PATTERN = "%sClientTest";
    +  private static final String SERVICE_CLIENT_TRANSPORT_TEST_CLASS_NAME_PATTERN = "%sClient%sTest";
       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";
    @@ -30,10 +34,10 @@ public class ClassNames {
       private static final String TRANSPORT_SERVICE_CALLABLE_FACTORY_CLASS_NAME_PATTERN =
           "%s%sCallableFactory";
     
    -  private final String transportPrefix;
    +  private final List transportPrefixes;
     
    -  public ClassNames(String transportPrefix) {
    -    this.transportPrefix = transportPrefix;
    +  public ClassNames(String... transportPrefixes) {
    +    this.transportPrefixes = Arrays.asList(transportPrefixes);
       }
     
       public static String getServiceClientClassName(Service service) {
    @@ -59,23 +63,50 @@ public static String getServiceStubClassName(Service service) {
       }
     
       public String getTransportServiceCallableFactoryClassName(Service service) {
    -    return String.format(
    -        TRANSPORT_SERVICE_CALLABLE_FACTORY_CLASS_NAME_PATTERN,
    -        transportPrefix,
    -        monolithBackwardsCompatibleName(service.name()));
    +    return getTransportServiceCallableFactoryClassNames(service).get(0);
    +  }
    +
    +  public List getTransportServiceCallableFactoryClassNames(Service service) {
    +    return transportPrefixes.stream()
    +        .map(
    +            prefix ->
    +                String.format(
    +                    TRANSPORT_SERVICE_CALLABLE_FACTORY_CLASS_NAME_PATTERN,
    +                    prefix,
    +                    monolithBackwardsCompatibleName(service.name())))
    +        .collect(Collectors.toList());
       }
     
       public String getTransportServiceStubClassName(Service service) {
    -    return String.format(
    -        TRANSPORT_SERVICE_STUB_CLASS_NAME_PATTERN,
    -        transportPrefix,
    -        monolithBackwardsCompatibleName(service.name()));
    +    return getTransportServiceStubClassNames(service).get(0);
    +  }
    +
    +  public List getTransportServiceStubClassNames(Service service) {
    +    return transportPrefixes.stream()
    +        .map(
    +            prefix ->
    +                String.format(
    +                    TRANSPORT_SERVICE_STUB_CLASS_NAME_PATTERN,
    +                    prefix,
    +                    monolithBackwardsCompatibleName(service.name())))
    +        .collect(Collectors.toList());
       }
     
       public static String getServiceClientTestClassName(Service service) {
         return String.format(SERVICE_CLIENT_TEST_CLASS_NAME_PATTERN, service.overriddenName());
       }
     
    +  public List getServiceClientTestClassNames(Service service) {
    +    return transportPrefixes.stream()
    +        .map(
    +            prefix ->
    +                String.format(
    +                    SERVICE_CLIENT_TRANSPORT_TEST_CLASS_NAME_PATTERN,
    +                    service.overriddenName(),
    +                    prefix))
    +        .collect(Collectors.toList());
    +  }
    +
       public static String getMockServiceClassName(Service service) {
         return String.format(MOCK_SERVICE_CLASS_NAME_PATTERN, service.name());
       }
    diff --git a/src/main/java/com/google/api/generator/gapic/model/HttpBindings.java b/src/main/java/com/google/api/generator/gapic/model/HttpBindings.java
    index 9ca67cf4c7..171f6b1bf7 100644
    --- a/src/main/java/com/google/api/generator/gapic/model/HttpBindings.java
    +++ b/src/main/java/com/google/api/generator/gapic/model/HttpBindings.java
    @@ -57,6 +57,8 @@ public int compareTo(HttpBinding o) {
     
       public abstract Set bodyParameters();
     
    +  public abstract boolean isAsteriskBody();
    +
       public static HttpBindings.Builder builder() {
         return new AutoValue_HttpBindings.Builder()
             .setPathParameters(ImmutableSet.of())
    @@ -93,6 +95,8 @@ public abstract static class Builder {
     
         public abstract HttpBindings.Builder setBodyParameters(Set bodyParameters);
     
    +    public abstract HttpBindings.Builder setIsAsteriskBody(boolean asteriskBody);
    +
         public abstract HttpBindings autoBuild();
     
         public HttpBindings build() {
    diff --git a/src/main/java/com/google/api/generator/gapic/model/Service.java b/src/main/java/com/google/api/generator/gapic/model/Service.java
    index ace91051bc..34d3f97b25 100644
    --- a/src/main/java/com/google/api/generator/gapic/model/Service.java
    +++ b/src/main/java/com/google/api/generator/gapic/model/Service.java
    @@ -79,6 +79,24 @@ public TypeNode operationType() {
         return null;
       }
     
    +  public boolean hasLroMethods() {
    +    for (Method method : methods()) {
    +      if (method.hasLro()) {
    +        return true;
    +      }
    +    }
    +    return false;
    +  }
    +
    +  public boolean hasStandardLroMethods() {
    +    for (Method method : methods()) {
    +      if (method.hasLro() && method.lro().operationServiceStubType() == null) {
    +        return true;
    +      }
    +    }
    +    return false;
    +  }
    +
       public abstract Builder toBuilder();
     
       public static Builder builder() {
    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 aeb7b9361c..ae7820c8ed 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
    @@ -17,8 +17,6 @@
     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;
     
       /**
    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 26629949ef..36828206d3 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
    @@ -104,6 +104,7 @@ private static HttpBindings parseHttpRuleHelper(
                 validateAndConstructHttpBindings(queryParamNames, message, messageTypes, false))
             .setBodyParameters(
                 validateAndConstructHttpBindings(bodyParamNames, message, messageTypes, false))
    +        .setIsAsteriskBody(body.equals(ASTERISK))
             .build();
       }
     
    diff --git a/src/test/java/com/google/api/generator/gapic/BUILD.bazel b/src/test/java/com/google/api/generator/gapic/BUILD.bazel
    index 40de9b259f..5c5f8983ad 100644
    --- a/src/test/java/com/google/api/generator/gapic/BUILD.bazel
    +++ b/src/test/java/com/google/api/generator/gapic/BUILD.bazel
    @@ -6,6 +6,7 @@ filegroup(
             "//src/test/java/com/google/api/generator/gapic/composer:composer_files",
             "//src/test/java/com/google/api/generator/gapic/composer/defaultvalue:defaultvalue_files",
             "//src/test/java/com/google/api/generator/gapic/composer/grpc:grpc_files",
    +        #        "//src/test/java/com/google/api/generator/gapic/composer/grpcrest:grpcrest_files",
             "//src/test/java/com/google/api/generator/gapic/composer/resourcename:resourcename_files",
             "//src/test/java/com/google/api/generator/gapic/composer/rest:rest_files",
             "//src/test/java/com/google/api/generator/gapic/composer/samplecode:samplecode_files",
    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
    index 159c97d9b1..28a4bfc8b4 100644
    --- 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
    @@ -5,8 +5,6 @@ package(default_visibility = ["//visibility:public"])
     
     UPDATE_GOLDENS_TESTS = [
         "BatchingDescriptorComposerTest",
    -    "ServiceClientClassComposerTest",
    -    "ServiceStubClassComposerTest",
     ]
     
     TESTS = UPDATE_GOLDENS_TESTS + [
    diff --git a/src/test/java/com/google/api/generator/gapic/composer/common/RetrySettingsComposerTest.java b/src/test/java/com/google/api/generator/gapic/composer/common/RetrySettingsComposerTest.java
    index 09b1bf5b1c..d3fa5aa2e9 100644
    --- a/src/test/java/com/google/api/generator/gapic/composer/common/RetrySettingsComposerTest.java
    +++ b/src/test/java/com/google/api/generator/gapic/composer/common/RetrySettingsComposerTest.java
    @@ -27,6 +27,7 @@
     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.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;
    @@ -329,7 +330,9 @@ public void lroBuilderExpr() {
                 waitMethod,
                 builderVarExpr,
                 RETRY_CODES_DEFINITIONS_VAR_EXPR,
    -            RETRY_PARAM_DEFINITIONS_VAR_EXPR);
    +            RETRY_PARAM_DEFINITIONS_VAR_EXPR,
    +            GrpcContext.instance().operationResponseTransformerType(),
    +            GrpcContext.instance().operationMetadataTransformerType());
         builderExpr.accept(writerVisitor);
         String expected =
             LineFormatter.lines(
    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 14ac8deeba..825635a75e 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
    @@ -8,8 +8,10 @@ TESTS = [
         "GrpcServiceStubClassComposerTest",
         "MockServiceClassComposerTest",
         "MockServiceImplClassComposerTest",
    +    "ServiceClientClassComposerTest",
         "ServiceClientTestClassComposerTest",
         "ServiceSettingsClassComposerTest",
    +    "ServiceStubClassComposerTest",
         "ServiceStubSettingsClassComposerTest",
     ]
     
    diff --git a/src/test/java/com/google/api/generator/gapic/composer/common/ServiceClientClassComposerTest.java b/src/test/java/com/google/api/generator/gapic/composer/grpc/ServiceClientClassComposerTest.java
    similarity index 89%
    rename from src/test/java/com/google/api/generator/gapic/composer/common/ServiceClientClassComposerTest.java
    rename to src/test/java/com/google/api/generator/gapic/composer/grpc/ServiceClientClassComposerTest.java
    index b7767f41a6..331b94e484 100644
    --- a/src/test/java/com/google/api/generator/gapic/composer/common/ServiceClientClassComposerTest.java
    +++ b/src/test/java/com/google/api/generator/gapic/composer/grpc/ServiceClientClassComposerTest.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.common;
    +package com.google.api.generator.gapic.composer.grpc;
     
     import static com.google.api.generator.test.framework.Assert.assertCodeEquals;
     
    @@ -28,7 +28,7 @@
     public class ServiceClientClassComposerTest {
       @Test
       public void generateServiceClasses() {
    -    GapicContext context = TestProtoLoader.instance().parseShowcaseEcho();
    +    GapicContext context = GrpcTestProtoLoader.instance().parseShowcaseEcho();
         Service echoProtoService = context.services().get(0);
         GapicClass clazz = ServiceClientClassComposer.instance().generate(context, echoProtoService);
     
    @@ -41,7 +41,7 @@ public void generateServiceClasses() {
     
       @Test
       public void generateServiceClasses_deprecated() {
    -    GapicContext context = TestProtoLoader.instance().parseDeprecatedService();
    +    GapicContext context = GrpcTestProtoLoader.instance().parseDeprecatedService();
         Service protoService = context.services().get(0);
         GapicClass clazz = ServiceClientClassComposer.instance().generate(context, protoService);
     
    @@ -55,7 +55,7 @@ public void generateServiceClasses_deprecated() {
     
       @Test
       public void generateServiceClasses_methodSignatureHasNestedFields() {
    -    GapicContext context = TestProtoLoader.instance().parseShowcaseIdentity();
    +    GapicContext context = GrpcTestProtoLoader.instance().parseShowcaseIdentity();
         Service protoService = context.services().get(0);
         GapicClass clazz = ServiceClientClassComposer.instance().generate(context, protoService);
     
    @@ -68,7 +68,7 @@ public void generateServiceClasses_methodSignatureHasNestedFields() {
     
       @Test
       public void generateServiceClasses_bookshopNameConflicts() {
    -    GapicContext context = TestProtoLoader.instance().parseBookshopService();
    +    GapicContext context = GrpcTestProtoLoader.instance().parseBookshopService();
         Service protoService = context.services().get(0);
         GapicClass clazz = ServiceClientClassComposer.instance().generate(context, protoService);
     
    diff --git a/src/test/java/com/google/api/generator/gapic/composer/common/ServiceStubClassComposerTest.java b/src/test/java/com/google/api/generator/gapic/composer/grpc/ServiceStubClassComposerTest.java
    similarity index 94%
    rename from src/test/java/com/google/api/generator/gapic/composer/common/ServiceStubClassComposerTest.java
    rename to src/test/java/com/google/api/generator/gapic/composer/grpc/ServiceStubClassComposerTest.java
    index b30ce3630c..bb411b9ad3 100644
    --- a/src/test/java/com/google/api/generator/gapic/composer/common/ServiceStubClassComposerTest.java
    +++ b/src/test/java/com/google/api/generator/gapic/composer/grpc/ServiceStubClassComposerTest.java
    @@ -12,9 +12,10 @@
     // See the License for the specific language governing permissions and
     // limitations under the License.
     
    -package com.google.api.generator.gapic.composer.common;
    +package com.google.api.generator.gapic.composer.grpc;
     
     import com.google.api.generator.engine.writer.JavaWriterVisitor;
    +import com.google.api.generator.gapic.composer.common.TestProtoLoader;
     import com.google.api.generator.gapic.model.GapicClass;
     import com.google.api.generator.gapic.model.GapicContext;
     import com.google.api.generator.gapic.model.Service;
    diff --git a/src/test/java/com/google/api/generator/gapic/composer/common/goldens/BookshopClient.golden b/src/test/java/com/google/api/generator/gapic/composer/grpc/goldens/BookshopClient.golden
    similarity index 100%
    rename from src/test/java/com/google/api/generator/gapic/composer/common/goldens/BookshopClient.golden
    rename to src/test/java/com/google/api/generator/gapic/composer/grpc/goldens/BookshopClient.golden
    diff --git a/src/test/java/com/google/api/generator/gapic/composer/common/goldens/DeprecatedServiceClient.golden b/src/test/java/com/google/api/generator/gapic/composer/grpc/goldens/DeprecatedServiceClient.golden
    similarity index 100%
    rename from src/test/java/com/google/api/generator/gapic/composer/common/goldens/DeprecatedServiceClient.golden
    rename to src/test/java/com/google/api/generator/gapic/composer/grpc/goldens/DeprecatedServiceClient.golden
    diff --git a/src/test/java/com/google/api/generator/gapic/composer/common/goldens/DeprecatedServiceStub.golden b/src/test/java/com/google/api/generator/gapic/composer/grpc/goldens/DeprecatedServiceStub.golden
    similarity index 100%
    rename from src/test/java/com/google/api/generator/gapic/composer/common/goldens/DeprecatedServiceStub.golden
    rename to src/test/java/com/google/api/generator/gapic/composer/grpc/goldens/DeprecatedServiceStub.golden
    diff --git a/src/test/java/com/google/api/generator/gapic/composer/common/goldens/EchoClient.golden b/src/test/java/com/google/api/generator/gapic/composer/grpc/goldens/EchoClient.golden
    similarity index 100%
    rename from src/test/java/com/google/api/generator/gapic/composer/common/goldens/EchoClient.golden
    rename to src/test/java/com/google/api/generator/gapic/composer/grpc/goldens/EchoClient.golden
    diff --git a/src/test/java/com/google/api/generator/gapic/composer/common/goldens/EchoStub.golden b/src/test/java/com/google/api/generator/gapic/composer/grpc/goldens/EchoStub.golden
    similarity index 100%
    rename from src/test/java/com/google/api/generator/gapic/composer/common/goldens/EchoStub.golden
    rename to src/test/java/com/google/api/generator/gapic/composer/grpc/goldens/EchoStub.golden
    diff --git a/src/test/java/com/google/api/generator/gapic/composer/common/goldens/IdentityClient.golden b/src/test/java/com/google/api/generator/gapic/composer/grpc/goldens/IdentityClient.golden
    similarity index 100%
    rename from src/test/java/com/google/api/generator/gapic/composer/common/goldens/IdentityClient.golden
    rename to src/test/java/com/google/api/generator/gapic/composer/grpc/goldens/IdentityClient.golden
    diff --git a/src/test/java/com/google/api/generator/gapic/composer/rest/ServiceStubSettingsClassComposerTest.java b/src/test/java/com/google/api/generator/gapic/composer/rest/ServiceStubSettingsClassComposerTest.java
    index e3e5641f93..53392a549e 100644
    --- a/src/test/java/com/google/api/generator/gapic/composer/rest/ServiceStubSettingsClassComposerTest.java
    +++ b/src/test/java/com/google/api/generator/gapic/composer/rest/ServiceStubSettingsClassComposerTest.java
    @@ -27,7 +27,7 @@
     public class ServiceStubSettingsClassComposerTest {
       @Test
       public void generateServiceStubSettingsClasses_basic() {
    -    GapicContext context = RestTestProtoLoader.instance().parseShowcaseEcho();
    +    GapicContext context = RestTestProtoLoader.instance().parseCompliance();
         Service echoProtoService = context.services().get(0);
         GapicClass clazz =
             ServiceStubSettingsClassComposer.instance().generate(context, echoProtoService);
    diff --git a/src/test/java/com/google/api/generator/gapic/composer/rest/goldens/ComplianceStubSettings.golden b/src/test/java/com/google/api/generator/gapic/composer/rest/goldens/ComplianceStubSettings.golden
    index 3535651104..a858c0123e 100644
    --- a/src/test/java/com/google/api/generator/gapic/composer/rest/goldens/ComplianceStubSettings.golden
    +++ b/src/test/java/com/google/api/generator/gapic/composer/rest/goldens/ComplianceStubSettings.golden
    @@ -1,60 +1,33 @@
     package com.google.showcase.v1beta1.stub;
     
    -import static com.google.showcase.v1beta1.EchoClient.PagedExpandPagedResponse;
    -import static com.google.showcase.v1beta1.EchoClient.SimplePagedExpandPagedResponse;
    -
     import com.google.api.core.ApiFunction;
    -import com.google.api.core.ApiFuture;
     import com.google.api.core.BetaApi;
     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.ProtoOperationTransformers;
     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.longrunning.OperationSnapshot;
    -import com.google.api.gax.longrunning.OperationTimedPollAlgorithm;
     import com.google.api.gax.retrying.RetrySettings;
    -import com.google.api.gax.rpc.ApiCallContext;
     import com.google.api.gax.rpc.ApiClientHeaderProvider;
     import com.google.api.gax.rpc.ClientContext;
    -import com.google.api.gax.rpc.OperationCallSettings;
    -import com.google.api.gax.rpc.PageContext;
    -import com.google.api.gax.rpc.PagedCallSettings;
    -import com.google.api.gax.rpc.PagedListDescriptor;
    -import com.google.api.gax.rpc.PagedListResponseFactory;
    -import com.google.api.gax.rpc.ServerStreamingCallSettings;
     import com.google.api.gax.rpc.StatusCode;
    -import com.google.api.gax.rpc.StreamingCallSettings;
     import com.google.api.gax.rpc.StubSettings;
     import com.google.api.gax.rpc.TransportChannelProvider;
     import com.google.api.gax.rpc.UnaryCallSettings;
    -import com.google.api.gax.rpc.UnaryCallable;
     import com.google.common.collect.ImmutableList;
     import com.google.common.collect.ImmutableMap;
     import com.google.common.collect.ImmutableSet;
     import com.google.common.collect.Lists;
    -import com.google.longrunning.Operation;
    -import com.google.showcase.v1beta1.BlockRequest;
    -import com.google.showcase.v1beta1.BlockResponse;
    -import com.google.showcase.v1beta1.EchoRequest;
    -import com.google.showcase.v1beta1.EchoResponse;
    -import com.google.showcase.v1beta1.ExpandRequest;
    -import com.google.showcase.v1beta1.Object;
    -import com.google.showcase.v1beta1.PagedExpandRequest;
    -import com.google.showcase.v1beta1.PagedExpandResponse;
    -import com.google.showcase.v1beta1.WaitMetadata;
    -import com.google.showcase.v1beta1.WaitRequest;
    -import com.google.showcase.v1beta1.WaitResponse;
    +import com.google.showcase.v1beta1.RepeatRequest;
    +import com.google.showcase.v1beta1.RepeatResponse;
     import java.io.IOException;
     import java.util.List;
     import javax.annotation.Generated;
    -import org.threeten.bp.Duration;
     
     // AUTO-GENERATED DOCUMENTATION AND CLASS.
     /**
    - * Settings class to configure an instance of {@link EchoStub}.
    + * Settings class to configure an instance of {@link ComplianceStub}.
      *
      * 

    The default instance has everything set to sensible defaults: * @@ -67,214 +40,73 @@ import org.threeten.bp.Duration; *

    The builder of this class is recursive, so contained classes are themselves builders. When * build() is called, the tree of builders is called to create the complete settings object. * - *

    For example, to set the total timeout of echo to 30 seconds: + *

    For example, to set the total timeout of repeatDataBody to 30 seconds: * *

    {@code
    - * EchoStubSettings.Builder echoSettingsBuilder = EchoStubSettings.newBuilder();
    - * echoSettingsBuilder
    - *     .echoSettings()
    + * ComplianceStubSettings.Builder complianceSettingsBuilder = ComplianceStubSettings.newBuilder();
    + * complianceSettingsBuilder
    + *     .repeatDataBodySettings()
      *     .setRetrySettings(
    - *         echoSettingsBuilder
    - *             .echoSettings()
    + *         complianceSettingsBuilder
    + *             .repeatDataBodySettings()
      *             .getRetrySettings()
      *             .toBuilder()
      *             .setTotalTimeout(Duration.ofSeconds(30))
      *             .build());
    - * EchoStubSettings echoSettings = echoSettingsBuilder.build();
    + * ComplianceStubSettings complianceSettings = complianceSettingsBuilder.build();
      * }
    */ @BetaApi @Generated("by gapic-generator-java") -public class EchoStubSettings extends StubSettings { +public class ComplianceStubSettings extends StubSettings { /** The default scopes of the service. */ private static final ImmutableList DEFAULT_SERVICE_SCOPES = - ImmutableList.builder().add("https://www.googleapis.com/auth/cloud-platform").build(); - - private final UnaryCallSettings echoSettings; - private final ServerStreamingCallSettings expandSettings; - private final StreamingCallSettings collectSettings; - private final StreamingCallSettings chatSettings; - private final StreamingCallSettings chatAgainSettings; - private final PagedCallSettings - pagedExpandSettings; - private final PagedCallSettings< - PagedExpandRequest, PagedExpandResponse, SimplePagedExpandPagedResponse> - simplePagedExpandSettings; - private final UnaryCallSettings waitSettings; - private final OperationCallSettings - waitOperationSettings; - private final UnaryCallSettings blockSettings; - private final UnaryCallSettings collideNameSettings; - - private static final PagedListDescriptor - PAGED_EXPAND_PAGE_STR_DESC = - new PagedListDescriptor() { - @Override - public String emptyToken() { - return ""; - } - - @Override - public PagedExpandRequest injectToken(PagedExpandRequest payload, String token) { - return PagedExpandRequest.newBuilder(payload).setPageToken(token).build(); - } - - @Override - public PagedExpandRequest injectPageSize(PagedExpandRequest payload, int pageSize) { - return PagedExpandRequest.newBuilder(payload).setPageSize(pageSize).build(); - } - - @Override - public Integer extractPageSize(PagedExpandRequest payload) { - return payload.getPageSize(); - } - - @Override - public String extractNextToken(PagedExpandResponse payload) { - return payload.getNextPageToken(); - } - - @Override - public Iterable extractResources(PagedExpandResponse payload) { - return payload.getResponsesList() == null - ? ImmutableList.of() - : payload.getResponsesList(); - } - }; - - private static final PagedListDescriptor - SIMPLE_PAGED_EXPAND_PAGE_STR_DESC = - new PagedListDescriptor() { - @Override - public String emptyToken() { - return ""; - } - - @Override - public PagedExpandRequest injectToken(PagedExpandRequest payload, String token) { - return PagedExpandRequest.newBuilder(payload).setPageToken(token).build(); - } - - @Override - public PagedExpandRequest injectPageSize(PagedExpandRequest payload, int pageSize) { - return PagedExpandRequest.newBuilder(payload).setPageSize(pageSize).build(); - } - - @Override - public Integer extractPageSize(PagedExpandRequest payload) { - return payload.getPageSize(); - } - - @Override - public String extractNextToken(PagedExpandResponse payload) { - return payload.getNextPageToken(); - } - - @Override - public Iterable extractResources(PagedExpandResponse payload) { - return payload.getResponsesList() == null - ? ImmutableList.of() - : payload.getResponsesList(); - } - }; - - private static final PagedListResponseFactory< - PagedExpandRequest, PagedExpandResponse, PagedExpandPagedResponse> - PAGED_EXPAND_PAGE_STR_FACT = - new PagedListResponseFactory< - PagedExpandRequest, PagedExpandResponse, PagedExpandPagedResponse>() { - @Override - public ApiFuture getFuturePagedResponse( - UnaryCallable callable, - PagedExpandRequest request, - ApiCallContext context, - ApiFuture futureResponse) { - PageContext pageContext = - PageContext.create(callable, PAGED_EXPAND_PAGE_STR_DESC, request, context); - return PagedExpandPagedResponse.createAsync(pageContext, futureResponse); - } - }; - - private static final PagedListResponseFactory< - PagedExpandRequest, PagedExpandResponse, SimplePagedExpandPagedResponse> - SIMPLE_PAGED_EXPAND_PAGE_STR_FACT = - new PagedListResponseFactory< - PagedExpandRequest, PagedExpandResponse, SimplePagedExpandPagedResponse>() { - @Override - public ApiFuture getFuturePagedResponse( - UnaryCallable callable, - PagedExpandRequest request, - ApiCallContext context, - ApiFuture futureResponse) { - PageContext pageContext = - PageContext.create(callable, SIMPLE_PAGED_EXPAND_PAGE_STR_DESC, request, context); - return SimplePagedExpandPagedResponse.createAsync(pageContext, futureResponse); - } - }; - - /** Returns the object with the settings used for calls to echo. */ - public UnaryCallSettings echoSettings() { - return echoSettings; - } - - /** Returns the object with the settings used for calls to expand. */ - public ServerStreamingCallSettings expandSettings() { - return expandSettings; - } - - /** Returns the object with the settings used for calls to collect. */ - public StreamingCallSettings collectSettings() { - return collectSettings; - } - - /** Returns the object with the settings used for calls to chat. */ - public StreamingCallSettings chatSettings() { - return chatSettings; + ImmutableList.builder().build(); + + private final UnaryCallSettings repeatDataBodySettings; + private final UnaryCallSettings repeatDataBodyInfoSettings; + private final UnaryCallSettings repeatDataQuerySettings; + private final UnaryCallSettings repeatDataSimplePathSettings; + private final UnaryCallSettings repeatDataPathResourceSettings; + private final UnaryCallSettings + repeatDataPathTrailingResourceSettings; + + /** Returns the object with the settings used for calls to repeatDataBody. */ + public UnaryCallSettings repeatDataBodySettings() { + return repeatDataBodySettings; } - /** Returns the object with the settings used for calls to chatAgain. */ - public StreamingCallSettings chatAgainSettings() { - return chatAgainSettings; + /** Returns the object with the settings used for calls to repeatDataBodyInfo. */ + public UnaryCallSettings repeatDataBodyInfoSettings() { + return repeatDataBodyInfoSettings; } - /** Returns the object with the settings used for calls to pagedExpand. */ - public PagedCallSettings - pagedExpandSettings() { - return pagedExpandSettings; + /** Returns the object with the settings used for calls to repeatDataQuery. */ + public UnaryCallSettings repeatDataQuerySettings() { + return repeatDataQuerySettings; } - /** Returns the object with the settings used for calls to simplePagedExpand. */ - public PagedCallSettings - simplePagedExpandSettings() { - return simplePagedExpandSettings; + /** Returns the object with the settings used for calls to repeatDataSimplePath. */ + public UnaryCallSettings repeatDataSimplePathSettings() { + return repeatDataSimplePathSettings; } - /** Returns the object with the settings used for calls to wait. */ - public UnaryCallSettings waitSettings() { - return waitSettings; + /** Returns the object with the settings used for calls to repeatDataPathResource. */ + public UnaryCallSettings repeatDataPathResourceSettings() { + return repeatDataPathResourceSettings; } - /** Returns the object with the settings used for calls to wait. */ - public OperationCallSettings waitOperationSettings() { - return waitOperationSettings; - } - - /** Returns the object with the settings used for calls to block. */ - public UnaryCallSettings blockSettings() { - return blockSettings; - } - - /** Returns the object with the settings used for calls to collideName. */ - public UnaryCallSettings collideNameSettings() { - return collideNameSettings; + /** Returns the object with the settings used for calls to repeatDataPathTrailingResource. */ + public UnaryCallSettings repeatDataPathTrailingResourceSettings() { + return repeatDataPathTrailingResourceSettings; } @BetaApi("A restructuring of stub classes is planned, so this may break in the future") - public EchoStub createStub() throws IOException { + public ComplianceStub createStub() throws IOException { if (getTransportChannelProvider() .getTransportName() .equals(HttpJsonTransportChannel.getHttpJsonTransportName())) { - return HttpJsonEchoStub.create(this); + return HttpJsonComplianceStub.create(this); } throw new UnsupportedOperationException( String.format( @@ -319,7 +151,8 @@ public class EchoStubSettings extends StubSettings { @BetaApi("The surface for customizing headers is not stable yet and may change in the future.") public static ApiClientHeaderProvider.Builder defaultApiClientHeaderProviderBuilder() { return ApiClientHeaderProvider.newBuilder() - .setGeneratedLibToken("gapic", GaxProperties.getLibraryVersion(EchoStubSettings.class)) + .setGeneratedLibToken( + "gapic", GaxProperties.getLibraryVersion(ComplianceStubSettings.class)) .setTransportToken( GaxHttpJsonProperties.getHttpJsonTokenName(), GaxHttpJsonProperties.getHttpJsonVersion()); @@ -340,54 +173,38 @@ public class EchoStubSettings extends StubSettings { return new Builder(this); } - protected EchoStubSettings(Builder settingsBuilder) throws IOException { + protected ComplianceStubSettings(Builder settingsBuilder) throws IOException { super(settingsBuilder); - echoSettings = settingsBuilder.echoSettings().build(); - expandSettings = settingsBuilder.expandSettings().build(); - collectSettings = settingsBuilder.collectSettings().build(); - chatSettings = settingsBuilder.chatSettings().build(); - chatAgainSettings = settingsBuilder.chatAgainSettings().build(); - pagedExpandSettings = settingsBuilder.pagedExpandSettings().build(); - simplePagedExpandSettings = settingsBuilder.simplePagedExpandSettings().build(); - waitSettings = settingsBuilder.waitSettings().build(); - waitOperationSettings = settingsBuilder.waitOperationSettings().build(); - blockSettings = settingsBuilder.blockSettings().build(); - collideNameSettings = settingsBuilder.collideNameSettings().build(); + repeatDataBodySettings = settingsBuilder.repeatDataBodySettings().build(); + repeatDataBodyInfoSettings = settingsBuilder.repeatDataBodyInfoSettings().build(); + repeatDataQuerySettings = settingsBuilder.repeatDataQuerySettings().build(); + repeatDataSimplePathSettings = settingsBuilder.repeatDataSimplePathSettings().build(); + repeatDataPathResourceSettings = settingsBuilder.repeatDataPathResourceSettings().build(); + repeatDataPathTrailingResourceSettings = + settingsBuilder.repeatDataPathTrailingResourceSettings().build(); } - /** Builder for EchoStubSettings. */ - public static class Builder extends StubSettings.Builder { + /** Builder for ComplianceStubSettings. */ + public static class Builder extends StubSettings.Builder { private final ImmutableList> unaryMethodSettingsBuilders; - private final UnaryCallSettings.Builder echoSettings; - private final ServerStreamingCallSettings.Builder expandSettings; - private final StreamingCallSettings.Builder collectSettings; - private final StreamingCallSettings.Builder chatSettings; - private final StreamingCallSettings.Builder chatAgainSettings; - private final PagedCallSettings.Builder< - PagedExpandRequest, PagedExpandResponse, PagedExpandPagedResponse> - pagedExpandSettings; - private final PagedCallSettings.Builder< - PagedExpandRequest, PagedExpandResponse, SimplePagedExpandPagedResponse> - simplePagedExpandSettings; - private final UnaryCallSettings.Builder waitSettings; - private final OperationCallSettings.Builder - waitOperationSettings; - private final UnaryCallSettings.Builder blockSettings; - private final UnaryCallSettings.Builder collideNameSettings; + private final UnaryCallSettings.Builder repeatDataBodySettings; + private final UnaryCallSettings.Builder + repeatDataBodyInfoSettings; + private final UnaryCallSettings.Builder repeatDataQuerySettings; + private final UnaryCallSettings.Builder + repeatDataSimplePathSettings; + private final UnaryCallSettings.Builder + repeatDataPathResourceSettings; + private final UnaryCallSettings.Builder + repeatDataPathTrailingResourceSettings; private static final ImmutableMap> RETRYABLE_CODE_DEFINITIONS; static { ImmutableMap.Builder> definitions = ImmutableMap.builder(); - definitions.put( - "retry_policy_1_codes", - ImmutableSet.copyOf( - Lists.newArrayList( - StatusCode.Code.UNAVAILABLE, StatusCode.Code.UNKNOWN))); - definitions.put( - "no_retry_0_codes", ImmutableSet.copyOf(Lists.newArrayList())); + definitions.put("no_retry_codes", ImmutableSet.copyOf(Lists.newArrayList())); RETRYABLE_CODE_DEFINITIONS = definitions.build(); } @@ -396,25 +213,8 @@ public class EchoStubSettings extends StubSettings { static { ImmutableMap.Builder definitions = ImmutableMap.builder(); RetrySettings settings = null; - settings = - RetrySettings.newBuilder() - .setInitialRetryDelay(Duration.ofMillis(100L)) - .setRetryDelayMultiplier(2.0) - .setMaxRetryDelay(Duration.ofMillis(3000L)) - .setInitialRpcTimeout(Duration.ofMillis(10000L)) - .setRpcTimeoutMultiplier(1.0) - .setMaxRpcTimeout(Duration.ofMillis(10000L)) - .setTotalTimeout(Duration.ofMillis(10000L)) - .build(); - definitions.put("retry_policy_1_params", settings); - settings = - RetrySettings.newBuilder() - .setInitialRpcTimeout(Duration.ofMillis(5000L)) - .setRpcTimeoutMultiplier(1.0) - .setMaxRpcTimeout(Duration.ofMillis(5000L)) - .setTotalTimeout(Duration.ofMillis(5000L)) - .build(); - definitions.put("no_retry_0_params", settings); + settings = RetrySettings.newBuilder().setRpcTimeoutMultiplier(1.0).build(); + definitions.put("no_retry_params", settings); RETRY_PARAM_DEFINITIONS = definitions.build(); } @@ -425,52 +225,43 @@ public class EchoStubSettings extends StubSettings { protected Builder(ClientContext clientContext) { super(clientContext); - echoSettings = UnaryCallSettings.newUnaryCallSettingsBuilder(); - expandSettings = ServerStreamingCallSettings.newBuilder(); - collectSettings = StreamingCallSettings.newBuilder(); - chatSettings = StreamingCallSettings.newBuilder(); - chatAgainSettings = StreamingCallSettings.newBuilder(); - pagedExpandSettings = PagedCallSettings.newBuilder(PAGED_EXPAND_PAGE_STR_FACT); - simplePagedExpandSettings = PagedCallSettings.newBuilder(SIMPLE_PAGED_EXPAND_PAGE_STR_FACT); - waitSettings = UnaryCallSettings.newUnaryCallSettingsBuilder(); - waitOperationSettings = OperationCallSettings.newBuilder(); - blockSettings = UnaryCallSettings.newUnaryCallSettingsBuilder(); - collideNameSettings = UnaryCallSettings.newUnaryCallSettingsBuilder(); + repeatDataBodySettings = UnaryCallSettings.newUnaryCallSettingsBuilder(); + repeatDataBodyInfoSettings = UnaryCallSettings.newUnaryCallSettingsBuilder(); + repeatDataQuerySettings = UnaryCallSettings.newUnaryCallSettingsBuilder(); + repeatDataSimplePathSettings = UnaryCallSettings.newUnaryCallSettingsBuilder(); + repeatDataPathResourceSettings = UnaryCallSettings.newUnaryCallSettingsBuilder(); + repeatDataPathTrailingResourceSettings = UnaryCallSettings.newUnaryCallSettingsBuilder(); unaryMethodSettingsBuilders = ImmutableList.>of( - echoSettings, - pagedExpandSettings, - simplePagedExpandSettings, - waitSettings, - blockSettings, - collideNameSettings); + repeatDataBodySettings, + repeatDataBodyInfoSettings, + repeatDataQuerySettings, + repeatDataSimplePathSettings, + repeatDataPathResourceSettings, + repeatDataPathTrailingResourceSettings); initDefaults(this); } - protected Builder(EchoStubSettings settings) { + protected Builder(ComplianceStubSettings settings) { super(settings); - echoSettings = settings.echoSettings.toBuilder(); - expandSettings = settings.expandSettings.toBuilder(); - collectSettings = settings.collectSettings.toBuilder(); - chatSettings = settings.chatSettings.toBuilder(); - chatAgainSettings = settings.chatAgainSettings.toBuilder(); - pagedExpandSettings = settings.pagedExpandSettings.toBuilder(); - simplePagedExpandSettings = settings.simplePagedExpandSettings.toBuilder(); - waitSettings = settings.waitSettings.toBuilder(); - waitOperationSettings = settings.waitOperationSettings.toBuilder(); - blockSettings = settings.blockSettings.toBuilder(); - collideNameSettings = settings.collideNameSettings.toBuilder(); + repeatDataBodySettings = settings.repeatDataBodySettings.toBuilder(); + repeatDataBodyInfoSettings = settings.repeatDataBodyInfoSettings.toBuilder(); + repeatDataQuerySettings = settings.repeatDataQuerySettings.toBuilder(); + repeatDataSimplePathSettings = settings.repeatDataSimplePathSettings.toBuilder(); + repeatDataPathResourceSettings = settings.repeatDataPathResourceSettings.toBuilder(); + repeatDataPathTrailingResourceSettings = + settings.repeatDataPathTrailingResourceSettings.toBuilder(); unaryMethodSettingsBuilders = ImmutableList.>of( - echoSettings, - pagedExpandSettings, - simplePagedExpandSettings, - waitSettings, - blockSettings, - collideNameSettings); + repeatDataBodySettings, + repeatDataBodyInfoSettings, + repeatDataQuerySettings, + repeatDataSimplePathSettings, + repeatDataPathResourceSettings, + repeatDataPathTrailingResourceSettings); } private static Builder createDefault() { @@ -488,62 +279,34 @@ public class EchoStubSettings extends StubSettings { private static Builder initDefaults(Builder builder) { builder - .echoSettings() - .setRetryableCodes(RETRYABLE_CODE_DEFINITIONS.get("retry_policy_1_codes")) - .setRetrySettings(RETRY_PARAM_DEFINITIONS.get("retry_policy_1_params")); - - builder - .expandSettings() - .setRetryableCodes(RETRYABLE_CODE_DEFINITIONS.get("retry_policy_1_codes")) - .setRetrySettings(RETRY_PARAM_DEFINITIONS.get("retry_policy_1_params")); + .repeatDataBodySettings() + .setRetryableCodes(RETRYABLE_CODE_DEFINITIONS.get("no_retry_codes")) + .setRetrySettings(RETRY_PARAM_DEFINITIONS.get("no_retry_params")); builder - .pagedExpandSettings() - .setRetryableCodes(RETRYABLE_CODE_DEFINITIONS.get("retry_policy_1_codes")) - .setRetrySettings(RETRY_PARAM_DEFINITIONS.get("retry_policy_1_params")); + .repeatDataBodyInfoSettings() + .setRetryableCodes(RETRYABLE_CODE_DEFINITIONS.get("no_retry_codes")) + .setRetrySettings(RETRY_PARAM_DEFINITIONS.get("no_retry_params")); builder - .simplePagedExpandSettings() - .setRetryableCodes(RETRYABLE_CODE_DEFINITIONS.get("no_retry_0_codes")) - .setRetrySettings(RETRY_PARAM_DEFINITIONS.get("no_retry_0_params")); + .repeatDataQuerySettings() + .setRetryableCodes(RETRYABLE_CODE_DEFINITIONS.get("no_retry_codes")) + .setRetrySettings(RETRY_PARAM_DEFINITIONS.get("no_retry_params")); builder - .waitSettings() - .setRetryableCodes(RETRYABLE_CODE_DEFINITIONS.get("no_retry_0_codes")) - .setRetrySettings(RETRY_PARAM_DEFINITIONS.get("no_retry_0_params")); + .repeatDataSimplePathSettings() + .setRetryableCodes(RETRYABLE_CODE_DEFINITIONS.get("no_retry_codes")) + .setRetrySettings(RETRY_PARAM_DEFINITIONS.get("no_retry_params")); builder - .blockSettings() - .setRetryableCodes(RETRYABLE_CODE_DEFINITIONS.get("no_retry_0_codes")) - .setRetrySettings(RETRY_PARAM_DEFINITIONS.get("no_retry_0_params")); + .repeatDataPathResourceSettings() + .setRetryableCodes(RETRYABLE_CODE_DEFINITIONS.get("no_retry_codes")) + .setRetrySettings(RETRY_PARAM_DEFINITIONS.get("no_retry_params")); builder - .collideNameSettings() - .setRetryableCodes(RETRYABLE_CODE_DEFINITIONS.get("no_retry_0_codes")) - .setRetrySettings(RETRY_PARAM_DEFINITIONS.get("no_retry_0_params")); - - builder - .waitOperationSettings() - .setInitialCallSettings( - UnaryCallSettings.newUnaryCallSettingsBuilder() - .setRetryableCodes(RETRYABLE_CODE_DEFINITIONS.get("no_retry_0_codes")) - .setRetrySettings(RETRY_PARAM_DEFINITIONS.get("no_retry_0_params")) - .build()) - .setResponseTransformer( - ProtoOperationTransformers.ResponseTransformer.create(WaitResponse.class)) - .setMetadataTransformer( - ProtoOperationTransformers.MetadataTransformer.create(WaitMetadata.class)) - .setPollingAlgorithm( - OperationTimedPollAlgorithm.create( - RetrySettings.newBuilder() - .setInitialRetryDelay(Duration.ofMillis(5000L)) - .setRetryDelayMultiplier(1.5) - .setMaxRetryDelay(Duration.ofMillis(45000L)) - .setInitialRpcTimeout(Duration.ZERO) - .setRpcTimeoutMultiplier(1.0) - .setMaxRpcTimeout(Duration.ZERO) - .setTotalTimeout(Duration.ofMillis(300000L)) - .build())); + .repeatDataPathTrailingResourceSettings() + .setRetryableCodes(RETRYABLE_CODE_DEFINITIONS.get("no_retry_codes")) + .setRetrySettings(RETRY_PARAM_DEFINITIONS.get("no_retry_params")); return builder; } @@ -563,71 +326,41 @@ public class EchoStubSettings extends StubSettings { return unaryMethodSettingsBuilders; } - /** Returns the builder for the settings used for calls to echo. */ - public UnaryCallSettings.Builder echoSettings() { - return echoSettings; - } - - /** Returns the builder for the settings used for calls to expand. */ - public ServerStreamingCallSettings.Builder expandSettings() { - return expandSettings; - } - - /** Returns the builder for the settings used for calls to collect. */ - public StreamingCallSettings.Builder collectSettings() { - return collectSettings; - } - - /** Returns the builder for the settings used for calls to chat. */ - public StreamingCallSettings.Builder chatSettings() { - return chatSettings; - } - - /** Returns the builder for the settings used for calls to chatAgain. */ - public StreamingCallSettings.Builder chatAgainSettings() { - return chatAgainSettings; - } - - /** Returns the builder for the settings used for calls to pagedExpand. */ - public PagedCallSettings.Builder< - PagedExpandRequest, PagedExpandResponse, PagedExpandPagedResponse> - pagedExpandSettings() { - return pagedExpandSettings; + /** Returns the builder for the settings used for calls to repeatDataBody. */ + public UnaryCallSettings.Builder repeatDataBodySettings() { + return repeatDataBodySettings; } - /** Returns the builder for the settings used for calls to simplePagedExpand. */ - public PagedCallSettings.Builder< - PagedExpandRequest, PagedExpandResponse, SimplePagedExpandPagedResponse> - simplePagedExpandSettings() { - return simplePagedExpandSettings; + /** Returns the builder for the settings used for calls to repeatDataBodyInfo. */ + public UnaryCallSettings.Builder repeatDataBodyInfoSettings() { + return repeatDataBodyInfoSettings; } - /** Returns the builder for the settings used for calls to wait. */ - public UnaryCallSettings.Builder waitSettings() { - return waitSettings; + /** Returns the builder for the settings used for calls to repeatDataQuery. */ + public UnaryCallSettings.Builder repeatDataQuerySettings() { + return repeatDataQuerySettings; } - /** Returns the builder for the settings used for calls to wait. */ - @BetaApi( - "The surface for use by generated code is not stable yet and may change in the future.") - public OperationCallSettings.Builder - waitOperationSettings() { - return waitOperationSettings; + /** Returns the builder for the settings used for calls to repeatDataSimplePath. */ + public UnaryCallSettings.Builder repeatDataSimplePathSettings() { + return repeatDataSimplePathSettings; } - /** Returns the builder for the settings used for calls to block. */ - public UnaryCallSettings.Builder blockSettings() { - return blockSettings; + /** Returns the builder for the settings used for calls to repeatDataPathResource. */ + public UnaryCallSettings.Builder + repeatDataPathResourceSettings() { + return repeatDataPathResourceSettings; } - /** Returns the builder for the settings used for calls to collideName. */ - public UnaryCallSettings.Builder collideNameSettings() { - return collideNameSettings; + /** Returns the builder for the settings used for calls to repeatDataPathTrailingResource. */ + public UnaryCallSettings.Builder + repeatDataPathTrailingResourceSettings() { + return repeatDataPathTrailingResourceSettings; } @Override - public EchoStubSettings build() throws IOException { - return new EchoStubSettings(this); + public ComplianceStubSettings build() throws IOException { + return new ComplianceStubSettings(this); } } } diff --git a/src/test/java/com/google/api/generator/gapic/composer/rest/goldens/HttpJsonComplianceCallableFactory.golden b/src/test/java/com/google/api/generator/gapic/composer/rest/goldens/HttpJsonComplianceCallableFactory.golden index 8db61290e0..ab84437e6e 100644 --- a/src/test/java/com/google/api/generator/gapic/composer/rest/goldens/HttpJsonComplianceCallableFactory.golden +++ b/src/test/java/com/google/api/generator/gapic/composer/rest/goldens/HttpJsonComplianceCallableFactory.golden @@ -4,7 +4,6 @@ import com.google.api.core.BetaApi; import com.google.api.gax.core.BackgroundResource; import com.google.api.gax.httpjson.HttpJsonCallSettings; import com.google.api.gax.httpjson.HttpJsonCallableFactory; -import com.google.api.gax.httpjson.HttpJsonOperationSnapshotCallable; import com.google.api.gax.httpjson.HttpJsonStubCallableFactory; import com.google.api.gax.rpc.BatchingCallSettings; import com.google.api.gax.rpc.ClientContext; @@ -13,7 +12,6 @@ import com.google.api.gax.rpc.OperationCallable; import com.google.api.gax.rpc.PagedCallSettings; import com.google.api.gax.rpc.UnaryCallSettings; import com.google.api.gax.rpc.UnaryCallable; -import com.google.longrunning.Operation; import javax.annotation.Generated; // AUTO-GENERATED DOCUMENTATION AND CLASS. @@ -25,7 +23,7 @@ import javax.annotation.Generated; @BetaApi @Generated("by gapic-generator-java") public class HttpJsonComplianceCallableFactory - implements HttpJsonStubCallableFactory { + implements HttpJsonStubCallableFactory { @Override public UnaryCallable createUnaryCallable( @@ -60,18 +58,10 @@ public class HttpJsonComplianceCallableFactory @Override public OperationCallable createOperationCallable( - HttpJsonCallSettings httpJsonCallSettings, + HttpJsonCallSettings httpJsonCallSettings, OperationCallSettings callSettings, ClientContext clientContext, BackgroundResource operationsStub) { - UnaryCallable innerCallable = - HttpJsonCallableFactory.createBaseUnaryCallable( - httpJsonCallSettings, callSettings.getInitialCallSettings(), clientContext); - HttpJsonOperationSnapshotCallable initialCallable = - new HttpJsonOperationSnapshotCallable( - innerCallable, - httpJsonCallSettings.getMethodDescriptor().getOperationSnapshotFactory()); - return HttpJsonCallableFactory.createOperationCallable( - callSettings, clientContext, operationsStub.longRunningClient(), initialCallable); + return null; } } diff --git a/src/test/java/com/google/api/generator/gapic/composer/rest/goldens/HttpJsonComplianceStub.golden b/src/test/java/com/google/api/generator/gapic/composer/rest/goldens/HttpJsonComplianceStub.golden index 5324f21655..331e5bf961 100644 --- a/src/test/java/com/google/api/generator/gapic/composer/rest/goldens/HttpJsonComplianceStub.golden +++ b/src/test/java/com/google/api/generator/gapic/composer/rest/goldens/HttpJsonComplianceStub.golden @@ -57,8 +57,7 @@ public class HttpJsonComplianceStub extends ComplianceStub { }) .setRequestBodyExtractor( request -> - ProtoRestSerializer.create() - .toBody("serverVerify", request.getServerVerify())) + ProtoRestSerializer.create().toBody("*", request.toBuilder().build())) .build()) .setResponseParser( ProtoMessageResponseParser.newBuilder() diff --git a/test/integration/goldens/compute/com/google/cloud/compute/v1/AddressesClient.java b/test/integration/goldens/compute/com/google/cloud/compute/v1/AddressesClient.java index 7173f3bce5..f9039b41df 100644 --- a/test/integration/goldens/compute/com/google/cloud/compute/v1/AddressesClient.java +++ b/test/integration/goldens/compute/com/google/cloud/compute/v1/AddressesClient.java @@ -329,6 +329,8 @@ public final OperationFuture deleteAsync( * @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 */ + @BetaApi( + "The surface for long-running operations is not stable yet and may change in the future.") public final OperationFuture deleteAsync(DeleteAddressRequest request) { return deleteOperationCallable().futureCall(request); } @@ -438,6 +440,8 @@ public final OperationFuture insertAsync( * @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 */ + @BetaApi( + "The surface for long-running operations is not stable yet and may change in the future.") public final OperationFuture insertAsync(InsertAddressRequest request) { return insertOperationCallable().futureCall(request); } diff --git a/test/integration/goldens/compute/com/google/cloud/compute/v1/RegionOperationsClient.java b/test/integration/goldens/compute/com/google/cloud/compute/v1/RegionOperationsClient.java index fb6a5e296d..09fb0b090a 100644 --- a/test/integration/goldens/compute/com/google/cloud/compute/v1/RegionOperationsClient.java +++ b/test/integration/goldens/compute/com/google/cloud/compute/v1/RegionOperationsClient.java @@ -222,6 +222,112 @@ public final UnaryCallable getCallable() { return stub.getCallable(); } + // AUTO-GENERATED DOCUMENTATION AND METHOD. + /** + * Waits for the specified Operation resource to return as `DONE` or for the request to approach + * the 2 minute deadline, and retrieves the specified Operation resource. This method differs from + * the `GET` method in that it waits for no more than the default deadline (2 minutes) and then + * returns the current state of the operation, which might be `DONE` or still in progress. + * + *

    This method is called on a best-effort basis. Specifically: - In uncommon cases, when the + * server is overloaded, the request might return before the default deadline is reached, or might + * return after zero seconds. - If the default deadline is reached, there is no guarantee that the + * operation is actually done when the method returns. Be prepared to retry if the operation is + * not `DONE`. + * + *

    Sample code: + * + *

    {@code
    +   * try (RegionOperationsClient regionOperationsClient = RegionOperationsClient.create()) {
    +   *   String project = "project-309310695";
    +   *   String region = "region-934795532";
    +   *   String operation = "operation1662702951";
    +   *   Operation response = regionOperationsClient.wait(project, region, operation);
    +   * }
    +   * }
    + * + * @param project Project ID for this request. + * @param region Name of the region for this request. + * @param operation Name of the Operations resource to return. + * @throws com.google.api.gax.rpc.ApiException if the remote call fails + */ + public final Operation wait(String project, String region, String operation) { + WaitRegionOperationRequest request = + WaitRegionOperationRequest.newBuilder() + .setProject(project) + .setRegion(region) + .setOperation(operation) + .build(); + return wait(request); + } + + // AUTO-GENERATED DOCUMENTATION AND METHOD. + /** + * Waits for the specified Operation resource to return as `DONE` or for the request to approach + * the 2 minute deadline, and retrieves the specified Operation resource. This method differs from + * the `GET` method in that it waits for no more than the default deadline (2 minutes) and then + * returns the current state of the operation, which might be `DONE` or still in progress. + * + *

    This method is called on a best-effort basis. Specifically: - In uncommon cases, when the + * server is overloaded, the request might return before the default deadline is reached, or might + * return after zero seconds. - If the default deadline is reached, there is no guarantee that the + * operation is actually done when the method returns. Be prepared to retry if the operation is + * not `DONE`. + * + *

    Sample code: + * + *

    {@code
    +   * try (RegionOperationsClient regionOperationsClient = RegionOperationsClient.create()) {
    +   *   WaitRegionOperationRequest request =
    +   *       WaitRegionOperationRequest.newBuilder()
    +   *           .setOperation("operation1662702951")
    +   *           .setProject("project-309310695")
    +   *           .setRegion("region-934795532")
    +   *           .build();
    +   *   Operation response = regionOperationsClient.wait(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 Operation wait(WaitRegionOperationRequest request) { + return waitCallable().call(request); + } + + // AUTO-GENERATED DOCUMENTATION AND METHOD. + /** + * Waits for the specified Operation resource to return as `DONE` or for the request to approach + * the 2 minute deadline, and retrieves the specified Operation resource. This method differs from + * the `GET` method in that it waits for no more than the default deadline (2 minutes) and then + * returns the current state of the operation, which might be `DONE` or still in progress. + * + *

    This method is called on a best-effort basis. Specifically: - In uncommon cases, when the + * server is overloaded, the request might return before the default deadline is reached, or might + * return after zero seconds. - If the default deadline is reached, there is no guarantee that the + * operation is actually done when the method returns. Be prepared to retry if the operation is + * not `DONE`. + * + *

    Sample code: + * + *

    {@code
    +   * try (RegionOperationsClient regionOperationsClient = RegionOperationsClient.create()) {
    +   *   WaitRegionOperationRequest request =
    +   *       WaitRegionOperationRequest.newBuilder()
    +   *           .setOperation("operation1662702951")
    +   *           .setProject("project-309310695")
    +   *           .setRegion("region-934795532")
    +   *           .build();
    +   *   ApiFuture future = regionOperationsClient.waitCallable().futureCall(request);
    +   *   // Do something.
    +   *   Operation response = future.get();
    +   * }
    +   * }
    + */ + public final UnaryCallable waitCallable() { + return stub.waitCallable(); + } + @Override public final void close() { stub.close(); diff --git a/test/integration/goldens/compute/com/google/cloud/compute/v1/RegionOperationsClientTest.java b/test/integration/goldens/compute/com/google/cloud/compute/v1/RegionOperationsClientTest.java index d41b1f5191..684c1312ab 100644 --- a/test/integration/goldens/compute/com/google/cloud/compute/v1/RegionOperationsClientTest.java +++ b/test/integration/goldens/compute/com/google/cloud/compute/v1/RegionOperationsClientTest.java @@ -140,4 +140,73 @@ public void getExceptionTest() throws Exception { // Expected exception. } } + + @Test + public void waitTest() throws Exception { + Operation expectedResponse = + Operation.newBuilder() + .setClientOperationId("clientOperationId-1230366697") + .setCreationTimestamp("creationTimestamp-370203401") + .setDescription("description-1724546052") + .setEndTime("endTime-1607243192") + .setError(Error.newBuilder().build()) + .setHttpErrorMessage("httpErrorMessage1577303431") + .setHttpErrorStatusCode(1386087020) + .setId(3355) + .setInsertTime("insertTime966165798") + .setKind("kind3292052") + .setName("name3373707") + .setOperationType("operationType91999553") + .setProgress(-1001078227) + .setRegion("region-934795532") + .setSelfLink("selfLink1191800166") + .setStartTime("startTime-2129294769") + .setStatusMessage("statusMessage-958704715") + .setTargetId(-815576439) + .setTargetLink("targetLink486368555") + .setUser("user3599307") + .addAllWarnings(new ArrayList()) + .setZone("zone3744684") + .build(); + mockService.addResponse(expectedResponse); + + String project = "project-309310695"; + String region = "region-934795532"; + String operation = "operation1662702951"; + + Operation actualResponse = client.wait(project, region, operation); + Assert.assertEquals(expectedResponse, actualResponse); + + List actualRequests = mockService.getRequestPaths(); + Assert.assertEquals(1, actualRequests.size()); + + String apiClientHeaderKey = + mockService + .getRequestHeaders() + .get(ApiClientHeaderProvider.getDefaultApiClientHeaderKey()) + .iterator() + .next(); + Assert.assertTrue( + GaxHttpJsonProperties.getDefaultApiClientHeaderPattern() + .matcher(apiClientHeaderKey) + .matches()); + } + + @Test + public void waitExceptionTest() throws Exception { + ApiException exception = + ApiExceptionFactory.createException( + new Exception(), FakeStatusCode.of(StatusCode.Code.INVALID_ARGUMENT), false); + mockService.addException(exception); + + try { + String project = "project-309310695"; + String region = "region-934795532"; + String operation = "operation1662702951"; + client.wait(project, region, operation); + Assert.fail("No exception raised"); + } catch (InvalidArgumentException e) { + // Expected exception. + } + } } diff --git a/test/integration/goldens/compute/com/google/cloud/compute/v1/RegionOperationsSettings.java b/test/integration/goldens/compute/com/google/cloud/compute/v1/RegionOperationsSettings.java index 4e0ffca9d4..91cabed69d 100644 --- a/test/integration/goldens/compute/com/google/cloud/compute/v1/RegionOperationsSettings.java +++ b/test/integration/goldens/compute/com/google/cloud/compute/v1/RegionOperationsSettings.java @@ -72,6 +72,11 @@ public UnaryCallSettings getSettings() { return ((RegionOperationsStubSettings) getStubSettings()).getSettings(); } + /** Returns the object with the settings used for calls to wait. */ + public UnaryCallSettings waitSettings() { + return ((RegionOperationsStubSettings) getStubSettings()).waitSettings(); + } + public static final RegionOperationsSettings create(RegionOperationsStubSettings stub) throws IOException { return new RegionOperationsSettings.Builder(stub.toBuilder()).build(); @@ -175,6 +180,11 @@ public UnaryCallSettings.Builder getSettin return getStubSettingsBuilder().getSettings(); } + /** Returns the builder for the settings used for calls to wait. */ + public UnaryCallSettings.Builder waitSettings() { + return getStubSettingsBuilder().waitSettings(); + } + @Override public RegionOperationsSettings build() throws IOException { return new RegionOperationsSettings(this); diff --git a/test/integration/goldens/compute/com/google/cloud/compute/v1/gapic_metadata.json b/test/integration/goldens/compute/com/google/cloud/compute/v1/gapic_metadata.json index d2f2df6b3d..a56d0a2382 100644 --- a/test/integration/goldens/compute/com/google/cloud/compute/v1/gapic_metadata.json +++ b/test/integration/goldens/compute/com/google/cloud/compute/v1/gapic_metadata.json @@ -33,6 +33,9 @@ "rpcs": { "Get": { "methods": ["get", "get", "getCallable"] + }, + "Wait": { + "methods": ["wait", "wait", "waitCallable"] } } } diff --git a/test/integration/goldens/compute/com/google/cloud/compute/v1/stub/AddressesStub.java b/test/integration/goldens/compute/com/google/cloud/compute/v1/stub/AddressesStub.java index 551b0ec0eb..9ae394b7ca 100644 --- a/test/integration/goldens/compute/com/google/cloud/compute/v1/stub/AddressesStub.java +++ b/test/integration/goldens/compute/com/google/cloud/compute/v1/stub/AddressesStub.java @@ -40,10 +40,6 @@ @Generated("by gapic-generator-java") public abstract class AddressesStub implements BackgroundResource { - public RegionOperationsStub getOperationsStub() { - throw new UnsupportedOperationException("Not implemented: getOperationsStub()"); - } - public UnaryCallable aggregatedListPagedCallable() { throw new UnsupportedOperationException("Not implemented: aggregatedListPagedCallable()"); diff --git a/test/integration/goldens/compute/com/google/cloud/compute/v1/stub/AddressesStubSettings.java b/test/integration/goldens/compute/com/google/cloud/compute/v1/stub/AddressesStubSettings.java index 55866e3401..517743de7d 100644 --- a/test/integration/goldens/compute/com/google/cloud/compute/v1/stub/AddressesStubSettings.java +++ b/test/integration/goldens/compute/com/google/cloud/compute/v1/stub/AddressesStubSettings.java @@ -25,10 +25,10 @@ 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.ProtoOperationTransformers; 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.httpjson.ProtoOperationTransformers; import com.google.api.gax.longrunning.OperationSnapshot; import com.google.api.gax.longrunning.OperationTimedPollAlgorithm; import com.google.api.gax.retrying.RetrySettings; diff --git a/test/integration/goldens/compute/com/google/cloud/compute/v1/stub/HttpJsonAddressesStub.java b/test/integration/goldens/compute/com/google/cloud/compute/v1/stub/HttpJsonAddressesStub.java index 943580e59b..9e5e90fbe1 100644 --- a/test/integration/goldens/compute/com/google/cloud/compute/v1/stub/HttpJsonAddressesStub.java +++ b/test/integration/goldens/compute/com/google/cloud/compute/v1/stub/HttpJsonAddressesStub.java @@ -261,7 +261,7 @@ public class HttpJsonAddressesStub extends AddressesStub { private final UnaryCallable listPagedCallable; private final BackgroundResource backgroundResources; - private final HttpJsonRegionOperationsStub operationsStub; + private final HttpJsonRegionOperationsStub httpJsonOperationsStub; private final HttpJsonStubCallableFactory callableFactory; public static final HttpJsonAddressesStub create(AddressesStubSettings settings) @@ -300,7 +300,8 @@ protected HttpJsonAddressesStub( HttpJsonStubCallableFactory callableFactory) throws IOException { this.callableFactory = callableFactory; - this.operationsStub = HttpJsonRegionOperationsStub.create(clientContext, callableFactory); + this.httpJsonOperationsStub = + HttpJsonRegionOperationsStub.create(clientContext, callableFactory); HttpJsonCallSettings aggregatedListTransportSettings = @@ -334,7 +335,7 @@ protected HttpJsonAddressesStub( deleteTransportSettings, settings.deleteOperationSettings(), clientContext, - operationsStub); + httpJsonOperationsStub); this.insertCallable = callableFactory.createUnaryCallable( insertTransportSettings, settings.insertSettings(), clientContext); @@ -343,7 +344,7 @@ protected HttpJsonAddressesStub( insertTransportSettings, settings.insertOperationSettings(), clientContext, - operationsStub); + httpJsonOperationsStub); this.listCallable = callableFactory.createUnaryCallable( listTransportSettings, settings.listSettings(), clientContext); diff --git a/test/integration/goldens/compute/com/google/cloud/compute/v1/stub/HttpJsonRegionOperationsCallableFactory.java b/test/integration/goldens/compute/com/google/cloud/compute/v1/stub/HttpJsonRegionOperationsCallableFactory.java index b775dbba59..24e9ad539a 100644 --- a/test/integration/goldens/compute/com/google/cloud/compute/v1/stub/HttpJsonRegionOperationsCallableFactory.java +++ b/test/integration/goldens/compute/com/google/cloud/compute/v1/stub/HttpJsonRegionOperationsCallableFactory.java @@ -20,7 +20,6 @@ import com.google.api.gax.core.BackgroundResource; import com.google.api.gax.httpjson.HttpJsonCallSettings; import com.google.api.gax.httpjson.HttpJsonCallableFactory; -import com.google.api.gax.httpjson.HttpJsonOperationSnapshotCallable; import com.google.api.gax.httpjson.HttpJsonStubCallableFactory; import com.google.api.gax.rpc.BatchingCallSettings; import com.google.api.gax.rpc.ClientContext; @@ -29,7 +28,6 @@ import com.google.api.gax.rpc.PagedCallSettings; import com.google.api.gax.rpc.UnaryCallSettings; import com.google.api.gax.rpc.UnaryCallable; -import com.google.longrunning.Operation; import javax.annotation.Generated; // AUTO-GENERATED DOCUMENTATION AND CLASS. @@ -41,7 +39,7 @@ @Generated("by gapic-generator-java") @BetaApi public class HttpJsonRegionOperationsCallableFactory - implements HttpJsonStubCallableFactory { + implements HttpJsonStubCallableFactory { @Override public UnaryCallable createUnaryCallable( @@ -76,18 +74,10 @@ public UnaryCallable createBatchingCa @Override public OperationCallable createOperationCallable( - HttpJsonCallSettings httpJsonCallSettings, + HttpJsonCallSettings httpJsonCallSettings, OperationCallSettings callSettings, ClientContext clientContext, BackgroundResource operationsStub) { - UnaryCallable innerCallable = - HttpJsonCallableFactory.createBaseUnaryCallable( - httpJsonCallSettings, callSettings.getInitialCallSettings(), clientContext); - HttpJsonOperationSnapshotCallable initialCallable = - new HttpJsonOperationSnapshotCallable( - innerCallable, - httpJsonCallSettings.getMethodDescriptor().getOperationSnapshotFactory()); - return HttpJsonCallableFactory.createOperationCallable( - callSettings, clientContext, operationsStub.longRunningClient(), initialCallable); + return null; } } diff --git a/test/integration/goldens/compute/com/google/cloud/compute/v1/stub/HttpJsonRegionOperationsStub.java b/test/integration/goldens/compute/com/google/cloud/compute/v1/stub/HttpJsonRegionOperationsStub.java index 1949dd2c60..c167489173 100644 --- a/test/integration/goldens/compute/com/google/cloud/compute/v1/stub/HttpJsonRegionOperationsStub.java +++ b/test/integration/goldens/compute/com/google/cloud/compute/v1/stub/HttpJsonRegionOperationsStub.java @@ -36,6 +36,7 @@ import com.google.cloud.compute.v1.GetRegionOperationRequest; import com.google.cloud.compute.v1.Operation; import com.google.cloud.compute.v1.Operation.Status; +import com.google.cloud.compute.v1.WaitRegionOperationRequest; import java.io.IOException; import java.util.ArrayList; import java.util.Arrays; @@ -107,7 +108,41 @@ public class HttpJsonRegionOperationsStub extends RegionOperationsStub { }) .build(); + private static final ApiMethodDescriptor + waitMethodDescriptor = + ApiMethodDescriptor.newBuilder() + .setFullMethodName("google.cloud.compute.v1.RegionOperations/Wait") + .setHttpMethod(HttpMethods.POST) + .setRequestFormatter( + ProtoMessageRequestFormatter.newBuilder() + .setPath( + "/compute/v1/projects/projects/{project}/regions/{region}/operations/{operation}/wait", + request -> { + Map fields = new HashMap<>(); + ProtoRestSerializer serializer = + ProtoRestSerializer.create(); + serializer.putPathParam(fields, "operation", request.getOperation()); + serializer.putPathParam(fields, "project", request.getProject()); + serializer.putPathParam(fields, "region", request.getRegion()); + return fields; + }) + .setQueryParamsExtractor( + request -> { + Map> fields = new HashMap<>(); + ProtoRestSerializer serializer = + ProtoRestSerializer.create(); + return fields; + }) + .setRequestBodyExtractor(request -> null) + .build()) + .setResponseParser( + ProtoMessageResponseParser.newBuilder() + .setDefaultInstance(Operation.getDefaultInstance()) + .build()) + .build(); + private final UnaryCallable getCallable; + private final UnaryCallable waitCallable; private final BackgroundResource backgroundResources; private final LongRunningClient longRunningClient; @@ -156,10 +191,17 @@ protected HttpJsonRegionOperationsStub( HttpJsonCallSettings.newBuilder() .setMethodDescriptor(getMethodDescriptor) .build(); + HttpJsonCallSettings waitTransportSettings = + HttpJsonCallSettings.newBuilder() + .setMethodDescriptor(waitMethodDescriptor) + .build(); this.getCallable = callableFactory.createUnaryCallable( getTransportSettings, settings.getSettings(), clientContext); + this.waitCallable = + callableFactory.createUnaryCallable( + waitTransportSettings, settings.waitSettings(), clientContext); this.longRunningClient = new HttpJsonLongRunningClient( @@ -174,6 +216,7 @@ protected HttpJsonRegionOperationsStub( public static List getMethodDescriptors() { List methodDescriptors = new ArrayList<>(); methodDescriptors.add(getMethodDescriptor); + methodDescriptors.add(waitMethodDescriptor); return methodDescriptors; } @@ -182,6 +225,11 @@ public UnaryCallable getCallable() { return getCallable; } + @Override + public UnaryCallable waitCallable() { + return waitCallable; + } + @Override public LongRunningClient longRunningClient() { return longRunningClient; diff --git a/test/integration/goldens/compute/com/google/cloud/compute/v1/stub/RegionOperationsStub.java b/test/integration/goldens/compute/com/google/cloud/compute/v1/stub/RegionOperationsStub.java index c3019038cb..2d40fa610a 100644 --- a/test/integration/goldens/compute/com/google/cloud/compute/v1/stub/RegionOperationsStub.java +++ b/test/integration/goldens/compute/com/google/cloud/compute/v1/stub/RegionOperationsStub.java @@ -16,10 +16,13 @@ package com.google.cloud.compute.v1.stub; +import com.google.api.core.BetaApi; import com.google.api.gax.core.BackgroundResource; +import com.google.api.gax.rpc.LongRunningClient; import com.google.api.gax.rpc.UnaryCallable; import com.google.cloud.compute.v1.GetRegionOperationRequest; import com.google.cloud.compute.v1.Operation; +import com.google.cloud.compute.v1.WaitRegionOperationRequest; import javax.annotation.Generated; // AUTO-GENERATED DOCUMENTATION AND CLASS. @@ -31,10 +34,19 @@ @Generated("by gapic-generator-java") public abstract class RegionOperationsStub implements BackgroundResource { + @BetaApi + public LongRunningClient longRunningClient() { + throw new UnsupportedOperationException("Not implemented: longRunningClient()"); + } + public UnaryCallable getCallable() { throw new UnsupportedOperationException("Not implemented: getCallable()"); } + public UnaryCallable waitCallable() { + throw new UnsupportedOperationException("Not implemented: waitCallable()"); + } + @Override public abstract void close(); } diff --git a/test/integration/goldens/compute/com/google/cloud/compute/v1/stub/RegionOperationsStubSettings.java b/test/integration/goldens/compute/com/google/cloud/compute/v1/stub/RegionOperationsStubSettings.java index ebcf98e4f7..3c57601386 100644 --- a/test/integration/goldens/compute/com/google/cloud/compute/v1/stub/RegionOperationsStubSettings.java +++ b/test/integration/goldens/compute/com/google/cloud/compute/v1/stub/RegionOperationsStubSettings.java @@ -33,6 +33,7 @@ import com.google.api.gax.rpc.UnaryCallSettings; import com.google.cloud.compute.v1.GetRegionOperationRequest; import com.google.cloud.compute.v1.Operation; +import com.google.cloud.compute.v1.WaitRegionOperationRequest; import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableMap; import com.google.common.collect.ImmutableSet; @@ -85,12 +86,18 @@ public class RegionOperationsStubSettings extends StubSettings getSettings; + private final UnaryCallSettings waitSettings; /** Returns the object with the settings used for calls to get. */ public UnaryCallSettings getSettings() { return getSettings; } + /** Returns the object with the settings used for calls to wait. */ + public UnaryCallSettings waitSettings() { + return waitSettings; + } + @BetaApi("A restructuring of stub classes is planned, so this may break in the future") public RegionOperationsStub createStub() throws IOException { if (getTransportChannelProvider() @@ -167,12 +174,14 @@ protected RegionOperationsStubSettings(Builder settingsBuilder) throws IOExcepti super(settingsBuilder); getSettings = settingsBuilder.getSettings().build(); + waitSettings = settingsBuilder.waitSettings().build(); } /** Builder for RegionOperationsStubSettings. */ public static class Builder extends StubSettings.Builder { private final ImmutableList> unaryMethodSettingsBuilders; private final UnaryCallSettings.Builder getSettings; + private final UnaryCallSettings.Builder waitSettings; private static final ImmutableMap> RETRYABLE_CODE_DEFINITIONS; @@ -184,6 +193,7 @@ public static class Builder extends StubSettings.BuildernewArrayList( StatusCode.Code.DEADLINE_EXCEEDED, StatusCode.Code.UNAVAILABLE))); + definitions.put("no_retry_codes", ImmutableSet.copyOf(Lists.newArrayList())); RETRYABLE_CODE_DEFINITIONS = definitions.build(); } @@ -203,6 +213,8 @@ public static class Builder extends StubSettings.Builder>of(getSettings); + unaryMethodSettingsBuilders = + ImmutableList.>of(getSettings, waitSettings); initDefaults(this); } @@ -223,8 +237,10 @@ protected Builder(RegionOperationsStubSettings settings) { super(settings); getSettings = settings.getSettings.toBuilder(); + waitSettings = settings.waitSettings.toBuilder(); - unaryMethodSettingsBuilders = ImmutableList.>of(getSettings); + unaryMethodSettingsBuilders = + ImmutableList.>of(getSettings, waitSettings); } private static Builder createDefault() { @@ -246,6 +262,11 @@ private static Builder initDefaults(Builder builder) { .setRetryableCodes(RETRYABLE_CODE_DEFINITIONS.get("retry_policy_0_codes")) .setRetrySettings(RETRY_PARAM_DEFINITIONS.get("retry_policy_0_params")); + builder + .waitSettings() + .setRetryableCodes(RETRYABLE_CODE_DEFINITIONS.get("no_retry_codes")) + .setRetrySettings(RETRY_PARAM_DEFINITIONS.get("no_retry_params")); + return builder; } @@ -269,6 +290,11 @@ public UnaryCallSettings.Builder getSettin return getSettings; } + /** Returns the builder for the settings used for calls to wait. */ + public UnaryCallSettings.Builder waitSettings() { + return waitSettings; + } + @Override public RegionOperationsStubSettings build() throws IOException { return new RegionOperationsStubSettings(this); From 8ae8e6f111d0f3849986cd0445d6003601ced148 Mon Sep 17 00:00:00 2001 From: Vadym Matsishevskyi <25311427+vam-google@users.noreply.github.com> Date: Thu, 9 Sep 2021 01:59:39 -0700 Subject: [PATCH 6/9] fix: DIREGAPIC LRO generated tests logic (#838) --- ...bstractServiceClientTestClassComposer.java | 24 +++--------- .../defaultvalue/DefaultValueComposer.java | 35 ++++++++++++++++- .../HttpJsonServiceStubClassComposer.java | 5 ++- .../api/generator/gapic/model/Message.java | 4 +- .../gapic/model/OperationResponse.java | 6 --- .../generator/gapic/protoparser/Parser.java | 7 +++- .../cloud/compute/v1/AddressesClientTest.java | 39 +++++++------------ .../v1/RegionOperationsClientTest.java | 7 +++- 8 files changed, 67 insertions(+), 60 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 364dd183b3..8309679eae 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 @@ -59,6 +59,7 @@ 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.OperationResponse; import com.google.api.generator.gapic.model.ResourceName; import com.google.api.generator.gapic.model.Service; import com.google.api.generator.gapic.utils.JavaStyle; @@ -413,7 +414,10 @@ private MethodDefinition createRpcTestMethod( .setValueExpr(expectedResponseValExpr) .build()); - if (method.hasLro()) { + if (method.hasLro() + && (method.lro().operationServiceStubType() == null + || !method.lro().responseType().equals(method.outputType()))) { + VariableExpr resultOperationVarExpr = VariableExpr.withVariable( Variable.builder() @@ -910,24 +914,6 @@ private void addDynamicTypes(GapicContext context, Service service, TypeStore ty } } - private static TypeNode getOperationCallSettingsTypeHelper( - Method protoMethod, boolean isBuilder) { - Preconditions.checkState( - protoMethod.hasLro(), - String.format("Cannot get OperationCallSettings on non-LRO method %s", protoMethod.name())); - Class callSettingsClazz = - isBuilder ? OperationCallSettings.Builder.class : OperationCallSettings.class; - return TypeNode.withReference( - ConcreteReference.builder() - .setClazz(callSettingsClazz) - .setGenerics( - Arrays.asList( - protoMethod.inputType().reference(), - protoMethod.lro().responseType().reference(), - protoMethod.lro().metadataType().reference())) - .build()); - } - 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/defaultvalue/DefaultValueComposer.java b/src/main/java/com/google/api/generator/gapic/composer/defaultvalue/DefaultValueComposer.java index 5af2722fd7..1b0ffc3c41 100644 --- a/src/main/java/com/google/api/generator/gapic/composer/defaultvalue/DefaultValueComposer.java +++ b/src/main/java/com/google/api/generator/gapic/composer/defaultvalue/DefaultValueComposer.java @@ -27,6 +27,7 @@ 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.VaporReference; import com.google.api.generator.engine.ast.Variable; import com.google.api.generator.engine.ast.VariableExpr; import com.google.api.generator.gapic.composer.resourcename.ResourceNameTokenizer; @@ -265,9 +266,12 @@ public static Expr createSimpleMessageBuilderExpr( .setStaticReferenceType(message.type()) .setMethodName("newBuilder") .build(); + for (Field field : message.fields()) { if (field.isContainedInOneof() // Avoid colliding fields. - || ((field.isMessage() || field.isEnum()) // Avoid importing unparsed messages. + || ((field.isMessage() + || (field.isEnum() + && message.operationResponse() == null)) // Avoid importing unparsed messages. && !field.isRepeated() && !messageTypes.containsKey(field.type().reference().fullName()))) { continue; @@ -292,7 +296,34 @@ public static Expr createSimpleMessageBuilderExpr( .setReturnType(TypeNode.STRING) .build(); } else { - defaultExpr = createDefaultValue(field, true); + if (message.operationResponse() != null) { + if (field.name().equals(message.operationResponse().statusFieldName())) { + String statusTypeName = message.operationResponse().statusFieldTypeName(); + String statusClassName = statusTypeName.substring(statusTypeName.lastIndexOf('.') + 1); + + TypeNode statusType = + TypeNode.withReference( + VaporReference.builder() + .setName(statusClassName) + .setPakkage(message.type().reference().fullName()) + .setIsStaticImport(false) + .build()); + defaultExpr = + VariableExpr.builder() + .setVariable(Variable.builder().setName("DONE").setType(statusType).build()) + .setStaticReferenceType(statusType) + .build(); + + } else if (field.name().equals(message.operationResponse().errorCodeFieldName())) { + defaultExpr = + ValueExpr.withValue( + PrimitiveValue.builder().setType(field.type()).setValue("0").build()); + } + } + + if (defaultExpr == null) { + defaultExpr = createDefaultValue(field, true); + } } builderExpr = MethodInvocationExpr.builder() diff --git a/src/main/java/com/google/api/generator/gapic/composer/rest/HttpJsonServiceStubClassComposer.java b/src/main/java/com/google/api/generator/gapic/composer/rest/HttpJsonServiceStubClassComposer.java index fb45703936..59a05c0a62 100644 --- a/src/main/java/com/google/api/generator/gapic/composer/rest/HttpJsonServiceStubClassComposer.java +++ b/src/main/java/com/google/api/generator/gapic/composer/rest/HttpJsonServiceStubClassComposer.java @@ -511,11 +511,14 @@ private List setOperationSnapshotFactoryExpr( String statusTypeName = operationResponse.statusFieldTypeName(); String statusClassName = statusTypeName.substring(statusTypeName.lastIndexOf('.') + 1); + TypeNode opType = + protoMethod.hasLro() ? protoMethod.lro().responseType() : protoMethod.outputType(); + TypeNode statusType = TypeNode.withReference( VaporReference.builder() .setName(statusClassName) - .setPakkage(protoMethod.outputType().reference().fullName()) + .setPakkage(opType.reference().fullName()) .setIsStaticImport(false) .build()); VariableExpr statusDoneExpr = diff --git a/src/main/java/com/google/api/generator/gapic/model/Message.java b/src/main/java/com/google/api/generator/gapic/model/Message.java index 51245444fe..91a5388e37 100644 --- a/src/main/java/com/google/api/generator/gapic/model/Message.java +++ b/src/main/java/com/google/api/generator/gapic/model/Message.java @@ -53,6 +53,7 @@ public abstract class Message { public abstract ImmutableMap fieldMap(); + @Nullable public abstract OperationResponse operationResponse(); public abstract Map operationRequestFields(); @@ -113,8 +114,7 @@ public static Builder builder() { .setFieldMap(Collections.emptyMap()) .setEnumValues(Collections.emptyMap()) .setOperationResponseFields(HashBiMap.create()) - .setOperationRequestFields(Collections.emptyMap()) - .setOperationResponse(OperationResponse.builder().build()); + .setOperationRequestFields(Collections.emptyMap()); } @AutoValue.Builder diff --git a/src/main/java/com/google/api/generator/gapic/model/OperationResponse.java b/src/main/java/com/google/api/generator/gapic/model/OperationResponse.java index 20543d3fc8..9ad5ac385f 100644 --- a/src/main/java/com/google/api/generator/gapic/model/OperationResponse.java +++ b/src/main/java/com/google/api/generator/gapic/model/OperationResponse.java @@ -16,23 +16,17 @@ package com.google.api.generator.gapic.model; import com.google.auto.value.AutoValue; -import javax.annotation.Nullable; @AutoValue public abstract class OperationResponse { - @Nullable public abstract String nameFieldName(); - @Nullable public abstract String statusFieldName(); - @Nullable public abstract String errorCodeFieldName(); - @Nullable public abstract String errorMessageFieldName(); - @Nullable public abstract String statusFieldTypeName(); public static Builder builder() { 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 a5f227a3d7..1ccfc3d1eb 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 @@ -564,7 +564,7 @@ private static Map parseMessages( List fields = messageDescriptor.getFields(); HashMap operationRequestFields = new HashMap(); BiMap operationResponseFields = HashBiMap.create(); - OperationResponse.Builder operationResponse = OperationResponse.builder(); + OperationResponse.Builder operationResponse = null; for (FieldDescriptor fd : fields) { if (fd.getOptions().hasExtension(ExtendedOperationsProto.operationRequestField)) { String orf = fd.getOptions().getExtension(ExtendedOperationsProto.operationRequestField); @@ -577,6 +577,9 @@ private static Map parseMessages( if (fd.getOptions().hasExtension(ExtendedOperationsProto.operationField)) { OperationResponseMapping orm = fd.getOptions().getExtension(ExtendedOperationsProto.operationField); + if (operationResponse == null) { + operationResponse = OperationResponse.builder(); + } if (orm.equals(OperationResponseMapping.NAME)) { operationResponse.setNameFieldName(fd.getName()); } else if (orm.equals(OperationResponseMapping.STATUS)) { @@ -599,7 +602,7 @@ private static Map parseMessages( .setOuterNestedTypes(outerNestedTypes) .setOperationRequestFields(operationRequestFields) .setOperationResponseFields(operationResponseFields) - .setOperationResponse(operationResponse.build()) + .setOperationResponse(operationResponse != null ? operationResponse.build() : null) .build()); return messages; } diff --git a/test/integration/goldens/compute/com/google/cloud/compute/v1/AddressesClientTest.java b/test/integration/goldens/compute/com/google/cloud/compute/v1/AddressesClientTest.java index 04f3ea46b9..ec3f75047c 100644 --- a/test/integration/goldens/compute/com/google/cloud/compute/v1/AddressesClientTest.java +++ b/test/integration/goldens/compute/com/google/cloud/compute/v1/AddressesClientTest.java @@ -28,10 +28,9 @@ import com.google.api.gax.rpc.InvalidArgumentException; import com.google.api.gax.rpc.StatusCode; import com.google.api.gax.rpc.testing.FakeStatusCode; +import com.google.cloud.compute.v1.Operation.Status; import com.google.cloud.compute.v1.stub.HttpJsonAddressesStub; import com.google.common.collect.Lists; -import com.google.longrunning.Operation; -import com.google.protobuf.Any; import java.io.IOException; import java.util.ArrayList; import java.util.Arrays; @@ -135,15 +134,15 @@ public void aggregatedListExceptionTest() throws Exception { @Test public void deleteTest() throws Exception { - com.google.cloud.compute.v1.Operation expectedResponse = - com.google.cloud.compute.v1.Operation.newBuilder() + Operation expectedResponse = + Operation.newBuilder() .setClientOperationId("clientOperationId-1230366697") .setCreationTimestamp("creationTimestamp-370203401") .setDescription("description-1724546052") .setEndTime("endTime-1607243192") .setError(Error.newBuilder().build()) .setHttpErrorMessage("httpErrorMessage1577303431") - .setHttpErrorStatusCode(1386087020) + .setHttpErrorStatusCode(0) .setId(3355) .setInsertTime("insertTime966165798") .setKind("kind3292052") @@ -153,6 +152,7 @@ public void deleteTest() throws Exception { .setRegion("region-934795532") .setSelfLink("selfLink1191800166") .setStartTime("startTime-2129294769") + .setStatus(Status.DONE) .setStatusMessage("statusMessage-958704715") .setTargetId(-815576439) .setTargetLink("targetLink486368555") @@ -160,20 +160,13 @@ public void deleteTest() throws Exception { .addAllWarnings(new ArrayList()) .setZone("zone3744684") .build(); - Operation resultOperation = - Operation.newBuilder() - .setName("deleteTest") - .setDone(true) - .setResponse(Any.pack(expectedResponse)) - .build(); - mockService.addResponse(resultOperation); + mockService.addResponse(expectedResponse); String project = "project-309310695"; String region = "region-934795532"; String address = "address-1147692044"; - com.google.cloud.compute.v1.Operation actualResponse = - client.deleteAsync(project, region, address).get(); + Operation actualResponse = client.deleteAsync(project, region, address).get(); Assert.assertEquals(expectedResponse, actualResponse); List actualRequests = mockService.getRequestPaths(); @@ -210,15 +203,15 @@ public void deleteExceptionTest() throws Exception { @Test public void insertTest() throws Exception { - com.google.cloud.compute.v1.Operation expectedResponse = - com.google.cloud.compute.v1.Operation.newBuilder() + Operation expectedResponse = + Operation.newBuilder() .setClientOperationId("clientOperationId-1230366697") .setCreationTimestamp("creationTimestamp-370203401") .setDescription("description-1724546052") .setEndTime("endTime-1607243192") .setError(Error.newBuilder().build()) .setHttpErrorMessage("httpErrorMessage1577303431") - .setHttpErrorStatusCode(1386087020) + .setHttpErrorStatusCode(0) .setId(3355) .setInsertTime("insertTime966165798") .setKind("kind3292052") @@ -228,6 +221,7 @@ public void insertTest() throws Exception { .setRegion("region-934795532") .setSelfLink("selfLink1191800166") .setStartTime("startTime-2129294769") + .setStatus(Status.DONE) .setStatusMessage("statusMessage-958704715") .setTargetId(-815576439) .setTargetLink("targetLink486368555") @@ -235,20 +229,13 @@ public void insertTest() throws Exception { .addAllWarnings(new ArrayList()) .setZone("zone3744684") .build(); - Operation resultOperation = - Operation.newBuilder() - .setName("insertTest") - .setDone(true) - .setResponse(Any.pack(expectedResponse)) - .build(); - mockService.addResponse(resultOperation); + mockService.addResponse(expectedResponse); String project = "project-309310695"; String region = "region-934795532"; Address addressResource = Address.newBuilder().build(); - com.google.cloud.compute.v1.Operation actualResponse = - client.insertAsync(project, region, addressResource).get(); + Operation actualResponse = client.insertAsync(project, region, addressResource).get(); Assert.assertEquals(expectedResponse, actualResponse); List actualRequests = mockService.getRequestPaths(); diff --git a/test/integration/goldens/compute/com/google/cloud/compute/v1/RegionOperationsClientTest.java b/test/integration/goldens/compute/com/google/cloud/compute/v1/RegionOperationsClientTest.java index 684c1312ab..c1a2c78519 100644 --- a/test/integration/goldens/compute/com/google/cloud/compute/v1/RegionOperationsClientTest.java +++ b/test/integration/goldens/compute/com/google/cloud/compute/v1/RegionOperationsClientTest.java @@ -25,6 +25,7 @@ import com.google.api.gax.rpc.InvalidArgumentException; import com.google.api.gax.rpc.StatusCode; import com.google.api.gax.rpc.testing.FakeStatusCode; +import com.google.cloud.compute.v1.Operation.Status; import com.google.cloud.compute.v1.stub.HttpJsonRegionOperationsStub; import java.io.IOException; import java.util.ArrayList; @@ -82,7 +83,7 @@ public void getTest() throws Exception { .setEndTime("endTime-1607243192") .setError(Error.newBuilder().build()) .setHttpErrorMessage("httpErrorMessage1577303431") - .setHttpErrorStatusCode(1386087020) + .setHttpErrorStatusCode(0) .setId(3355) .setInsertTime("insertTime966165798") .setKind("kind3292052") @@ -92,6 +93,7 @@ public void getTest() throws Exception { .setRegion("region-934795532") .setSelfLink("selfLink1191800166") .setStartTime("startTime-2129294769") + .setStatus(Status.DONE) .setStatusMessage("statusMessage-958704715") .setTargetId(-815576439) .setTargetLink("targetLink486368555") @@ -151,7 +153,7 @@ public void waitTest() throws Exception { .setEndTime("endTime-1607243192") .setError(Error.newBuilder().build()) .setHttpErrorMessage("httpErrorMessage1577303431") - .setHttpErrorStatusCode(1386087020) + .setHttpErrorStatusCode(0) .setId(3355) .setInsertTime("insertTime966165798") .setKind("kind3292052") @@ -161,6 +163,7 @@ public void waitTest() throws Exception { .setRegion("region-934795532") .setSelfLink("selfLink1191800166") .setStartTime("startTime-2129294769") + .setStatus(Status.DONE) .setStatusMessage("statusMessage-958704715") .setTargetId(-815576439) .setTargetLink("targetLink486368555") From c4c9dfa1668471612f0b9003606459d24ae649de Mon Sep 17 00:00:00 2001 From: Vadym Matsishevskyi <25311427+vam-google@users.noreply.github.com> Date: Tue, 21 Sep 2021 03:34:51 -0700 Subject: [PATCH 7/9] feat: Add REST AIP-151 LRO suport (#846) Depends on https://github.com/googleapis/gax-java/pull/1484 --- ...ractTransportServiceStubClassComposer.java | 106 +++-- .../composer/grpcrest/GrpcRestContext.java | 4 +- ...onServiceCallableFactoryClassComposer.java | 14 +- .../HttpJsonServiceStubClassComposer.java | 365 ++++++++++++------ .../gapic/composer/rest/RestContext.java | 4 +- .../HttpJsonComplianceCallableFactory.golden | 20 +- .../goldens/HttpJsonComplianceStub.golden | 15 + .../v1/stub/HttpJsonAddressesStub.java | 12 + ...tpJsonRegionOperationsCallableFactory.java | 20 +- .../v1/stub/HttpJsonRegionOperationsStub.java | 7 + 10 files changed, 386 insertions(+), 181 deletions(-) diff --git a/src/main/java/com/google/api/generator/gapic/composer/common/AbstractTransportServiceStubClassComposer.java b/src/main/java/com/google/api/generator/gapic/composer/common/AbstractTransportServiceStubClassComposer.java index 3aa79a452f..d3b9eae6f9 100644 --- a/src/main/java/com/google/api/generator/gapic/composer/common/AbstractTransportServiceStubClassComposer.java +++ b/src/main/java/com/google/api/generator/gapic/composer/common/AbstractTransportServiceStubClassComposer.java @@ -17,6 +17,7 @@ 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.longrunning.OperationSnapshot; import com.google.api.gax.rpc.BidiStreamingCallable; import com.google.api.gax.rpc.ClientContext; import com.google.api.gax.rpc.ClientStreamingCallable; @@ -119,6 +120,7 @@ private static TypeStore createStaticTypes() { IOException.class, Operation.class, OperationCallable.class, + OperationSnapshot.class, RequestParamsExtractor.class, ServerStreamingCallable.class, TimeUnit.class, @@ -161,7 +163,7 @@ public GapicClass generate(GapicContext context, Service service) { } boolean operationPollingMethod = checkOperationPollingMethod(service); - if(operationPollingMethod) { + if (operationPollingMethod) { VariableExpr longRunningVarExpr = declareLongRunningClient(); if (longRunningVarExpr != null) { classMemberVarExprs.put("longRunningClient", longRunningVarExpr); @@ -212,7 +214,10 @@ public GapicClass generate(GapicContext context, Service service) { } protected abstract Statement createMethodDescriptorVariableDecl( - Service service, Method protoMethod, VariableExpr methodDescriptorVarExpr, Map messageTypes); + Service service, + Method protoMethod, + VariableExpr methodDescriptorVarExpr, + Map messageTypes); protected boolean generateOperationsStubLogic(Service service) { return true; @@ -227,7 +232,8 @@ protected List createOperationsStubGetterMethod( String methodName = String.format( "get%s", - JavaStyle.toUpperCamelCase(getTransportContext().transportOperationsStubNames().get(0))); + JavaStyle.toUpperCamelCase( + getTransportContext().transportOperationsStubNames().get(0))); return Arrays.asList( MethodDefinition.builder() @@ -248,6 +254,10 @@ protected List createGetMethodDescriptorsMethod( return Arrays.asList(); } + protected List createTypeRegistry(Service service) { + return Arrays.asList(); + } + protected List createClassStatements( Service service, Map protoMethodNameToDescriptorVarExprs, @@ -255,8 +265,15 @@ protected List createClassStatements( Map classMemberVarExprs, Map messageTypes) { List classStatements = new ArrayList<>(); + + classStatements.addAll(createTypeRegistry(service)); + if (!classStatements.isEmpty()) { + classStatements.add(EMPTY_LINE_STATEMENT); + } + for (Statement statement : - createMethodDescriptorVariableDecls(service, protoMethodNameToDescriptorVarExprs, messageTypes)) { + createMethodDescriptorVariableDecls( + service, protoMethodNameToDescriptorVarExprs, messageTypes)) { classStatements.add(statement); classStatements.add(EMPTY_LINE_STATEMENT); } @@ -265,11 +282,15 @@ protected List createClassStatements( classStatements.add(EMPTY_LINE_STATEMENT); classStatements.addAll(createClassMemberFieldDeclarations(classMemberVarExprs)); + classStatements.add(EMPTY_LINE_STATEMENT); + return classStatements; } protected List createMethodDescriptorVariableDecls( - Service service, Map protoMethodNameToDescriptorVarExprs, Map messageTypes) { + Service service, + Map protoMethodNameToDescriptorVarExprs, + Map messageTypes) { return service.methods().stream() .map( m -> @@ -418,14 +439,17 @@ protected List createClassMethods( createGetMethodDescriptorsMethod(service, typeStore, protoMethodNameToDescriptorVarExprs)); javaMethods.addAll( createOperationsStubGetterMethod( - service, classMemberVarExprs.get(getTransportContext().transportOperationsStubNames().get(0)))); + service, + classMemberVarExprs.get(getTransportContext().transportOperationsStubNames().get(0)))); javaMethods.addAll(createCallableGetterMethods(callableClassMemberVarExprs)); javaMethods.addAll( - createStubOverrideMethods(classMemberVarExprs.get(BACKGROUND_RESOURCES_MEMBER_NAME), service)); + createStubOverrideMethods( + classMemberVarExprs.get(BACKGROUND_RESOURCES_MEMBER_NAME), service)); return javaMethods; } - protected List createStaticCreatorMethods(Service service, TypeStore typeStore, String newBuilderMethod) { + protected List createStaticCreatorMethods( + Service service, TypeStore typeStore, String newBuilderMethod) { TypeNode creatorMethodReturnType = typeStore.get(getTransportContext().classNames().getTransportServiceStubClassName(service)); Function, MethodDefinition.Builder> creatorMethodStarterFn = @@ -584,22 +608,16 @@ protected List createConstructorMethods( .build()) .setValueExpr(callableFactoryVarExpr) .build()); - VariableExpr operationsStubClassVarExpr = classMemberVarExprs.get(getTransportContext().transportOperationsStubNames().get(0)); - //TODO: refactor this + VariableExpr operationsStubClassVarExpr = + classMemberVarExprs.get(getTransportContext().transportOperationsStubNames().get(0)); + // TODO: refactor this if (generateOperationsStubLogic(service)) { - TypeNode opeationsStubType = getTransportOperationsStubType(service); - secondCtorExprs.add( - AssignmentExpr.builder() - .setVariableExpr( - operationsStubClassVarExpr.toBuilder().setExprReferenceExpr(thisExpr).build()) - .setValueExpr( - MethodInvocationExpr.builder() - .setStaticReferenceType(opeationsStubType) - .setMethodName("create") - .setArguments(Arrays.asList(clientContextVarExpr, callableFactoryVarExpr)) - .setReturnType(operationsStubClassVarExpr.type()) - .build()) - .build()); + secondCtorExprs.addAll(createOperationsStubInitExpr( + service, + thisExpr, + operationsStubClassVarExpr, + clientContextVarExpr, + callableFactoryVarExpr)); } secondCtorStatements.addAll( secondCtorExprs.stream().map(e -> ExprStatement.withExpr(e)).collect(Collectors.toList())); @@ -665,7 +683,6 @@ protected List createConstructorMethods( secondCtorExprs.clear(); secondCtorStatements.add(EMPTY_LINE_STATEMENT); - secondCtorStatements.addAll(createLongRunningClient(service, typeStore)); // Instantiate backgroundResources. @@ -699,6 +716,27 @@ protected List createConstructorMethods( return Arrays.asList(firstCtor, secondCtor); } + protected List createOperationsStubInitExpr( + Service service, + Expr thisExpr, + VariableExpr operationsStubClassVarExpr, + VariableExpr clientContextVarExpr, + VariableExpr callableFactoryVarExpr) { + TypeNode opeationsStubType = getTransportOperationsStubType(service); + return Collections.singletonList( + AssignmentExpr.builder() + .setVariableExpr( + operationsStubClassVarExpr.toBuilder().setExprReferenceExpr(thisExpr).build()) + .setValueExpr( + MethodInvocationExpr.builder() + .setStaticReferenceType(opeationsStubType) + .setMethodName("create") + .setArguments(Arrays.asList(clientContextVarExpr, callableFactoryVarExpr)) + .setReturnType(operationsStubClassVarExpr.type()) + .build()) + .build()); + } + protected List createLongRunningClient(Service service, TypeStore typeStore) { return ImmutableList.of(); } @@ -963,8 +1001,8 @@ private List createStubOverrideMethods( } private boolean checkOperationPollingMethod(Service service) { - for(Method method : service.methods()) { - if(method.isOperationPollingMethod()) { + for (Method method : service.methods()) { + if (method.isOperationPollingMethod()) { return true; } } @@ -1063,15 +1101,15 @@ protected TypeNode getTransportOperationsStubType(Service service) { TypeNode transportOpeationsStubType = service.operationServiceStubType(); if (transportOpeationsStubType == null) { transportOpeationsStubType = getTransportContext().transportOperationsStubTypes().get(0); - } - else { - transportOpeationsStubType = TypeNode.withReference( - VaporReference.builder() - .setName("HttpJson" + transportOpeationsStubType.reference().simpleName()) - .setPakkage(transportOpeationsStubType.reference().pakkage()) - .build()); + } else { + transportOpeationsStubType = + TypeNode.withReference( + VaporReference.builder() + .setName("HttpJson" + transportOpeationsStubType.reference().simpleName()) + .setPakkage(transportOpeationsStubType.reference().pakkage()) + .build()); } return transportOpeationsStubType; } -} \ No newline at end of file +} diff --git a/src/main/java/com/google/api/generator/gapic/composer/grpcrest/GrpcRestContext.java b/src/main/java/com/google/api/generator/gapic/composer/grpcrest/GrpcRestContext.java index 3f84bf3c97..59376001e2 100644 --- a/src/main/java/com/google/api/generator/gapic/composer/grpcrest/GrpcRestContext.java +++ b/src/main/java/com/google/api/generator/gapic/composer/grpcrest/GrpcRestContext.java @@ -14,7 +14,6 @@ package com.google.api.generator.gapic.composer.grpcrest; -import com.google.api.gax.core.BackgroundResource; import com.google.api.gax.grpc.GrpcTransportChannel; import com.google.api.gax.grpc.InstantiatingGrpcChannelProvider; import com.google.api.gax.grpc.ProtoOperationTransformers; @@ -72,7 +71,8 @@ public abstract class GrpcRestContext extends TransportContext { .setTransportCallableFactoryType(null) .setOperationsStubTypes( ImmutableList.of( - classToType(OperationsStub.class), classToType(BackgroundResource.class))) + classToType(OperationsStub.class), + classToType(com.google.api.gax.httpjson.longrunning.stub.OperationsStub.class))) .setTransportCallSettingsName(null) // For RetrySettingsComposer // TODO: fix when LRO for REST RE FIXED diff --git a/src/main/java/com/google/api/generator/gapic/composer/rest/HttpJsonServiceCallableFactoryClassComposer.java b/src/main/java/com/google/api/generator/gapic/composer/rest/HttpJsonServiceCallableFactoryClassComposer.java index a7b525239e..b295cb8f83 100644 --- a/src/main/java/com/google/api/generator/gapic/composer/rest/HttpJsonServiceCallableFactoryClassComposer.java +++ b/src/main/java/com/google/api/generator/gapic/composer/rest/HttpJsonServiceCallableFactoryClassComposer.java @@ -27,14 +27,13 @@ import com.google.api.generator.engine.ast.NewObjectExpr; 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.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.AbstractServiceCallableFactoryClassComposer; import com.google.api.generator.gapic.composer.store.TypeStore; import com.google.api.generator.gapic.model.Service; -import com.google.common.collect.ImmutableList; +import com.google.longrunning.Operation; import java.util.ArrayList; import java.util.Arrays; import java.util.List; @@ -46,7 +45,7 @@ public class HttpJsonServiceCallableFactoryClassComposer new HttpJsonServiceCallableFactoryClassComposer(); private static final TypeNode DEFAULT_OPERATION_TYPE = - TypeNode.withReference(ConcreteReference.withClazz(Object.class)); + TypeNode.withReference(ConcreteReference.withClazz(Operation.class)); private HttpJsonServiceCallableFactoryClassComposer() { super(RestContext.instance()); @@ -129,15 +128,6 @@ protected MethodDefinition createOperationCallableMethod(Service service, TypeSt Arrays.asList(betaAnnotation)); List createOperationCallableBody = new ArrayList<>(); - if (service.operationServiceStubType() == null) { - // It is an Operation polling service, it cannot contain LRO methods - return method - .toBuilder() - .setBody(ImmutableList.of()) - .setReturnExpr(ValueExpr.createNullExpr()) - .build(); - } - List arguments = new ArrayList<>(method.arguments()); Variable httpJsonCallSettingsVar = arguments.get(0).variable(); diff --git a/src/main/java/com/google/api/generator/gapic/composer/rest/HttpJsonServiceStubClassComposer.java b/src/main/java/com/google/api/generator/gapic/composer/rest/HttpJsonServiceStubClassComposer.java index 59a05c0a62..172326176d 100644 --- a/src/main/java/com/google/api/generator/gapic/composer/rest/HttpJsonServiceStubClassComposer.java +++ b/src/main/java/com/google/api/generator/gapic/composer/rest/HttpJsonServiceStubClassComposer.java @@ -25,6 +25,7 @@ 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.gax.httpjson.longrunning.stub.HttpJsonOperationsStub; import com.google.api.gax.longrunning.OperationSnapshot; import com.google.api.gax.rpc.LongRunningClient; import com.google.api.gax.rpc.UnaryCallable; @@ -59,6 +60,7 @@ import com.google.api.generator.gapic.utils.JavaStyle; import com.google.common.collect.BiMap; import com.google.common.collect.ImmutableList; +import com.google.protobuf.TypeRegistry; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; @@ -76,6 +78,14 @@ public class HttpJsonServiceStubClassComposer extends AbstractTransportServiceSt new HttpJsonServiceStubClassComposer(); private static final TypeStore FIXED_REST_TYPESTORE = createStaticTypes(); + private static final VariableExpr TYPE_REGISTRY_VAR_EXPR = + VariableExpr.builder() + .setVariable( + Variable.builder() + .setName("typeRegistry") + .setType(FIXED_REST_TYPESTORE.get(TypeRegistry.class.getSimpleName())) + .build()) + .build(); protected HttpJsonServiceStubClassComposer() { super(RestContext.instance()); @@ -94,11 +104,13 @@ private static TypeStore createStaticTypes() { InternalApi.class, HashMap.class, HttpJsonCallSettings.class, + HttpJsonOperationSnapshot.class, HttpJsonStubCallableFactory.class, Map.class, ProtoMessageRequestFormatter.class, ProtoMessageResponseParser.class, - ProtoRestSerializer.class)); + ProtoRestSerializer.class, + TypeRegistry.class)); } @Override @@ -201,6 +213,13 @@ protected Expr createTransportSettingsInitExpr( .setArguments(Arrays.asList(methodDescriptorVarExpr)) .build(); + callSettingsBuilderExpr = + MethodInvocationExpr.builder() + .setExprReferenceExpr(callSettingsBuilderExpr) + .setMethodName("setTypeRegistry") + .setArguments(Arrays.asList(TYPE_REGISTRY_VAR_EXPR)) + .build(); + callSettingsBuilderExpr = MethodInvocationExpr.builder() .setExprReferenceExpr(callSettingsBuilderExpr) @@ -396,6 +415,11 @@ private List setResponseParserExpr(Method protoMethod) { .setReturnType(protoMethod.outputType()) .build())) .apply(expr); + + expr = + methodMaker + .apply("setDefaultTypeRegistry", Arrays.asList(TYPE_REGISTRY_VAR_EXPR)) + .apply(expr); expr = methodMaker.apply("build", Collections.emptyList()).apply(expr); return Collections.singletonList(expr); @@ -451,15 +475,6 @@ private MethodInvocationExpr getExpr(VariableExpr var, String num) { private List setOperationSnapshotFactoryExpr( Method protoMethod, Map messageTypes) { - Message inputOperationMessage = - messageTypes.get(protoMethod.inputType().reference().fullName()); - Message outputOperationMessage = - messageTypes.get(protoMethod.outputType().reference().fullName()); - OperationResponse operationResponse = outputOperationMessage.operationResponse(); - - BiFunction, Function> - methodMaker = getMethodMaker(); - // Generate input varibles for create() VariableExpr requestVarExpr = VariableExpr.withVariable( @@ -468,127 +483,148 @@ private List setOperationSnapshotFactoryExpr( VariableExpr.withVariable( Variable.builder().setType(protoMethod.outputType()).setName("response").build()); - List createBody = new ArrayList(4); + MethodInvocationExpr buildExpr; + List createBody = new ArrayList<>(4); - // Generate opName - TypeNode stringBuilderType = - TypeNode.withReference(ConcreteReference.withClazz(StringBuilder.class)); - VariableExpr opNameVarExpr = - VariableExpr.withVariable( - Variable.builder().setType(stringBuilderType).setName("opName").build()); - MethodInvocationExpr getId = - MethodInvocationExpr.builder() - .setExprReferenceExpr(responseVarExpr) - .setMethodName(getMethodFormat(operationResponse.nameFieldName())) - .build(); - Expr opNameObjectExpr = - NewObjectExpr.builder().setType(stringBuilderType).setArguments(getId).build(); - AssignmentExpr opNameAssignExpr = - AssignmentExpr.builder() - .setVariableExpr(opNameVarExpr.toBuilder().setIsDecl(true).build()) - .setValueExpr(opNameObjectExpr) - .build(); - createBody.add(ExprStatement.withExpr(opNameAssignExpr)); - - // Generate compound operation name - if (!protoMethod.isOperationPollingMethod()) { - // TODO: Change to ordered map - Map requestFields = inputOperationMessage.operationRequestFields(); - List fieldAnnotationNames = new ArrayList(requestFields.keySet()); - Collections.sort(fieldAnnotationNames); - for (String fieldName : fieldAnnotationNames) { - createBody.add(appendField(opNameVarExpr, requestVarExpr, requestFields.get(fieldName))); + TypeNode httpJsonOperationSnapshotType = + FIXED_REST_TYPESTORE.get(HttpJsonOperationSnapshot.class.getSimpleName()); + TypeNode operationSnapshotType = FIXED_TYPESTORE.get(OperationSnapshot.class.getSimpleName()); + + Message inputOperationMessage = + messageTypes.get(protoMethod.inputType().reference().fullName()); + Message outputOperationMessage = + messageTypes.get(protoMethod.outputType().reference().fullName()); + OperationResponse operationResponse = outputOperationMessage.operationResponse(); + + if (operationResponse == null) { + // AIP-151 LRO + // HttpJsonOperationSnapshot.create(response) + buildExpr = + MethodInvocationExpr.builder() + .setStaticReferenceType(httpJsonOperationSnapshotType) + .setMethodName("create") + .setArguments(responseVarExpr) + .setReturnType(operationSnapshotType) + .build(); + } else { + BiFunction, Function> + methodMaker = getMethodMaker(); + + // Generate opName + TypeNode stringBuilderType = + TypeNode.withReference(ConcreteReference.withClazz(StringBuilder.class)); + VariableExpr opNameVarExpr = + VariableExpr.withVariable( + Variable.builder().setType(stringBuilderType).setName("opName").build()); + MethodInvocationExpr getId = + MethodInvocationExpr.builder() + .setExprReferenceExpr(responseVarExpr) + .setMethodName(getMethodFormat(operationResponse.nameFieldName())) + .build(); + Expr opNameObjectExpr = + NewObjectExpr.builder().setType(stringBuilderType).setArguments(getId).build(); + AssignmentExpr opNameAssignExpr = + AssignmentExpr.builder() + .setVariableExpr(opNameVarExpr.toBuilder().setIsDecl(true).build()) + .setValueExpr(opNameObjectExpr) + .build(); + createBody.add(ExprStatement.withExpr(opNameAssignExpr)); + + // Generate compound operation name + if (!protoMethod.isOperationPollingMethod()) { + // TODO: Change to ordered map + Map requestFields = inputOperationMessage.operationRequestFields(); + List fieldAnnotationNames = new ArrayList(requestFields.keySet()); + Collections.sort(fieldAnnotationNames); + for (String fieldName : fieldAnnotationNames) { + createBody.add(appendField(opNameVarExpr, requestVarExpr, requestFields.get(fieldName))); + } } - } - // Generate check for status == done - MethodInvocationExpr getStatusExpr = - MethodInvocationExpr.builder() - .setExprReferenceExpr(responseVarExpr) - .setMethodName(getMethodFormat(operationResponse.statusFieldName())) - .build(); + // Generate check for status == done + MethodInvocationExpr getStatusExpr = + MethodInvocationExpr.builder() + .setExprReferenceExpr(responseVarExpr) + .setMethodName(getMethodFormat(operationResponse.statusFieldName())) + .build(); - String statusTypeName = operationResponse.statusFieldTypeName(); - String statusClassName = statusTypeName.substring(statusTypeName.lastIndexOf('.') + 1); + String statusTypeName = operationResponse.statusFieldTypeName(); + String statusClassName = statusTypeName.substring(statusTypeName.lastIndexOf('.') + 1); - TypeNode opType = - protoMethod.hasLro() ? protoMethod.lro().responseType() : protoMethod.outputType(); + TypeNode opType = + protoMethod.hasLro() ? protoMethod.lro().responseType() : protoMethod.outputType(); - TypeNode statusType = - TypeNode.withReference( - VaporReference.builder() - .setName(statusClassName) - .setPakkage(opType.reference().fullName()) - .setIsStaticImport(false) - .build()); - VariableExpr statusDoneExpr = - VariableExpr.builder() - .setVariable(Variable.builder().setName("DONE").setType(TypeNode.INT).build()) - .setStaticReferenceType(statusType) - .build(); - MethodInvocationExpr statusEqualsExpr = - MethodInvocationExpr.builder() - .setExprReferenceExpr(statusDoneExpr) - .setMethodName("equals") - .setArguments(getStatusExpr) - .build(); + TypeNode statusType = + TypeNode.withReference( + VaporReference.builder() + .setName(statusClassName) + .setPakkage(opType.reference().fullName()) + .setIsStaticImport(false) + .build()); + VariableExpr statusDoneExpr = + VariableExpr.builder() + .setVariable(Variable.builder().setName("DONE").setType(TypeNode.INT).build()) + .setStaticReferenceType(statusType) + .build(); + MethodInvocationExpr statusEqualsExpr = + MethodInvocationExpr.builder() + .setExprReferenceExpr(statusDoneExpr) + .setMethodName("equals") + .setArguments(getStatusExpr) + .build(); - // Generate return statement - TypeNode httpJsonOperationSnapshotType = - TypeNode.withReference(ConcreteReference.withClazz(HttpJsonOperationSnapshot.class)); + // Generate return statement - // Generate getter methods from annotations - MethodInvocationExpr opNameToStringExpr = - MethodInvocationExpr.builder() - .setExprReferenceExpr(opNameVarExpr) - .setMethodName("toString") - .build(); - MethodInvocationExpr getHttpErrorStatusCodeExpr = - MethodInvocationExpr.builder() - .setExprReferenceExpr(responseVarExpr) - .setMethodName(getMethodFormat(operationResponse.errorCodeFieldName())) - .build(); - MethodInvocationExpr getHttpErrorMessageExpr = - MethodInvocationExpr.builder() - .setExprReferenceExpr(responseVarExpr) - .setMethodName(getMethodFormat(operationResponse.errorMessageFieldName())) - .build(); - MethodInvocationExpr newBuilderExpr = - MethodInvocationExpr.builder() - .setStaticReferenceType(httpJsonOperationSnapshotType) - .setMethodName("newBuilder") - .build(); + // Generate getter methods from annotations + MethodInvocationExpr opNameToStringExpr = + MethodInvocationExpr.builder() + .setExprReferenceExpr(opNameVarExpr) + .setMethodName("toString") + .build(); + MethodInvocationExpr getHttpErrorStatusCodeExpr = + MethodInvocationExpr.builder() + .setExprReferenceExpr(responseVarExpr) + .setMethodName(getMethodFormat(operationResponse.errorCodeFieldName())) + .build(); + MethodInvocationExpr getHttpErrorMessageExpr = + MethodInvocationExpr.builder() + .setExprReferenceExpr(responseVarExpr) + .setMethodName(getMethodFormat(operationResponse.errorMessageFieldName())) + .build(); + MethodInvocationExpr newBuilderExpr = + MethodInvocationExpr.builder() + .setStaticReferenceType(httpJsonOperationSnapshotType) + .setMethodName("newBuilder") + .build(); - newBuilderExpr = - methodMaker - .apply("setName", Collections.singletonList(opNameToStringExpr)) - .apply(newBuilderExpr); - newBuilderExpr = - methodMaker - .apply("setMetadata", Collections.singletonList(responseVarExpr)) - .apply(newBuilderExpr); - newBuilderExpr = - methodMaker - .apply("setDone", Collections.singletonList(statusEqualsExpr)) - .apply(newBuilderExpr); - newBuilderExpr = - methodMaker - .apply("setResponse", Collections.singletonList(responseVarExpr)) - .apply(newBuilderExpr); - newBuilderExpr = - methodMaker - .apply("setError", Arrays.asList(getHttpErrorStatusCodeExpr, getHttpErrorMessageExpr)) - .apply(newBuilderExpr); - TypeNode operationSnapshotType = - TypeNode.withReference( - ConcreteReference.builder().setClazz(OperationSnapshot.class).build()); - MethodInvocationExpr buildExpr = - MethodInvocationExpr.builder() - .setExprReferenceExpr(newBuilderExpr) - .setMethodName("build") - .setReturnType(operationSnapshotType) - .build(); + newBuilderExpr = + methodMaker + .apply("setName", Collections.singletonList(opNameToStringExpr)) + .apply(newBuilderExpr); + newBuilderExpr = + methodMaker + .apply("setMetadata", Collections.singletonList(responseVarExpr)) + .apply(newBuilderExpr); + newBuilderExpr = + methodMaker + .apply("setDone", Collections.singletonList(statusEqualsExpr)) + .apply(newBuilderExpr); + newBuilderExpr = + methodMaker + .apply("setResponse", Collections.singletonList(responseVarExpr)) + .apply(newBuilderExpr); + newBuilderExpr = + methodMaker + .apply("setError", Arrays.asList(getHttpErrorStatusCodeExpr, getHttpErrorMessageExpr)) + .apply(newBuilderExpr); + buildExpr = + MethodInvocationExpr.builder() + .setExprReferenceExpr(newBuilderExpr) + .setMethodName("build") + .setReturnType(operationSnapshotType) + .build(); + } // Generate lambda anonymous class return Collections.singletonList( LambdaExpr.builder() @@ -942,6 +978,36 @@ private List getHttpMethodTypeExpr(Method protoMethod) { return Collections.singletonList(expr); } + @Override + protected List createOperationsStubInitExpr( + Service service, + Expr thisExpr, + VariableExpr operationsStubClassVarExpr, + VariableExpr clientContextVarExpr, + VariableExpr callableFactoryVarExpr) { + TypeNode opeationsStubType = getTransportOperationsStubType(service); + String standardOpStub = HttpJsonOperationsStub.class.getName(); + + List arguments = + new ArrayList<>(Arrays.asList(clientContextVarExpr, callableFactoryVarExpr)); + if (standardOpStub.equals(opeationsStubType.reference().fullName())) { + arguments.add(TYPE_REGISTRY_VAR_EXPR); + } + + return Collections.singletonList( + AssignmentExpr.builder() + .setVariableExpr( + operationsStubClassVarExpr.toBuilder().setExprReferenceExpr(thisExpr).build()) + .setValueExpr( + MethodInvocationExpr.builder() + .setStaticReferenceType(opeationsStubType) + .setMethodName("create") + .setArguments(arguments) + .setReturnType(operationsStubClassVarExpr.type()) + .build()) + .build()); + } + @Override protected List createLongRunningClient(Service service, TypeStore typeStore) { Method pollingMethod = service.operationPollingMethod(); @@ -1047,4 +1113,61 @@ protected Optional getCallableCreatorMethodName(TypeNode callableVarExpr } return Optional.of(String.format("create%sCallable", streamName)); } + + @Override + protected List createTypeRegistry(Service service) { + TypeNode typeRegistryType = FIXED_REST_TYPESTORE.get(TypeRegistry.class.getSimpleName()); + + VariableExpr typeRegistryVarExpr = + TYPE_REGISTRY_VAR_EXPR + .toBuilder() + .setIsDecl(true) + .setIsStatic(true) + .setScope(ScopeNode.PRIVATE) + .setIsFinal(true) + .build(); + + Map anyTypes = new HashMap<>(); + for (Method method : service.methods()) { + if (method.hasLro()) { + TypeNode anyType = method.lro().responseType(); + anyTypes.put(anyType.reference().fullName(), anyType); + anyType = method.lro().metadataType(); + anyTypes.put(anyType.reference().fullName(), anyType); + } + } + + Expr typeRegistryBuilderExpr = + MethodInvocationExpr.builder() + .setStaticReferenceType(typeRegistryType) + .setMethodName("newBuilder") + .build(); + + for (TypeNode anyType : anyTypes.values()) { + typeRegistryBuilderExpr = + MethodInvocationExpr.builder() + .setExprReferenceExpr(typeRegistryBuilderExpr) + .setMethodName("add") + .setArguments( + MethodInvocationExpr.builder() + .setStaticReferenceType(anyType) + .setMethodName("getDescriptor") + .build()) + .build(); + } + + typeRegistryBuilderExpr = + MethodInvocationExpr.builder() + .setExprReferenceExpr(typeRegistryBuilderExpr) + .setMethodName("build") + .setReturnType(typeRegistryType) + .build(); + + return Collections.singletonList( + ExprStatement.withExpr( + AssignmentExpr.builder() + .setVariableExpr(typeRegistryVarExpr) + .setValueExpr(typeRegistryBuilderExpr) + .build())); + } } diff --git a/src/main/java/com/google/api/generator/gapic/composer/rest/RestContext.java b/src/main/java/com/google/api/generator/gapic/composer/rest/RestContext.java index eab59215bf..2502a9128e 100644 --- a/src/main/java/com/google/api/generator/gapic/composer/rest/RestContext.java +++ b/src/main/java/com/google/api/generator/gapic/composer/rest/RestContext.java @@ -14,7 +14,6 @@ package com.google.api.generator.gapic.composer.rest; -import com.google.api.gax.core.BackgroundResource; import com.google.api.gax.httpjson.ApiMethodDescriptor; import com.google.api.gax.httpjson.HttpJsonCallSettings; import com.google.api.gax.httpjson.HttpJsonCallableFactory; @@ -24,6 +23,7 @@ import com.google.api.gax.httpjson.ProtoOperationTransformers; import com.google.api.gax.httpjson.longrunning.OperationsClient; import com.google.api.gax.httpjson.longrunning.stub.HttpJsonOperationsStub; +import com.google.api.gax.httpjson.longrunning.stub.OperationsStub; import com.google.api.generator.gapic.composer.common.TransportContext; import com.google.api.generator.gapic.composer.utils.ClassNames; import com.google.api.generator.gapic.model.Transport; @@ -58,7 +58,7 @@ public abstract class RestContext extends TransportContext { .setTransportCallSettingsType(classToType(HttpJsonCallSettings.class)) .setTransportCallableFactoryType(classToType(HttpJsonCallableFactory.class)) // TODO: set to com.google.api.gax.httpjson.longrunning.stub.OperationsStub.class - .setOperationsStubTypes(ImmutableList.of(classToType(BackgroundResource.class))) + .setOperationsStubTypes(ImmutableList.of(classToType(OperationsStub.class))) .setTransportCallSettingsName("httpJsonCallSettings") // For RetrySettingsComposer .setOperationResponseTransformerType( diff --git a/src/test/java/com/google/api/generator/gapic/composer/rest/goldens/HttpJsonComplianceCallableFactory.golden b/src/test/java/com/google/api/generator/gapic/composer/rest/goldens/HttpJsonComplianceCallableFactory.golden index ab84437e6e..6f5e7eab3b 100644 --- a/src/test/java/com/google/api/generator/gapic/composer/rest/goldens/HttpJsonComplianceCallableFactory.golden +++ b/src/test/java/com/google/api/generator/gapic/composer/rest/goldens/HttpJsonComplianceCallableFactory.golden @@ -1,10 +1,11 @@ package com.google.showcase.v1beta1.stub; import com.google.api.core.BetaApi; -import com.google.api.gax.core.BackgroundResource; import com.google.api.gax.httpjson.HttpJsonCallSettings; import com.google.api.gax.httpjson.HttpJsonCallableFactory; +import com.google.api.gax.httpjson.HttpJsonOperationSnapshotCallable; import com.google.api.gax.httpjson.HttpJsonStubCallableFactory; +import com.google.api.gax.httpjson.longrunning.stub.OperationsStub; import com.google.api.gax.rpc.BatchingCallSettings; import com.google.api.gax.rpc.ClientContext; import com.google.api.gax.rpc.OperationCallSettings; @@ -12,6 +13,7 @@ import com.google.api.gax.rpc.OperationCallable; import com.google.api.gax.rpc.PagedCallSettings; import com.google.api.gax.rpc.UnaryCallSettings; import com.google.api.gax.rpc.UnaryCallable; +import com.google.longrunning.Operation; import javax.annotation.Generated; // AUTO-GENERATED DOCUMENTATION AND CLASS. @@ -23,7 +25,7 @@ import javax.annotation.Generated; @BetaApi @Generated("by gapic-generator-java") public class HttpJsonComplianceCallableFactory - implements HttpJsonStubCallableFactory { + implements HttpJsonStubCallableFactory { @Override public UnaryCallable createUnaryCallable( @@ -58,10 +60,18 @@ public class HttpJsonComplianceCallableFactory @Override public OperationCallable createOperationCallable( - HttpJsonCallSettings httpJsonCallSettings, + HttpJsonCallSettings httpJsonCallSettings, OperationCallSettings callSettings, ClientContext clientContext, - BackgroundResource operationsStub) { - return null; + OperationsStub operationsStub) { + UnaryCallable innerCallable = + HttpJsonCallableFactory.createBaseUnaryCallable( + httpJsonCallSettings, callSettings.getInitialCallSettings(), clientContext); + HttpJsonOperationSnapshotCallable initialCallable = + new HttpJsonOperationSnapshotCallable( + innerCallable, + httpJsonCallSettings.getMethodDescriptor().getOperationSnapshotFactory()); + return HttpJsonCallableFactory.createOperationCallable( + callSettings, clientContext, operationsStub.longRunningClient(), initialCallable); } } diff --git a/src/test/java/com/google/api/generator/gapic/composer/rest/goldens/HttpJsonComplianceStub.golden b/src/test/java/com/google/api/generator/gapic/composer/rest/goldens/HttpJsonComplianceStub.golden index 331e5bf961..6b6a701df9 100644 --- a/src/test/java/com/google/api/generator/gapic/composer/rest/goldens/HttpJsonComplianceStub.golden +++ b/src/test/java/com/google/api/generator/gapic/composer/rest/goldens/HttpJsonComplianceStub.golden @@ -13,6 +13,7 @@ import com.google.api.gax.httpjson.ProtoMessageResponseParser; import com.google.api.gax.httpjson.ProtoRestSerializer; import com.google.api.gax.rpc.ClientContext; import com.google.api.gax.rpc.UnaryCallable; +import com.google.protobuf.TypeRegistry; import com.google.showcase.v1beta1.RepeatRequest; import com.google.showcase.v1beta1.RepeatResponse; import java.io.IOException; @@ -33,6 +34,8 @@ import javax.annotation.Generated; @Generated("by gapic-generator-java") @BetaApi("A restructuring of stub classes is planned, so this may break in the future") public class HttpJsonComplianceStub extends ComplianceStub { + private static final TypeRegistry typeRegistry = TypeRegistry.newBuilder().build(); + private static final ApiMethodDescriptor repeatDataBodyMethodDescriptor = ApiMethodDescriptor.newBuilder() @@ -62,6 +65,7 @@ public class HttpJsonComplianceStub extends ComplianceStub { .setResponseParser( ProtoMessageResponseParser.newBuilder() .setDefaultInstance(RepeatResponse.getDefaultInstance()) + .setDefaultTypeRegistry(typeRegistry) .build()) .build(); @@ -96,6 +100,7 @@ public class HttpJsonComplianceStub extends ComplianceStub { .setResponseParser( ProtoMessageResponseParser.newBuilder() .setDefaultInstance(RepeatResponse.getDefaultInstance()) + .setDefaultTypeRegistry(typeRegistry) .build()) .build(); @@ -130,6 +135,7 @@ public class HttpJsonComplianceStub extends ComplianceStub { .setResponseParser( ProtoMessageResponseParser.newBuilder() .setDefaultInstance(RepeatResponse.getDefaultInstance()) + .setDefaultTypeRegistry(typeRegistry) .build()) .build(); @@ -176,6 +182,7 @@ public class HttpJsonComplianceStub extends ComplianceStub { .setResponseParser( ProtoMessageResponseParser.newBuilder() .setDefaultInstance(RepeatResponse.getDefaultInstance()) + .setDefaultTypeRegistry(typeRegistry) .build()) .build(); @@ -220,6 +227,7 @@ public class HttpJsonComplianceStub extends ComplianceStub { .setResponseParser( ProtoMessageResponseParser.newBuilder() .setDefaultInstance(RepeatResponse.getDefaultInstance()) + .setDefaultTypeRegistry(typeRegistry) .build()) .build(); @@ -261,6 +269,7 @@ public class HttpJsonComplianceStub extends ComplianceStub { .setResponseParser( ProtoMessageResponseParser.newBuilder() .setDefaultInstance(RepeatResponse.getDefaultInstance()) + .setDefaultTypeRegistry(typeRegistry) .build()) .build(); @@ -315,27 +324,33 @@ public class HttpJsonComplianceStub extends ComplianceStub { HttpJsonCallSettings repeatDataBodyTransportSettings = HttpJsonCallSettings.newBuilder() .setMethodDescriptor(repeatDataBodyMethodDescriptor) + .setTypeRegistry(typeRegistry) .build(); HttpJsonCallSettings repeatDataBodyInfoTransportSettings = HttpJsonCallSettings.newBuilder() .setMethodDescriptor(repeatDataBodyInfoMethodDescriptor) + .setTypeRegistry(typeRegistry) .build(); HttpJsonCallSettings repeatDataQueryTransportSettings = HttpJsonCallSettings.newBuilder() .setMethodDescriptor(repeatDataQueryMethodDescriptor) + .setTypeRegistry(typeRegistry) .build(); HttpJsonCallSettings repeatDataSimplePathTransportSettings = HttpJsonCallSettings.newBuilder() .setMethodDescriptor(repeatDataSimplePathMethodDescriptor) + .setTypeRegistry(typeRegistry) .build(); HttpJsonCallSettings repeatDataPathResourceTransportSettings = HttpJsonCallSettings.newBuilder() .setMethodDescriptor(repeatDataPathResourceMethodDescriptor) + .setTypeRegistry(typeRegistry) .build(); HttpJsonCallSettings repeatDataPathTrailingResourceTransportSettings = HttpJsonCallSettings.newBuilder() .setMethodDescriptor(repeatDataPathTrailingResourceMethodDescriptor) + .setTypeRegistry(typeRegistry) .build(); this.repeatDataBodyCallable = diff --git a/test/integration/goldens/compute/com/google/cloud/compute/v1/stub/HttpJsonAddressesStub.java b/test/integration/goldens/compute/com/google/cloud/compute/v1/stub/HttpJsonAddressesStub.java index 9e5e90fbe1..679bfc1ae2 100644 --- a/test/integration/goldens/compute/com/google/cloud/compute/v1/stub/HttpJsonAddressesStub.java +++ b/test/integration/goldens/compute/com/google/cloud/compute/v1/stub/HttpJsonAddressesStub.java @@ -43,6 +43,7 @@ import com.google.cloud.compute.v1.ListAddressesRequest; import com.google.cloud.compute.v1.Operation; import com.google.cloud.compute.v1.Operation.Status; +import com.google.protobuf.TypeRegistry; import java.io.IOException; import java.util.ArrayList; import java.util.HashMap; @@ -60,6 +61,9 @@ @Generated("by gapic-generator-java") @BetaApi("A restructuring of stub classes is planned, so this may break in the future") public class HttpJsonAddressesStub extends AddressesStub { + private static final TypeRegistry typeRegistry = + TypeRegistry.newBuilder().add(Operation.getDescriptor()).build(); + private static final ApiMethodDescriptor aggregatedListMethodDescriptor = ApiMethodDescriptor.newBuilder() @@ -105,6 +109,7 @@ public class HttpJsonAddressesStub extends AddressesStub { .setResponseParser( ProtoMessageResponseParser.newBuilder() .setDefaultInstance(AddressAggregatedList.getDefaultInstance()) + .setDefaultTypeRegistry(typeRegistry) .build()) .build(); @@ -140,6 +145,7 @@ public class HttpJsonAddressesStub extends AddressesStub { .setResponseParser( ProtoMessageResponseParser.newBuilder() .setDefaultInstance(Operation.getDefaultInstance()) + .setDefaultTypeRegistry(typeRegistry) .build()) .setOperationSnapshotFactory( (DeleteAddressRequest request, Operation response) -> { @@ -190,6 +196,7 @@ public class HttpJsonAddressesStub extends AddressesStub { .setResponseParser( ProtoMessageResponseParser.newBuilder() .setDefaultInstance(Operation.getDefaultInstance()) + .setDefaultTypeRegistry(typeRegistry) .build()) .setOperationSnapshotFactory( (InsertAddressRequest request, Operation response) -> { @@ -244,6 +251,7 @@ public class HttpJsonAddressesStub extends AddressesStub { .setResponseParser( ProtoMessageResponseParser.newBuilder() .setDefaultInstance(AddressList.getDefaultInstance()) + .setDefaultTypeRegistry(typeRegistry) .build()) .build(); @@ -307,18 +315,22 @@ protected HttpJsonAddressesStub( aggregatedListTransportSettings = HttpJsonCallSettings.newBuilder() .setMethodDescriptor(aggregatedListMethodDescriptor) + .setTypeRegistry(typeRegistry) .build(); HttpJsonCallSettings deleteTransportSettings = HttpJsonCallSettings.newBuilder() .setMethodDescriptor(deleteMethodDescriptor) + .setTypeRegistry(typeRegistry) .build(); HttpJsonCallSettings insertTransportSettings = HttpJsonCallSettings.newBuilder() .setMethodDescriptor(insertMethodDescriptor) + .setTypeRegistry(typeRegistry) .build(); HttpJsonCallSettings listTransportSettings = HttpJsonCallSettings.newBuilder() .setMethodDescriptor(listMethodDescriptor) + .setTypeRegistry(typeRegistry) .build(); this.aggregatedListCallable = diff --git a/test/integration/goldens/compute/com/google/cloud/compute/v1/stub/HttpJsonRegionOperationsCallableFactory.java b/test/integration/goldens/compute/com/google/cloud/compute/v1/stub/HttpJsonRegionOperationsCallableFactory.java index 24e9ad539a..16d93e6f94 100644 --- a/test/integration/goldens/compute/com/google/cloud/compute/v1/stub/HttpJsonRegionOperationsCallableFactory.java +++ b/test/integration/goldens/compute/com/google/cloud/compute/v1/stub/HttpJsonRegionOperationsCallableFactory.java @@ -17,10 +17,11 @@ package com.google.cloud.compute.v1.stub; import com.google.api.core.BetaApi; -import com.google.api.gax.core.BackgroundResource; import com.google.api.gax.httpjson.HttpJsonCallSettings; import com.google.api.gax.httpjson.HttpJsonCallableFactory; +import com.google.api.gax.httpjson.HttpJsonOperationSnapshotCallable; import com.google.api.gax.httpjson.HttpJsonStubCallableFactory; +import com.google.api.gax.httpjson.longrunning.stub.OperationsStub; import com.google.api.gax.rpc.BatchingCallSettings; import com.google.api.gax.rpc.ClientContext; import com.google.api.gax.rpc.OperationCallSettings; @@ -28,6 +29,7 @@ import com.google.api.gax.rpc.PagedCallSettings; import com.google.api.gax.rpc.UnaryCallSettings; import com.google.api.gax.rpc.UnaryCallable; +import com.google.longrunning.Operation; import javax.annotation.Generated; // AUTO-GENERATED DOCUMENTATION AND CLASS. @@ -39,7 +41,7 @@ @Generated("by gapic-generator-java") @BetaApi public class HttpJsonRegionOperationsCallableFactory - implements HttpJsonStubCallableFactory { + implements HttpJsonStubCallableFactory { @Override public UnaryCallable createUnaryCallable( @@ -74,10 +76,18 @@ public UnaryCallable createBatchingCa @Override public OperationCallable createOperationCallable( - HttpJsonCallSettings httpJsonCallSettings, + HttpJsonCallSettings httpJsonCallSettings, OperationCallSettings callSettings, ClientContext clientContext, - BackgroundResource operationsStub) { - return null; + OperationsStub operationsStub) { + UnaryCallable innerCallable = + HttpJsonCallableFactory.createBaseUnaryCallable( + httpJsonCallSettings, callSettings.getInitialCallSettings(), clientContext); + HttpJsonOperationSnapshotCallable initialCallable = + new HttpJsonOperationSnapshotCallable( + innerCallable, + httpJsonCallSettings.getMethodDescriptor().getOperationSnapshotFactory()); + return HttpJsonCallableFactory.createOperationCallable( + callSettings, clientContext, operationsStub.longRunningClient(), initialCallable); } } diff --git a/test/integration/goldens/compute/com/google/cloud/compute/v1/stub/HttpJsonRegionOperationsStub.java b/test/integration/goldens/compute/com/google/cloud/compute/v1/stub/HttpJsonRegionOperationsStub.java index c167489173..0f081f8c40 100644 --- a/test/integration/goldens/compute/com/google/cloud/compute/v1/stub/HttpJsonRegionOperationsStub.java +++ b/test/integration/goldens/compute/com/google/cloud/compute/v1/stub/HttpJsonRegionOperationsStub.java @@ -37,6 +37,7 @@ import com.google.cloud.compute.v1.Operation; import com.google.cloud.compute.v1.Operation.Status; import com.google.cloud.compute.v1.WaitRegionOperationRequest; +import com.google.protobuf.TypeRegistry; import java.io.IOException; import java.util.ArrayList; import java.util.Arrays; @@ -55,6 +56,8 @@ @Generated("by gapic-generator-java") @BetaApi("A restructuring of stub classes is planned, so this may break in the future") public class HttpJsonRegionOperationsStub extends RegionOperationsStub { + private static final TypeRegistry typeRegistry = TypeRegistry.newBuilder().build(); + private static final ApiMethodDescriptor getMethodDescriptor = ApiMethodDescriptor.newBuilder() @@ -85,6 +88,7 @@ public class HttpJsonRegionOperationsStub extends RegionOperationsStub { .setResponseParser( ProtoMessageResponseParser.newBuilder() .setDefaultInstance(Operation.getDefaultInstance()) + .setDefaultTypeRegistry(typeRegistry) .build()) .setOperationSnapshotFactory( (GetRegionOperationRequest request, Operation response) -> { @@ -138,6 +142,7 @@ public class HttpJsonRegionOperationsStub extends RegionOperationsStub { .setResponseParser( ProtoMessageResponseParser.newBuilder() .setDefaultInstance(Operation.getDefaultInstance()) + .setDefaultTypeRegistry(typeRegistry) .build()) .build(); @@ -190,10 +195,12 @@ protected HttpJsonRegionOperationsStub( HttpJsonCallSettings getTransportSettings = HttpJsonCallSettings.newBuilder() .setMethodDescriptor(getMethodDescriptor) + .setTypeRegistry(typeRegistry) .build(); HttpJsonCallSettings waitTransportSettings = HttpJsonCallSettings.newBuilder() .setMethodDescriptor(waitMethodDescriptor) + .setTypeRegistry(typeRegistry) .build(); this.getCallable = From ce5da949dffe263e8c21eeb909f64f430e26ca91 Mon Sep 17 00:00:00 2001 From: Vadym Matsishevskyi <25311427+vam-google@users.noreply.github.com> Date: Tue, 5 Oct 2021 19:15:46 -0700 Subject: [PATCH 8/9] chore: Merge master (#854) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * feat: enable self signed jwt for gapic clients (#794) * feat: enable self signed jwt for gapic clients * resolve comments * update gax version * update goldens * update golden files * chore: release 2.1.0 (#827) Co-authored-by: release-please[bot] <55107282+release-please[bot]@users.noreply.github.com> * feat: REGAPIC initial implementation (#824) This includes: 1) Proper GRPC transcoding 2) Mimimal REST Operations (go make it compilable) 3) Rely on resource names for tests values generation (to not fail http url path validation) 4) Empty Server Streaming method implementation * feat: REGAPIC Multitransport implementation (grpc+rest) (#833) 1) Fully backward compatible with grpc-only GAPIC 2) Strictly speaking not fully backward compatible with rest-only REGAPIC (but is compatible for practical cases). See below for details. 3) Introduces the concept of default transport (is necessary to preserve backward-compabitility). The default behavior assumes grpc transport. Needed to unblock DIREGAPIC LRO. To be reviewed after submission * fix: [bazel] fix rest transport handling in assembly rule (#835) * Portable String <--> bytes conversion (#841) * Fix development doc (#837) * Fix dev doc * Clarify BUILD.bazel location * Remove warnings (unused vars, dead code, missing annotations, missing generic reference, etc) (#840) * Remove warnings for test code (#842) * Remove extraneous call (#844) * Fix preserving sorted order of a collection (#845) * feat: Add REST AIP-151 LRO suport Depends on https://github.com/googleapis/gax-java/pull/1484 * chore(deps): update dependency gradle to v7 (#713) [![WhiteSource Renovate](https://app.renovatebot.com/images/banner.svg)](https://renovatebot.com) This PR contains the following updates: | Package | Update | Change | |---|---|---| | [gradle](https://gradle.org) ([source](https://togithub.com/gradle/gradle)) | major | `4.10.3` -> `7.0.2` | --- ### Release Notes
    gradle/gradle ### [`v7.0.2`](https://togithub.com/gradle/gradle/releases/v7.0.2) This is a patch release for Gradle 7.0. [This fixes an issue with files system watching on certain Linux distributions](https://togithub.com/gradle/gradle/milestone/177?closed=1). We recommend users upgrade to 7.0.2 instead of 7.0. #### Upgrade Instructions Switch your build to use Gradle 7.0.2 by updating your wrapper: ./gradlew wrapper --gradle-version=7.0.2 See the [Gradle 6.x upgrade guide](https://docs.gradle.org/7.0.1/userguide/upgrading_version\_6.html#changes\_7.0) to learn about deprecations, breaking changes and other considerations when upgrading to Gradle 7.0.1. #### Reporting Problems If you find a problem with this release, please file a bug on [GitHub Issues](https://togithub.com/gradle/gradle/issues) adhering to our issue guidelines. If you're not sure you're encountering a bug, please use the [forum](https://discuss.gradle.org/c/help-discuss). ### [`v7.0.1`](https://togithub.com/gradle/gradle/releases/v7.0.1) This is a patch release for Gradle 7.0. [This fixes several issues reported against 7.0](https://togithub.com/gradle/gradle/milestone/173?closed=1). We recommend users upgrade to 7.0.1 instead of 7.0. #### Upgrade Instructions Switch your build to use Gradle 7.0.1 by updating your wrapper: ./gradlew wrapper --gradle-version=7.0.1 See the [Gradle 6.x upgrade guide](https://docs.gradle.org/7.0.1/userguide/upgrading_version\_6.html#changes\_7.0) to learn about deprecations, breaking changes and other considerations when upgrading to Gradle 7.0.1. #### Reporting Problems If you find a problem with this release, please file a bug on [GitHub Issues](https://togithub.com/gradle/gradle/issues) adhering to our issue guidelines. If you're not sure you're encountering a bug, please use the [forum](https://discuss.gradle.org/c/help-discuss). ### [`v7.0`](https://togithub.com/gradle/gradle/compare/v6.9.0...v7.0.0) ### [`v6.9`](https://togithub.com/gradle/gradle/compare/v6.8.3...v6.9.0) ### [`v6.8.3`](https://togithub.com/gradle/gradle/releases/v6.8.3) This is a patch release for Gradle 6.8. This fixes [a critical bug](https://togithub.com/gradle/gradle/issues/16144) present in Gradle 6.8, 6.8.1 and 6.8.2. [All issues fixed in this patch release](https://togithub.com/gradle/gradle/milestone/171?closed=1) Please don’t use the original 6.8 release or previous patch releases, and instead upgrade to 6.8.3. ##### Upgrade Instructions Switch your build to use Gradle 6.8.3 by updating your wrapper: ./gradlew wrapper --gradle-version=6.8.3 --gradle-distribution-sha256-sum 7faa7198769f872826c8ef4f1450f839ec27f0b4d5d1e51bade63667cbccd205 See the [Gradle 6.x upgrade guide](https://docs.gradle.org/6.8.3/userguide/upgrading_version\_6.html#changes\_6.8) to learn about deprecations, breaking changes and other considerations when upgrading to Gradle 6.8.3. ##### Reporting Problems If you find a problem with this release, please file a bug on [GitHub Issues](https://togithub.com/gradle/gradle/issues) adhering to our issue guidelines. If you're not sure you're encountering a bug, please use the [forum](https://discuss.gradle.org/c/help-discuss). ### [`v6.8.2`](https://togithub.com/gradle/gradle/releases/v6.8.2) This is a patch release for Gradle 6.8. This fixes several bugs in Gradle 6.8.1. [All issues fixed in this patch release](https://togithub.com/gradle/gradle/milestone/170?closed=1) Please don’t use the original 6.8 release or the 6.8.1, and instead upgrade to 6.8.2. ##### Upgrade Instructions Switch your build to use Gradle 6.8.2 by updating your wrapper: `./gradlew wrapper --gradle-version=6.8.2` See the [Gradle 6.x upgrade guide](https://docs.gradle.org/6.8.2/userguide/upgrading_version\_6.html#changes\_6.8) to learn about deprecations, breaking changes and other considerations when upgrading to Gradle 6.8.2. ##### Reporting Problems If you find a problem with this release, please file a bug on [GitHub Issues](https://togithub.com/gradle/gradle/issues) adhering to our issue guidelines. If you're not sure you're encountering a bug, please use the [forum](https://discuss.gradle.org/c/help-discuss). ### [`v6.8.1`](https://togithub.com/gradle/gradle/releases/v6.8.1) This is a patch release for Gradle 6.8. This fixes several critical bugs in Gradle 6.8. [All issues fixed in this patch release](https://togithub.com/gradle/gradle/milestone/168?closed=1) We recommend that you use Gradle 6.8.1 over the initial release of Gradle 6.8. #### Upgrade Instructions Switch your build to use Gradle 6.8.1 by updating your wrapper: `./gradlew wrapper --gradle-version=6.8.1` See the [Gradle 6.x upgrade guide](https://docs.gradle.org/6.8.1/userguide/upgrading_version\_6.html#changes\_6.8) to learn about deprecations, breaking changes and other considerations when upgrading to Gradle 6.8.1. #### Reporting Problems If you find a problem with this release, please file a bug on [GitHub Issues](https://togithub.com/gradle/gradle/issues) adhering to our issue guidelines. If you're not sure you're encountering a bug, please use the [forum](https://discuss.gradle.org/c/help-discuss). ### [`v6.8`](https://togithub.com/gradle/gradle/compare/v6.7.1...v6.8.0) ### [`v6.7.1`](https://togithub.com/gradle/gradle/releases/v6.7.1) This is a patch release for Gradle 6.7. This fixes several critical bugs in Gradle 6.7. [All issues fixed in this patch release](https://togithub.com/gradle/gradle/milestone/160?closed=1) We recommend that you use Gradle 6.7.1 over the initial release of Gradle 6.7. #### Upgrade Instructions Switch your build to use Gradle 6.7.1 by updating your wrapper: `./gradlew wrapper --gradle-version=6.7.1` See the [Gradle 6.x upgrade guide](https://docs.gradle.org/6.7.1/userguide/upgrading_version\_6.html#changes\_6.7) to learn about deprecations, breaking changes and other considerations when upgrading to Gradle 6.7.1. #### Reporting Problems If you find a problem with this release, please file a bug on [GitHub Issues](https://togithub.com/gradle/gradle/issues) adhering to our issue guidelines. If you're not sure you're encountering a bug, please use the [forum](https://discuss.gradle.org/c/help-discuss). ### [`v6.7`](https://togithub.com/gradle/gradle/compare/v6.6.1...v6.7.0) ### [`v6.6.1`](https://togithub.com/gradle/gradle/releases/v6.6.1) This is a patch release for Gradle 6.6. This fixes several critical bugs in Gradle 6.6. [All issues fixed in this patch release](https://togithub.com/gradle/gradle/milestone/155?closed=1) We recommend that you use Gradle 6.6.1 over the initial release of Gradle 6.6. #### Upgrade Instructions Switch your build to use Gradle 6.6.1 by updating your wrapper: `./gradlew wrapper --gradle-version=6.6.1` See the [Gradle 6.x upgrade guide](https://docs.gradle.org/6.6.1/userguide/upgrading_version\_6.html#changes\_6.6) to learn about deprecations, breaking changes and other considerations when upgrading to Gradle 6.6.1. #### Reporting Problems If you find a problem with this release, please file a bug on [GitHub Issues](https://togithub.com/gradle/gradle/issues) adhering to our issue guidelines. If you're not sure you're encountering a bug, please use the [forum](https://discuss.gradle.org/c/help-discuss). ### [`v6.6`](https://togithub.com/gradle/gradle/compare/v6.5.1...v6.6.0) ### [`v6.5.1`](https://togithub.com/gradle/gradle/releases/v6.5.1) This is a patch release for Gradle 6.5. This fixes several critical bugs in Gradle 6.5: - Regression: Gradle 6.5 cached builds cause IllegalStateException [#​13367](https://togithub.com/gradle/gradle/issues/13367) - Regression: Compile classpath configuration is not deterministic [#​13555](https://togithub.com/gradle/gradle/issues/13555) - Regression: Class cast exception when GStrings are used with System.getProperty [#​13569](https://togithub.com/gradle/gradle/issues/13569) - And a number of dependency graph resolution errors ([#​13251](https://togithub.com/gradle/gradle/issues/13251), [#​13316](https://togithub.com/gradle/gradle/issues/13316), [#​13329](https://togithub.com/gradle/gradle/issues/13329), [#​13551](https://togithub.com/gradle/gradle/issues/13551)) [All issues fixed in this patch release](https://togithub.com/gradle/gradle/milestone/147?closed=1) We recommend that you use Gradle 6.5.1 over the initial release of Gradle 6.5. #### Upgrade Instructions Switch your build to use Gradle 6.5.1 by updating your wrapper: `./gradlew wrapper --gradle-version=6.5.1` See the [Gradle 6.x upgrade guide](https://docs.gradle.org/6.5.1/userguide/upgrading_version\_6.html#changes\_6.5) to learn about deprecations, breaking changes and other considerations when upgrading to Gradle 6.5.1. #### Reporting Problems If you find a problem with this release, please file a bug on [GitHub Issues](https://togithub.com/gradle/gradle/issues) adhering to our issue guidelines. If you're not sure you're encountering a bug, please use the [forum](https://discuss.gradle.org/c/help-discuss). ### [`v6.5`](https://togithub.com/gradle/gradle/compare/v6.4.1...v6.5.0) ### [`v6.4.1`](https://togithub.com/gradle/gradle/releases/v6.4.1) This is a patch release for Gradle 6.4. This fixes several critical bugs in Gradle 6.4: - Regression: Different daemons are used between IDE and CLI builds for the same project [#​13069](https://togithub.com/gradle/gradle/issues/13069) - Regression: Main-Class attribute always added to jar manifest when using application plugin [#​13057](https://togithub.com/gradle/gradle/issues/13057) [All issues fixed in this patch release](https://togithub.com/gradle/gradle/milestone/145?closed=1) We recommend that you use Gradle 6.4.1 over the initial release of Gradle 6.4. #### Upgrade Instructions Switch your build to use Gradle 6.4.1 by updating your wrapper: `./gradlew wrapper --gradle-version=6.4.1` See the [Gradle 6.x upgrade guide](https://docs.gradle.org/6.4.1/userguide/upgrading_version\_6.html#changes\_6.4) to learn about deprecations, breaking changes and other considerations when upgrading to Gradle 6.4.1. #### Reporting Problems If you find a problem with this release, please file a bug on [GitHub Issues](https://togithub.com/gradle/gradle/issues) adhering to our issue guidelines. If you're not sure you're encountering a bug, please use the [forum](https://discuss.gradle.org/c/help-discuss). ### [`v6.4`](https://togithub.com/gradle/gradle/compare/v6.3.0...v6.4.0) ### [`v6.3`](https://togithub.com/gradle/gradle/compare/v6.2.2...v6.3.0) ### [`v6.2.2`](https://togithub.com/gradle/gradle/releases/v6.2.2) This is a patch release for Gradle 6.2. This fixes a critical bug in Gradle 6.2: - Multi-project build use the properties of the rootProject for all included builds. [#​12381](https://togithub.com/gradle/gradle/issues/12381) [All issues fixed](https://togithub.com/gradle/gradle/milestone/134?closed=1) We recommend that you use Gradle 6.2.2 over the initial release of Gradle 6.2. [Read the full release notes](https://docs.gradle.org/6.2.2/release-notes.html) #### Upgrade Instructions Switch your build to use Gradle 6.2.2 by updating your wrapper: `./gradlew wrapper --gradle-version=6.2.2` See the [Gradle 6.x upgrade guide](https://docs.gradle.org/6.2.2/userguide/upgrading_version\_6.html#changes\_6.2) to learn about deprecations, breaking changes and other considerations when upgrading to Gradle 6.2.2. #### Reporting Problems If you find a problem with this release, please file a bug on [GitHub Issues](https://togithub.com/gradle/gradle/issues) adhering to our issue guidelines. If you're not sure you're encountering a bug, please use the [forum](https://discuss.gradle.org/c/help-discuss). ### [`v6.2.1`](https://togithub.com/gradle/gradle/releases/v6.2.1) This is a patch release for Gradle 6.2. This fixes several critical bugs in Gradle 6.2: - Project name disambiguation causes project / external dependency conflicts to be missed. [#​12315](https://togithub.com/gradle/gradle/issues/12315) - IdeaModelBuilder does not provide groovy-all as compile dep for buildSrc [#​12274](https://togithub.com/gradle/gradle/issues/12274) - Gradle crashes if GRADLE_RO_DEP_CACHE is set and it cannot create modules-2 directory within it [#​12293](https://togithub.com/gradle/gradle/issues/12293) [All issues fixed](https://togithub.com/gradle/gradle/milestone/133?closed=1) We recommend that you use Gradle 6.2.1 over the initial release of Gradle 6.2. [Read the full release notes](https://docs.gradle.org/6.2.1/release-notes.html) #### Upgrade Instructions Switch your build to use Gradle 6.2.1 by updating your wrapper: `./gradlew wrapper --gradle-version=6.2.1` See the [Gradle 6.x upgrade guide](https://docs.gradle.org/6.2.1/userguide/upgrading_version\_6.html#changes\_6.2) to learn about deprecations, breaking changes and other considerations when upgrading to Gradle 6.2.1. #### Reporting Problems If you find a problem with this release, please file a bug on [GitHub Issues](https://togithub.com/gradle/gradle/issues) adhering to our issue guidelines. If you're not sure you're encountering a bug, please use the [forum](https://discuss.gradle.org/c/help-discuss). ### [`v6.2`](https://togithub.com/gradle/gradle/compare/v6.1.1...v6.2.0) ### [`v6.1.1`](https://togithub.com/gradle/gradle/releases/v6.1.1) This is a patch release for Gradle 6.1. This fixes several critical bugs in Gradle 6.1: - Plugins using kotlin-dsl and compiled with 6.1 are incompatible with Gradle 6.0 [#​11947](https://togithub.com/gradle/gradle/issues/11947) - Missing fixed issues from Gradle 6.1 release notes [#​11954](https://togithub.com/gradle/gradle/issues/11954) - Memory regression when resolving large artifacts while computing checksums [#​11966](https://togithub.com/gradle/gradle/issues/11966) - Gradle 6.1 generates an empty .gradle and gradle directories on each execution in subproject directories [#​11971](https://togithub.com/gradle/gradle/issues/11971) [All issues fixed](https://togithub.com/gradle/gradle/issues?q=is%3Aclosed+milestone%3A6.1.1) We recommend that you use Gradle 6.1.1 over the initial release of Gradle 6.1. [Read the full release notes](https://docs.gradle.org/6.1.1/release-notes.html) #### Upgrade Instructions Switch your build to use Gradle 6.1.1 by updating your wrapper: `./gradlew wrapper --gradle-version=6.1.1` See the [Gradle 6.x upgrade guide](https://docs.gradle.org/6.1.1/userguide/upgrading_version\_6.html#changes\_6.1) to learn about deprecations, breaking changes and other considerations when upgrading to Gradle 6.1.x. #### Reporting Problems If you find a problem with this release, please file a bug on [GitHub Issues](https://togithub.com/gradle/gradle/issues) adhering to our issue guidelines. If you're not sure you're encountering a bug, please use the [forum](https://discuss.gradle.org/c/help-discuss). ### [`v6.1`](https://togithub.com/gradle/gradle/compare/v6.0.1...v6.1.0) ### [`v6.0.1`](https://togithub.com/gradle/gradle/releases/v6.0.1) This is a patch release for Gradle 6.0. This fixes several critical bugs in Gradle 6.0: - Incremental Java compilation is broken with Android 3.5.1 and Gradle 6.0 [#​11330](https://togithub.com/gradle/gradle/issues/11330) - Unable to use a Provider as an artifact for the maven-publish plugin [#​11054](https://togithub.com/gradle/gradle/issues/11054) - Implicit capabilities not always applied/detected [#​11300](https://togithub.com/gradle/gradle/issues/11300) - maven-metadata.xml SHA256 and SHA512 checksums prevent publishing to Nexus [#​11308](https://togithub.com/gradle/gradle/issues/11308) - Unable to properly resolve dynamic dependencies from mavenLocal() repo [#​11321](https://togithub.com/gradle/gradle/issues/11321) - Kotlin DSL: `fileTree(mapOf(...))` has unexpected behavior [#​11335](https://togithub.com/gradle/gradle/issues/11335) - Attribute disambiguation rule for 'org.gradle.category' can cause unexpected type exception [#​11365](https://togithub.com/gradle/gradle/issues/11365) [All issues fixed](https://togithub.com/gradle/gradle/issues?q=is%3Aclosed+milestone%3A6.0.1) We recommend that you use Gradle 6.0.1 over the initial release of Gradle 6.0. #### Upgrade Instructions Switch your build to use Gradle 6.0.1 by updating your wrapper properties: `./gradlew wrapper --gradle-version=6.0.1` Standalone downloads are available at https://gradle.org/install. #### Reporting Problems If you find a problem with Gradle, please file a bug on [GitHub Issues](https://togithub.com/gradle/gradle/issues) adhering to our issue guidelines. If you're not sure you're encountering a bug, please use the [forum](https://discuss.gradle.org/c/help-discuss). ### [`v5.6.4`](https://togithub.com/gradle/gradle/releases/v5.6.4) This bug-fix release contains all changes from 5.6.1 through 5.6.3 as well as: - Can't configure kotlinOptions after upgrade to gradle 5.6.3 using kotlin-dsl [#​11083](https://togithub.com/gradle/gradle/issues/11083) - Slow localhost look-up on macOS [#​11134](https://togithub.com/gradle/gradle/issues/11134) We recommend that you use Gradle 5.6.4 over any other 5.6.x release. #### Upgrade Instructions Switch your build to use Gradle 5.6.4 by updating your wrapper properties: `./gradlew wrapper --gradle-version=5.6.4` Standalone downloads are available at https://gradle.org/install. #### Reporting Problems If you find a problem with Gradle, please file a bug on [GitHub Issues](https://togithub.com/gradle/gradle/issues) adhering to our issue guidelines. If you're not sure you're encountering a bug, please use the [forum](https://discuss.gradle.org/c/help-discuss). ### [`v5.6.3`](https://togithub.com/gradle/gradle/releases/v5.6.3) This bug-fix release contains all changes from 5.6.1 and 5.6.2 as well as: - Let Kotlin DSL gracefully handle lambdas registered as extensions (5.6.3) [#​11014](https://togithub.com/gradle/gradle/issues/11014) - Gradle Module Metadata compatibility for unique snapshots [#​11050](https://togithub.com/gradle/gradle/issues/11050) - maven-publish publishes jars with wrong extension for known jar packagings like 'ejb' in 5.6 [#​10555](https://togithub.com/gradle/gradle/issues/10555) - Regression in 5.5 when using dependency constraints for non-jar dependencies without a POM [#​10948](https://togithub.com/gradle/gradle/issues/10948) - resolution failure when dependency locks and kotlin-dsl plugin are present [#​10697](https://togithub.com/gradle/gradle/issues/10697) - Non-Kotlin extensions crash the build when using Kotlin DSL + Kotlin plugins [#​10729](https://togithub.com/gradle/gradle/issues/10729) - Sporadic build failures with build-scan due to an overlapping ID assignment https://github.com/gradle/gradle/pull/10286 - Prevent StackOverflowException caused by excessive 'or' via PatternMatcher [#​10330](https://togithub.com/gradle/gradle/issues/10330) We recommend that you use Gradle 5.6.3 over any other 5.6.x release. #### Upgrade Instructions Switch your build to use Gradle 5.6.3 by updating your wrapper properties: `./gradlew wrapper --gradle-version=5.6.3` Standalone downloads are available at https://gradle.org/install. #### Reporting Problems If you find a problem with Gradle, please file a bug on [GitHub Issues](https://togithub.com/gradle/gradle/issues) adhering to our issue guidelines. If you're not sure you're encountering a bug, please use the [forum](https://discuss.gradle.org/c/help-discuss). ### [`v5.6.2`](https://togithub.com/gradle/gradle/releases/v5.6.2) This bug-fix release contains changes to Gradle 5.6.1: - Duplicate entry in generated .classpath file in Gradle >= 5.6 ([#​10393](https://togithub.com/gradle/gradle/issues/10393)) - Memory leak when using tasks that use Worker API and process isolation ([#​10411](https://togithub.com/gradle/gradle/issues/10411)) We recommend that you use Gradle 5.6.2 over 5.6.1. #### Upgrade Instructions Switch your build to use Gradle 5.6.2 by updating your wrapper properties: `./gradlew wrapper --gradle-version=5.6.2` Standalone downloads are available at https://gradle.org/install. #### Reporting Problems If you find a problem with Gradle, please file a bug on [GitHub Issues](https://togithub.com/gradle/gradle/issues) adhering to our issue guidelines. If you're not sure you're encountering a bug, please use the [forum](https://discuss.gradle.org/c/help-discuss). ### [`v5.6.1`](https://togithub.com/gradle/gradle/releases/v5.6.1) This bug-fix release contains changes to Gradle 5.6: - Unable to publish artifacts with custom classifier/extension from java project with Gradle 5.6 (https://github.com/gradle/gradle/issues/10287) - Regression in 5.6 signArchives (Duplicate key) (https://github.com/gradle/gradle/issues/10302) - Regression setting version for ArchiveTasks in 5.6 (https://github.com/gradle/gradle/issues/10311) - A failure occurred while executing org.jetbrains.kotlin.compilerRunner.GradleKotlinCompilerWork (https://github.com/gradle/gradle/issues/10317) - DirectoryFileTree breaks SourceTask since 5.6 (https://github.com/gradle/gradle/issues/10322) - Regression: Unable to pass java.util.Properties object using Worker API in Gradle 5.6 (https://github.com/gradle/gradle/issues/10323) - Unable to publish multiple publications with same coordinates (https://github.com/gradle/gradle/issues/10333) - Gradle 5.6 - Resolving resources from buildSrc or plugins (https://github.com/gradle/gradle/issues/10347) We recommend that you use Gradle 5.6.1 over 5.6. #### Upgrade Instructions Switch your build to use Gradle 5.6.1 by updating your wrapper properties: `./gradlew wrapper --gradle-version=5.6.1` Standalone downloads are available at https://gradle.org/install. #### Reporting Problems If you find a problem with Gradle, please file a bug on [GitHub Issues](https://togithub.com/gradle/gradle/issues) adhering to our issue guidelines. If you're not sure you're encountering a bug, please use the [forum](https://discuss.gradle.org/c/help-discuss). ### [`v5.5.1`](https://togithub.com/gradle/gradle/releases/v5.5.1) This bug-fix release contains three changes to Gradle 5.5: - Combination of errorprone-gradle-plugin and options.fork = true causes Java compilation to fail in Gradle 5.5 [#​9897](https://togithub.com/gradle/gradle/issues/9897) - Using dependency declaration `gradleKotlinDsl()` fails with 5.5 [#​9919](https://togithub.com/gradle/gradle/issues/9919) - Chain of transitives aligned by same platform can lead to broken resolution [#​9882](https://togithub.com/gradle/gradle/issues/9882) We recommend that you use Gradle 5.5.1 over 5.5. #### Upgrade Instructions Switch your build to use Gradle 5.5.1 by updating your wrapper properties: `./gradlew wrapper --gradle-version=5.5.1` Standalone downloads are available at https://gradle.org/install. #### Reporting Problems If you find a problem with Gradle, please file a bug on [GitHub Issues](https://togithub.com/gradle/gradle/issues) adhering to our issue guidelines. If you're not sure you're encountering a bug, please use the [forum](https://discuss.gradle.org/c/help-discuss). ### [`v5.4.1`](https://togithub.com/gradle/gradle/releases/v5.4.1) This bug-fix release contains two changes to Gradle 5.4: - Fix inconsistent classpath ordering when dependencies have lots of excludes - https://github.com/gradle/gradle/issues/9197 - Kotlin DSL IDEA script editor can't find JDK classes with Gradle 5.4 if *Gradle JVM* != *Project SDK* - https://github.com/gradle/gradle/issues/9195 We recommend that you use Gradle 5.4.1 over 5.4. #### Upgrade Instructions Switch your build to use Gradle 5.4.1 by updating your wrapper properties: `./gradlew wrapper --gradle-version=5.4.1` Standalone downloads are available at https://gradle.org/install. #### Reporting Problems If you find a problem with Gradle, please file a bug on [GitHub Issues](https://togithub.com/gradle/gradle/issues) adhering to our issue guidelines. If you're not sure you're encountering a bug, please use the [forum](https://discuss.gradle.org/c/help-discuss). ### [`v5.3.1`](https://togithub.com/gradle/gradle/releases/v5.3.1) This bug-fix release contains several changes to Gradle 5.3, notably: - Unable to use `java-platform` and `maven-publish` in multi-project: https://github.com/gradle/gradle/issues/8845 - Unexpected exception when adding a plugin on `buildSrc` compile classpath: https://github.com/gradle/kotlin-dsl/issues/1363 We recommend that you use Gradle 5.3.1 over 5.3. #### Upgrade Instructions Switch your build to use Gradle 5.3.1 by updating your wrapper properties: `./gradlew wrapper --gradle-version=5.3.1` Standalone downloads are available at https://gradle.org/install. #### Reporting Problems If you find a problem with Gradle, please file a bug on [GitHub Issues](https://togithub.com/gradle/gradle/issues) adhering to our issue guidelines. If you're not sure you're encountering a bug, please use the [forum](https://discuss.gradle.org/c/help-discuss). ### [`v5.2.1`](https://togithub.com/gradle/gradle/releases/v5.2.1) This bug-fix release contains several changes to Gradle 5.2, notably: - Checkstyle issues with a single source file: https://github.com/gradle/gradle/issues/8394 - BOM support conflicts: https://github.com/gradle/gradle/issues/8420 We recommend that you use Gradle 5.2.1 over 5.2. #### Upgrade Instructions Switch your build to use Gradle 5.2.1 by updating your wrapper properties: `./gradlew wrapper --gradle-version=5.2.1` Standalone downloads are available at https://gradle.org/install. #### Reporting Problems If you find a problem with Gradle, please file a bug on [GitHub Issues](https://togithub.com/gradle/gradle/issues) adhering to our issue guidelines. If you're not sure you're encountering a bug, please use the [forum](https://discuss.gradle.org/c/help-discuss). ### [`v5.1.1`](https://togithub.com/gradle/gradle/releases/v5.1.1) This bug-fix release contains several changes to Gradle 5.1, notably: - A daemon memory leak affecting all projects https://github.com/gradle/gradle/issues/8142 - Incremental Java compilation https://github.com/gradle/gradle/issues/8194 - A fix to Gradle's generated Javadoc in 5.1 https://github.com/gradle/gradle/issues/8183 We recommend that you use Gradle 5.1.1 over 5.1. #### Upgrade Instructions Switch your build to use Gradle 5.1.1 by updating your wrapper properties: `./gradlew wrapper --gradle-version=5.1.1` Standalone downloads are available at https://gradle.org/install. #### Reporting Problems If you find a problem with Gradle, please file a bug on [GitHub Issues](https://togithub.com/gradle/gradle/issues) adhering to our issue guidelines. If you're not sure you're encountering a bug, please use the [forum](https://discuss.gradle.org/c/help-discuss).
    --- ### Configuration πŸ“… **Schedule**: At any time (no schedule defined). 🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied. ♻️ **Rebasing**: Renovate will not automatically rebase this PR, because other commits have been found. πŸ”• **Ignore**: Close this PR and you won't be reminded about this update again. --- - [ ] If you want to rebase/retry this PR, check this box. --- This PR has been generated by [WhiteSource Renovate](https://renovate.whitesourcesoftware.com). View repository job log [here](https://app.renovatebot.com/dashboard#github/googleapis/gapic-generator-java). * chore(deps): update dependency bazel_skylib to v1.0.3 (#722) [![WhiteSource Renovate](https://app.renovatebot.com/images/banner.svg)](https://renovatebot.com) This PR contains the following updates: | Package | Type | Update | Change | |---|---|---|---| | [bazel_skylib](https://togithub.com/bazelbuild/bazel-skylib) | http_archive | patch | `1.0.2` -> `1.0.3` | --- ### Release Notes
    bazelbuild/bazel-skylib ### [`v1.0.3`](https://togithub.com/bazelbuild/bazel-skylib/releases/1.0.3) [Compare Source](https://togithub.com/bazelbuild/bazel-skylib/compare/1.0.2...1.0.3) **New Features** - copy_file: Add parameter to allow symlinks ([#​252](https://togithub.com/bazelbuild/bazel-skylib/issues/252)) - Create Gazelle language for Starlark ([#​251](https://togithub.com/bazelbuild/bazel-skylib/issues/251)) - Create a helper rule (`select_file`) for selecting a file from outputs of another rule ([#​233](https://togithub.com/bazelbuild/bazel-skylib/issues/233)) **Significant Changes** - Move Gazelle extension to //gazelle/bzl and change package name - Stop depending on rules_pkg through the federation. ([#​259](https://togithub.com/bazelbuild/bazel-skylib/issues/259)) **Incompatible Changes** - Remove links to maprules ([#​213](https://togithub.com/bazelbuild/bazel-skylib/issues/213)) - Remove old_sets.bzl ([#​231](https://togithub.com/bazelbuild/bazel-skylib/issues/231)) It has been deprecated for a while, the code is not really compatible with Bazel depset-related changes. **Contributors** Andrew Z Allen, Bocete, Bor Kae Hwang, irengrig, Jay Conrod, Jonathan B Coe, Marc Plano-Lesay, Robbert van Ginkel, Thomas Van Lenten, Yannic, and the Bazel team. **WORKSPACE setup** ``` load("@​bazel_tools//tools/build_defs/repo:http.bzl", "http_archive") http_archive( name = "bazel_skylib", urls = [ "https://github.com/bazelbuild/bazel-skylib/releases/download/1.0.3/bazel-skylib-1.0.3.tar.gz", "https://mirror.bazel.build/github.com/bazelbuild/bazel-skylib/releases/download/1.0.3/bazel-skylib-1.0.3.tar.gz", ], sha256 = "1c531376ac7e5a180e0237938a2536de0c54d93f5c278634818e0efc952dd56c", ) load("@​bazel_skylib//:workspace.bzl", "bazel_skylib_workspace") bazel_skylib_workspace() ``` **Using the rules** See [the source](https://togithub.com/bazelbuild/bazel-skylib/tree/1.0.3).
    --- ### Configuration πŸ“… **Schedule**: At any time (no schedule defined). 🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied. ♻️ **Rebasing**: Renovate will not automatically rebase this PR, because other commits have been found. πŸ”• **Ignore**: Close this PR and you won't be reminded about this update again. --- - [ ] If you want to rebase/retry this PR, check this box. --- This PR has been generated by [WhiteSource Renovate](https://renovate.whitesourcesoftware.com). View repository job log [here](https://app.renovatebot.com/dashboard#github/googleapis/gapic-generator-java). * chore(deps): update dependency bazel_skylib to v1.1.1 (#849) [![WhiteSource Renovate](https://app.renovatebot.com/images/banner.svg)](https://renovatebot.com) This PR contains the following updates: | Package | Type | Update | Change | |---|---|---|---| | [bazel_skylib](https://togithub.com/bazelbuild/bazel-skylib) | http_archive | minor | `1.0.3` -> `1.1.1` | --- ### Release Notes
    bazelbuild/bazel-skylib ### [`v1.1.1`](https://togithub.com/bazelbuild/bazel-skylib/releases/1.1.1) [Compare Source](https://togithub.com/bazelbuild/bazel-skylib/compare/1.0.3...1.1.1) Release 1.1.1 (initially tagged as 1.1.0) **New Features** - Gazelle: support relative imports ([#​271](https://togithub.com/bazelbuild/bazel-skylib/issues/271)) and imports from `@bazel_tools` ([#​273](https://togithub.com/bazelbuild/bazel-skylib/issues/273)) - Add partial.is_instance() ([#​276](https://togithub.com/bazelbuild/bazel-skylib/issues/276)) - Allow unittest.suite() to accept partial calls of test rules ([#​276](https://togithub.com/bazelbuild/bazel-skylib/issues/276)) - Allow specifying additional aspects to target under test in analysistest.make() ([#​299](https://togithub.com/bazelbuild/bazel-skylib/issues/299)) - Add Windows support for build_test ([#​302](https://togithub.com/bazelbuild/bazel-skylib/issues/302)) **Incompatible Changes** - structs.to_dict() ignores deprecated to_json()/to_proto() methods ([#​295](https://togithub.com/bazelbuild/bazel-skylib/issues/295)) **Contributors** aiuto, alandonovan, Alex Eagle, Alexandre Rostovtsev, Andrew Z Allen, c-parsons, Christopher Sauer, Daniel Wagner-Hall, David Sanderson, dmaclach, Laurent Le Brun, Mansur, Olek Wojnar, Philipp Wollermann, River, Samuel Giddins, Thaler Benedek **WORKSPACE setup** ``` load("@​bazel_tools//tools/build_defs/repo:http.bzl", "http_archive") http_archive( name = "bazel_skylib", urls = [ "https://github.com/bazelbuild/bazel-skylib/releases/download/1.1.1/bazel-skylib-1.1.1.tar.gz", "https://mirror.bazel.build/github.com/bazelbuild/bazel-skylib/releases/download/1.1.1/bazel-skylib-1.1.1.tar.gz", ], sha256 = "c6966ec828da198c5d9adbaa94c05e3a1c7f21bd012a0b29ba8ddbccb2c93b0d", ) load("@​bazel_skylib//:workspace.bzl", "bazel_skylib_workspace") bazel_skylib_workspace() ``` **Using the rules** See [the source](https://togithub.com/bazelbuild/bazel-skylib/tree/1.1.1).
    --- ### Configuration πŸ“… **Schedule**: At any time (no schedule defined). 🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied. β™» **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox. πŸ”• **Ignore**: Close this PR and you won't be reminded about this update again. --- - [ ] If you want to rebase/retry this PR, check this box. --- This PR has been generated by [WhiteSource Renovate](https://renovate.whitesourcesoftware.com). View repository job log [here](https://app.renovatebot.com/dashboard#github/googleapis/gapic-generator-java). * chore(deps): update dependency gradle to v7.2 (#848) [![WhiteSource Renovate](https://app.renovatebot.com/images/banner.svg)](https://renovatebot.com) This PR contains the following updates: | Package | Update | Change | |---|---|---| | [gradle](https://gradle.org) ([source](https://togithub.com/gradle/gradle)) | minor | `7.0.2` -> `7.2` | --- ### Release Notes
    gradle/gradle ### [`v7.2`](https://togithub.com/gradle/gradle/compare/v7.1.1...v7.2.0) ### [`v7.1.1`](https://togithub.com/gradle/gradle/releases/v7.1.1) This is a patch release for Gradle 7.1. It fixes the following issues: - [#​17488](https://togithub.com/gradle/gradle/issues/17488) Many Micronaut builds failing with NPE with Gradle 7.1 & JDK 8 - [#​17548](https://togithub.com/gradle/gradle/issues/17548) \[Configuration cache] Task not up-to-date for SantaTracker - [#​17542](https://togithub.com/gradle/gradle/issues/17542) \[Configuration cache] Filtered FC with mapped elements stored incorrectly We recommend users upgrade to 7.1.1 instead of 7.1. #### Upgrade Instructions Switch your build to use Gradle 7.1.1 by updating your wrapper: ./gradlew wrapper --gradle-version=7.1.1 See the [Gradle 7.x upgrade guide](https://docs.gradle.org/7.1.1/userguide/upgrading_version\_7.html#changes\_7.1) to learn about deprecations, breaking changes and other considerations when upgrading to Gradle 7.1.1. #### Reporting Problems If you find a problem with this release, please file a bug on [GitHub Issues](https://togithub.com/gradle/gradle/issues) adhering to our issue guidelines. If you're not sure you're encountering a bug, please use the [forum](https://discuss.gradle.org/c/help-discuss). ### [`v7.1`](https://togithub.com/gradle/gradle/compare/v7.0.2...v7.1.0)
    --- ### Configuration πŸ“… **Schedule**: At any time (no schedule defined). 🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied. β™» **Rebasing**: Renovate will not automatically rebase this PR, because other commits have been found. πŸ”• **Ignore**: Close this PR and you won't be reminded about this update again. --- - [ ] If you want to rebase/retry this PR, check this box. --- This PR has been generated by [WhiteSource Renovate](https://renovate.whitesourcesoftware.com). View repository job log [here](https://app.renovatebot.com/dashboard#github/googleapis/gapic-generator-java). * chore: rename default branch to main (#851) * chore: merge changes from master Co-authored-by: arithmetic1728 <58957152+arithmetic1728@users.noreply.github.com> Co-authored-by: release-please[bot] <55107282+release-please[bot]@users.noreply.github.com> Co-authored-by: Chanseok Oh Co-authored-by: WhiteSource Renovate Co-authored-by: Neenu Shaji --- .github/release-please.yml | 2 +- .github/workflows/ci.yaml | 4 +- DEVELOPMENT.md | 26 ++++++++--- README.md | 2 +- WORKSPACE | 6 +-- .../gradle/wrapper/gradle-wrapper.properties | 2 +- .../generator/engine/ast/AnnotationNode.java | 2 +- .../engine/ast/ArithmeticOperationExpr.java | 2 + .../engine/ast/AssignmentOperationExpr.java | 1 + .../generator/engine/ast/BlockComment.java | 1 + .../engine/ast/ConcreteReference.java | 12 ++--- .../api/generator/engine/ast/EnumRefExpr.java | 1 + .../google/api/generator/engine/ast/Expr.java | 1 + .../engine/ast/LogicalOperationExpr.java | 1 + .../engine/ast/MethodDefinition.java | 8 ++-- .../generator/engine/ast/NewObjectExpr.java | 1 + .../api/generator/engine/ast/ObjectValue.java | 2 + .../generator/engine/ast/OperationExpr.java | 2 + .../api/generator/engine/ast/Reference.java | 1 + .../engine/ast/ReferenceConstructorExpr.java | 3 +- .../engine/ast/RelationalOperationExpr.java | 1 + .../api/generator/engine/ast/Statement.java | 1 + .../engine/ast/StringObjectValue.java | 1 + .../api/generator/engine/ast/TypeNode.java | 22 ++------- .../engine/ast/UnaryOperationExpr.java | 3 ++ .../engine/writer/ImportWriterVisitor.java | 3 +- .../engine/writer/JavaWriterVisitor.java | 5 ++- .../comment/ServiceClientCommentComposer.java | 1 - .../comment/SettingsCommentComposer.java | 1 - ...ctServiceCallableFactoryClassComposer.java | 2 +- .../AbstractServiceClientClassComposer.java | 24 +--------- ...bstractServiceClientTestClassComposer.java | 5 +-- .../AbstractServiceSettingsClassComposer.java | 9 ++-- .../AbstractServiceStubClassComposer.java | 2 +- ...tractServiceStubSettingsClassComposer.java | 5 +-- ...ractTransportServiceStubClassComposer.java | 2 +- .../common/BatchingDescriptorComposer.java | 8 +--- .../common/RetrySettingsComposer.java | 2 +- .../defaultvalue/DefaultValueComposer.java | 3 -- .../grpc/GrpcServiceStubClassComposer.java | 5 +-- .../grpc/MockServiceClassComposer.java | 2 +- .../grpc/MockServiceImplClassComposer.java | 2 +- .../grpc/ServiceClientTestClassComposer.java | 5 +-- .../ServiceStubSettingsClassComposer.java | 2 +- .../ResourceNameHelperClassComposer.java | 13 ++---- .../rest/ServiceClientTestClassComposer.java | 1 - .../gapic/composer/store/TypeStore.java | 6 +-- .../BatchingSettingsConfigParser.java | 7 ++- .../GapicLanguageSettingsParser.java | 5 ++- .../GapicLroRetrySettingsParser.java | 5 ++- .../protoparser/MethodSignatureParser.java | 11 ----- .../generator/gapic/protoparser/Parser.java | 20 ++++----- .../gapic/protoparser/ServiceYamlParser.java | 4 +- .../gapic/protoparser/TypeParser.java | 5 --- .../generator/gapic/protowriter/Writer.java | 8 ++-- .../com/google/api/generator/util/Trie.java | 23 +++++----- .../engine/JavaCodeGeneratorTest.java | 5 +-- .../engine/ast/AnonymousClassExprTest.java | 31 +++++-------- .../generator/engine/ast/CastExprTest.java | 2 - .../engine/ast/ConcreteReferenceTest.java | 6 +-- .../engine/ast/ForStatementTest.java | 14 +++--- .../engine/ast/IdentifierNodeTest.java | 2 +- .../engine/ast/JavaDocCommentTest.java | 2 +- .../engine/ast/NewObjectExprTest.java | 2 +- .../engine/ast/NullObjectValueTest.java | 2 +- .../engine/ast/PrimitiveValueTest.java | 2 +- .../generator/engine/ast/ReferenceTest.java | 4 +- .../generator/engine/ast/ThrowExprTest.java | 2 +- .../engine/ast/TryCatchStatementTest.java | 45 +++++++------------ .../generator/engine/ast/TypeNodeTest.java | 4 +- .../engine/ast/VaporReferenceTest.java | 7 ++- .../generator/engine/ast/VariableTest.java | 2 +- .../writer/ImportWriterVisitorTest.java | 6 +-- .../engine/writer/JavaWriterVisitorTest.java | 13 +----- .../BatchingDescriptorComposerTest.java | 4 +- .../common/RetrySettingsComposerTest.java | 9 +--- .../composer/common/TestProtoLoader.java | 4 +- .../DefaultValueComposerTest.java | 2 +- .../ServiceClientTestClassComposerTest.java | 2 +- .../ServiceStubSettingsClassComposerTest.java | 2 +- .../ResourceNameHelperClassComposerTest.java | 35 ++++----------- .../ResourceNameTokenizerTest.java | 2 +- .../composer/rest/RestTestProtoLoader.java | 4 +- .../ServiceClientSampleCodeComposerTest.java | 4 +- .../SettingsSampleCodeComposerTest.java | 2 +- .../composer/utils/PackageCheckerTest.java | 4 +- .../gapic/model/GapicServiceConfigTest.java | 12 ++--- .../BatchingSettingsConfigParserTest.java | 6 +-- .../GapicLanguageSettingsParserTest.java | 4 +- .../GapicLroRetrySettingsParserTest.java | 4 +- .../gapic/protoparser/HttpRuleParserTest.java | 4 +- .../MethodSignatureParserTest.java | 18 +------- .../gapic/protoparser/ParserTest.java | 24 ++-------- .../protoparser/PluginArgumentParserTest.java | 6 +-- .../protoparser/ResourceNameParserTest.java | 9 ++-- .../ResourceReferenceParserTest.java | 10 ++--- .../protoparser/ServiceConfigParserTest.java | 6 +-- .../protoparser/ServiceYamlParserTest.java | 4 +- .../protoparser/SourceCodeInfoParserTest.java | 2 +- .../gapic/protoparser/TypeParserTest.java | 3 +- .../generator/gapic/utils/JavaStyleTest.java | 2 +- .../test/framework/SingleJUnitTestRunner.java | 2 +- .../api/generator/test/framework/Utils.java | 8 ++-- .../google/api/generator/util/TrieTest.java | 8 ++-- 104 files changed, 256 insertions(+), 405 deletions(-) diff --git a/.github/release-please.yml b/.github/release-please.yml index 9548aceb5e..ddc69395da 100644 --- a/.github/release-please.yml +++ b/.github/release-please.yml @@ -1,3 +1,3 @@ releaseType: simple handleGHRelease: true -primaryBranch: master +primaryBranch: main diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index dbf5754794..ec62f81cb2 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -1,14 +1,14 @@ on: push: branches: - - master + - main pull_request: name: ci jobs: build: runs-on: ubuntu-latest container: gcr.io/gapic-images/googleapis-bazel:20210105 - # Dockerfile for this image: https://github.com/googleapis/googleapis-discovery/blob/master/Dockerfile + # Dockerfile for this image: https://github.com/googleapis/googleapis-discovery/blob/main/Dockerfile # If you update its version, please also update it below in # 'Cache Bazel files' - unfortunately it cannot accept variables at this # time. diff --git a/DEVELOPMENT.md b/DEVELOPMENT.md index 8cd12949a0..ce5fec73c5 100644 --- a/DEVELOPMENT.md +++ b/DEVELOPMENT.md @@ -15,17 +15,17 @@ ## Running the Plugin 1. Clone [googleapis](https://github.com/googleapis/googleapis) and - [gapic-showcase](https://github.com/googleapis/gapic-showcase/) and install - protoc. + [gapic-showcase](https://github.com/googleapis/gapic-showcase/). 2. Copy the protos from Showcase into googleapis/google/showcase. ```sh - cp gapic-showcase/schema/google/showcase/v1beta1 googleapis/google/showcase/v1beta + mkdir googleapis/google/showcase + cp -r gapic-showcase/schema/google/showcase/v1beta1 googleapis/google/showcase/v1beta1 ``` -3. Add the new microgenerator rules to the protobuf directory's `BUILD.bazel` - file as follows: +3. Add the new microgenerator rules to + `googleapis/google/showcase/v1beta1/BUILD.bazel` file as follows: ```python load( @@ -33,6 +33,22 @@ # Existing rules here. "java_gapic_assembly_gradle_pkg", "java_gapic_library", + "java_proto_library", + "proto_library_with_info", + ) + + proto_library_with_info( + name = "showcase_proto_with_info", + deps = [ + ":showcase_proto", + ], + ) + + java_proto_library( + name = "showcase_java_proto", + deps = [ + "showcase_proto", + ], ) # This should either replace the existing monolith target or have a unique name diff --git a/README.md b/README.md index bf07953d1b..d9c6914dc9 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -[![codecov](https://codecov.io/gh/googleapis/gapic-generator-java/branch/master/graph/badge.svg?token=3RUU37GX9U)](https://codecov.io/gh/googleapis/gapic-generator-java) +[![codecov](https://codecov.io/gh/googleapis/gapic-generator-java/branch/main/graph/badge.svg?token=3RUU37GX9U)](https://codecov.io/gh/googleapis/gapic-generator-java) # API Client Generator for Java Generates a Java client library from protocol buffers. diff --git a/WORKSPACE b/WORKSPACE index 50cac18478..91c1361828 100644 --- a/WORKSPACE +++ b/WORKSPACE @@ -8,10 +8,10 @@ load("@bazel_tools//tools/build_defs/repo:jvm.bzl", "jvm_maven_import_external") # like protobuf will build. http_archive( name = "bazel_skylib", - sha256 = "97e70364e9249702246c0e9444bccdc4b847bed1eb03c5a3ece4f83dfe6abc44", + sha256 = "c6966ec828da198c5d9adbaa94c05e3a1c7f21bd012a0b29ba8ddbccb2c93b0d", urls = [ - "https://mirror.bazel.build/github.com/bazelbuild/bazel-skylib/releases/download/1.0.2/bazel-skylib-1.0.2.tar.gz", - "https://github.com/bazelbuild/bazel-skylib/releases/download/1.0.2/bazel-skylib-1.0.2.tar.gz", + "https://mirror.bazel.build/github.com/bazelbuild/bazel-skylib/releases/download/1.1.1/bazel-skylib-1.1.1.tar.gz", + "https://github.com/bazelbuild/bazel-skylib/releases/download/1.1.1/bazel-skylib-1.1.1.tar.gz", ], ) diff --git a/rules_java_gapic/resources/gradle/gradle/wrapper/gradle-wrapper.properties b/rules_java_gapic/resources/gradle/gradle/wrapper/gradle-wrapper.properties index 056e712818..4d39c109cf 100644 --- a/rules_java_gapic/resources/gradle/gradle/wrapper/gradle-wrapper.properties +++ b/rules_java_gapic/resources/gradle/gradle/wrapper/gradle-wrapper.properties @@ -3,4 +3,4 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-4.10.3-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-7.2-bin.zip diff --git a/src/main/java/com/google/api/generator/engine/ast/AnnotationNode.java b/src/main/java/com/google/api/generator/engine/ast/AnnotationNode.java index 888262cbf4..1a3412aa6c 100644 --- a/src/main/java/com/google/api/generator/engine/ast/AnnotationNode.java +++ b/src/main/java/com/google/api/generator/engine/ast/AnnotationNode.java @@ -25,7 +25,7 @@ public abstract class AnnotationNode implements AstNode { public static AnnotationNode DEPRECATED = AnnotationNode.builder().setType(annotationType(Deprecated.class)).build(); - private static TypeNode annotationType(Class clazz) { + private static TypeNode annotationType(Class clazz) { return TypeNode.withReference(ConcreteReference.withClazz(clazz)); } diff --git a/src/main/java/com/google/api/generator/engine/ast/ArithmeticOperationExpr.java b/src/main/java/com/google/api/generator/engine/ast/ArithmeticOperationExpr.java index 1a362758fd..886ec56ad4 100644 --- a/src/main/java/com/google/api/generator/engine/ast/ArithmeticOperationExpr.java +++ b/src/main/java/com/google/api/generator/engine/ast/ArithmeticOperationExpr.java @@ -24,8 +24,10 @@ public abstract class ArithmeticOperationExpr implements OperationExpr { public abstract Expr rhsExpr(); + @Override public abstract OperatorKind operatorKind(); + @Override public abstract TypeNode type(); @Override diff --git a/src/main/java/com/google/api/generator/engine/ast/AssignmentOperationExpr.java b/src/main/java/com/google/api/generator/engine/ast/AssignmentOperationExpr.java index af73f0b44f..4c2cfeec2e 100644 --- a/src/main/java/com/google/api/generator/engine/ast/AssignmentOperationExpr.java +++ b/src/main/java/com/google/api/generator/engine/ast/AssignmentOperationExpr.java @@ -23,6 +23,7 @@ public abstract class AssignmentOperationExpr implements OperationExpr { public abstract Expr valueExpr(); + @Override public abstract OperatorKind operatorKind(); @Override diff --git a/src/main/java/com/google/api/generator/engine/ast/BlockComment.java b/src/main/java/com/google/api/generator/engine/ast/BlockComment.java index 00f98aa2ec..9a9bc0d0cc 100644 --- a/src/main/java/com/google/api/generator/engine/ast/BlockComment.java +++ b/src/main/java/com/google/api/generator/engine/ast/BlockComment.java @@ -18,6 +18,7 @@ @AutoValue public abstract class BlockComment implements Comment { + @Override public abstract String comment(); @Override diff --git a/src/main/java/com/google/api/generator/engine/ast/ConcreteReference.java b/src/main/java/com/google/api/generator/engine/ast/ConcreteReference.java index 144c4beca1..5af0dbe869 100644 --- a/src/main/java/com/google/api/generator/engine/ast/ConcreteReference.java +++ b/src/main/java/com/google/api/generator/engine/ast/ConcreteReference.java @@ -32,10 +32,10 @@ public abstract class ConcreteReference implements Reference { private static final String RIGHT_ANGLE = ">"; private static final String QUESTION_MARK = "?"; - private static final Class WILDCARD_CLAZZ = ReferenceWildcard.class; + private static final Class WILDCARD_CLAZZ = ReferenceWildcard.class; // Private. - abstract Class clazz(); + abstract Class clazz(); @Override public void accept(AstNodeVisitor visitor) { @@ -105,7 +105,7 @@ public ImmutableList enclosingClassNames() { } // The innermost type will be the last element in the list. ImmutableList.Builder listBuilder = new ImmutableList.Builder<>(); - Class currentClz = clazz(); + Class currentClz = clazz(); while (currentClz.getEnclosingClass() != null) { listBuilder.add(currentClz.getEnclosingClass().getSimpleName()); currentClz = currentClz.getEnclosingClass(); @@ -198,7 +198,7 @@ public Reference copyAndSetGenerics(List generics) { return toBuilder().setGenerics(generics).build(); } - public static ConcreteReference withClazz(Class clazz) { + public static ConcreteReference withClazz(Class clazz) { return builder().setClazz(clazz).build(); } @@ -222,7 +222,7 @@ public static Builder builder() { @AutoValue.Builder public abstract static class Builder { - public abstract Builder setClazz(Class clazz); + public abstract Builder setClazz(Class clazz); public abstract Builder setUseFullName(boolean useFullName); @@ -239,7 +239,7 @@ public Builder setGenerics(Reference... references) { public abstract ConcreteReference autoBuild(); // Private. - abstract Class clazz(); + abstract Class clazz(); abstract ImmutableList generics(); diff --git a/src/main/java/com/google/api/generator/engine/ast/EnumRefExpr.java b/src/main/java/com/google/api/generator/engine/ast/EnumRefExpr.java index 9c2c49e756..8dcf18679b 100644 --- a/src/main/java/com/google/api/generator/engine/ast/EnumRefExpr.java +++ b/src/main/java/com/google/api/generator/engine/ast/EnumRefExpr.java @@ -21,6 +21,7 @@ public abstract class EnumRefExpr implements Expr { public abstract IdentifierNode identifier(); + @Override public abstract TypeNode type(); @Override diff --git a/src/main/java/com/google/api/generator/engine/ast/Expr.java b/src/main/java/com/google/api/generator/engine/ast/Expr.java index 6adc7a4fa5..134d2464d8 100644 --- a/src/main/java/com/google/api/generator/engine/ast/Expr.java +++ b/src/main/java/com/google/api/generator/engine/ast/Expr.java @@ -17,5 +17,6 @@ public interface Expr extends AstNode { TypeNode type(); + @Override void accept(AstNodeVisitor visitor); } diff --git a/src/main/java/com/google/api/generator/engine/ast/LogicalOperationExpr.java b/src/main/java/com/google/api/generator/engine/ast/LogicalOperationExpr.java index 2387345d31..9210ec3593 100644 --- a/src/main/java/com/google/api/generator/engine/ast/LogicalOperationExpr.java +++ b/src/main/java/com/google/api/generator/engine/ast/LogicalOperationExpr.java @@ -24,6 +24,7 @@ public abstract class LogicalOperationExpr implements OperationExpr { public abstract Expr rhsExpr(); + @Override public abstract OperatorKind operatorKind(); @Override diff --git a/src/main/java/com/google/api/generator/engine/ast/MethodDefinition.java b/src/main/java/com/google/api/generator/engine/ast/MethodDefinition.java index 3067dfc49a..4b65d14789 100644 --- a/src/main/java/com/google/api/generator/engine/ast/MethodDefinition.java +++ b/src/main/java/com/google/api/generator/engine/ast/MethodDefinition.java @@ -244,20 +244,18 @@ public MethodDefinition build() { "Abstract methods cannot be static, final, or private"); } - // If this method overrides another, ensure that the Override annotaiton is the last one. + // If this method overrides another, ensure that the Override annotation is the last one. ImmutableList processedAnnotations = annotations(); if (isOverride()) { processedAnnotations = - annotations() - .builder() + ImmutableList.builder() .addAll(annotations()) .add(AnnotationNode.OVERRIDE) .build(); } // Remove duplicates while maintaining insertion order. setAnnotations( - new LinkedHashSet(processedAnnotations) - .stream().collect(Collectors.toList())); + new LinkedHashSet<>(processedAnnotations).stream().collect(Collectors.toList())); MethodDefinition method = autoBuild(); diff --git a/src/main/java/com/google/api/generator/engine/ast/NewObjectExpr.java b/src/main/java/com/google/api/generator/engine/ast/NewObjectExpr.java index 50fbbed983..bbba011dff 100644 --- a/src/main/java/com/google/api/generator/engine/ast/NewObjectExpr.java +++ b/src/main/java/com/google/api/generator/engine/ast/NewObjectExpr.java @@ -23,6 +23,7 @@ @AutoValue public abstract class NewObjectExpr implements Expr { + @Override public abstract TypeNode type(); public abstract ImmutableList arguments(); diff --git a/src/main/java/com/google/api/generator/engine/ast/ObjectValue.java b/src/main/java/com/google/api/generator/engine/ast/ObjectValue.java index 49dd6abd9e..3cde72c4e9 100644 --- a/src/main/java/com/google/api/generator/engine/ast/ObjectValue.java +++ b/src/main/java/com/google/api/generator/engine/ast/ObjectValue.java @@ -15,7 +15,9 @@ package com.google.api.generator.engine.ast; public interface ObjectValue extends Value { + @Override TypeNode type(); + @Override String value(); } diff --git a/src/main/java/com/google/api/generator/engine/ast/OperationExpr.java b/src/main/java/com/google/api/generator/engine/ast/OperationExpr.java index 924a6a6930..36473e6e97 100644 --- a/src/main/java/com/google/api/generator/engine/ast/OperationExpr.java +++ b/src/main/java/com/google/api/generator/engine/ast/OperationExpr.java @@ -18,7 +18,9 @@ public interface OperationExpr extends Expr { OperatorKind operatorKind(); + @Override TypeNode type(); + @Override void accept(AstNodeVisitor visitor); } diff --git a/src/main/java/com/google/api/generator/engine/ast/Reference.java b/src/main/java/com/google/api/generator/engine/ast/Reference.java index fdc2c5c5ee..4dce11783f 100644 --- a/src/main/java/com/google/api/generator/engine/ast/Reference.java +++ b/src/main/java/com/google/api/generator/engine/ast/Reference.java @@ -19,6 +19,7 @@ import javax.annotation.Nullable; public interface Reference extends AstNode { + @Override void accept(AstNodeVisitor visitor); ImmutableList generics(); diff --git a/src/main/java/com/google/api/generator/engine/ast/ReferenceConstructorExpr.java b/src/main/java/com/google/api/generator/engine/ast/ReferenceConstructorExpr.java index 25940b0d3d..b68ff61ded 100644 --- a/src/main/java/com/google/api/generator/engine/ast/ReferenceConstructorExpr.java +++ b/src/main/java/com/google/api/generator/engine/ast/ReferenceConstructorExpr.java @@ -28,6 +28,7 @@ public enum KeywordKind { SUPER } + @Override public abstract TypeNode type(); public abstract KeywordKind keywordKind(); @@ -73,7 +74,7 @@ public Builder setArguments(Expr... arguments) { public ReferenceConstructorExpr build() { ReferenceConstructorExpr referenceConstructorExpr = autoBuild(); Preconditions.checkState( - referenceConstructorExpr.type().isReferenceType(referenceConstructorExpr.type()), + TypeNode.isReferenceType(referenceConstructorExpr.type()), "A this/super constructor must have a reference type."); NodeValidator.checkNoNullElements( diff --git a/src/main/java/com/google/api/generator/engine/ast/RelationalOperationExpr.java b/src/main/java/com/google/api/generator/engine/ast/RelationalOperationExpr.java index 80f0e4711b..d143abad5e 100644 --- a/src/main/java/com/google/api/generator/engine/ast/RelationalOperationExpr.java +++ b/src/main/java/com/google/api/generator/engine/ast/RelationalOperationExpr.java @@ -23,6 +23,7 @@ public abstract class RelationalOperationExpr implements OperationExpr { public abstract Expr rhsExpr(); + @Override public abstract OperatorKind operatorKind(); @Override diff --git a/src/main/java/com/google/api/generator/engine/ast/Statement.java b/src/main/java/com/google/api/generator/engine/ast/Statement.java index 041d5bfd0f..954b279fd7 100644 --- a/src/main/java/com/google/api/generator/engine/ast/Statement.java +++ b/src/main/java/com/google/api/generator/engine/ast/Statement.java @@ -15,5 +15,6 @@ package com.google.api.generator.engine.ast; public interface Statement extends AstNode { + @Override void accept(AstNodeVisitor visitor); } diff --git a/src/main/java/com/google/api/generator/engine/ast/StringObjectValue.java b/src/main/java/com/google/api/generator/engine/ast/StringObjectValue.java index c121df71c3..602c0dbf82 100644 --- a/src/main/java/com/google/api/generator/engine/ast/StringObjectValue.java +++ b/src/main/java/com/google/api/generator/engine/ast/StringObjectValue.java @@ -20,6 +20,7 @@ @AutoValue public abstract class StringObjectValue implements ObjectValue { + @Override public abstract String value(); @Override diff --git a/src/main/java/com/google/api/generator/engine/ast/TypeNode.java b/src/main/java/com/google/api/generator/engine/ast/TypeNode.java index 99de1a213d..50bcc62657 100644 --- a/src/main/java/com/google/api/generator/engine/ast/TypeNode.java +++ b/src/main/java/com/google/api/generator/engine/ast/TypeNode.java @@ -112,7 +112,7 @@ public int compareTo(TypeNode other) { return -1; } - if (this.equals(TypeNode.NULL)) { + if (equals(TypeNode.NULL)) { // Can't self-compare, so we don't need to check whether the other one is TypeNode.NULL. return other.isPrimitiveType() ? 1 : -1; } @@ -161,7 +161,7 @@ public static TypeNode withReference(Reference reference) { return TypeNode.builder().setTypeKind(TypeKind.OBJECT).setReference(reference).build(); } - public static TypeNode withExceptionClazz(Class clazz) { + public static TypeNode withExceptionClazz(Class clazz) { Preconditions.checkState(Exception.class.isAssignableFrom(clazz)); return withReference(ConcreteReference.withClazz(clazz)); } @@ -200,11 +200,11 @@ public boolean isPrimitiveType() { } public boolean isProtoPrimitiveType() { - return isPrimitiveType() || this.equals(TypeNode.STRING) || this.equals(TypeNode.BYTESTRING); + return isPrimitiveType() || equals(TypeNode.STRING) || equals(TypeNode.BYTESTRING); } public boolean isSupertypeOrEquals(TypeNode other) { - boolean oneTypeIsNull = this.equals(TypeNode.NULL) ^ other.equals(TypeNode.NULL); + boolean oneTypeIsNull = equals(TypeNode.NULL) ^ other.equals(TypeNode.NULL); return !isPrimitiveType() && !other.isPrimitiveType() && isArray() == other.isArray() @@ -256,20 +256,6 @@ boolean isBoxedTypeEquals(TypeNode other) { return Objects.equals(other, BOXED_TYPE_MAP.get(this)); } - private static TypeNode createPrimitiveType(TypeKind typeKind) { - if (!isPrimitiveType(typeKind)) { - throw new IllegalArgumentException("Object is not a primitive type."); - } - return TypeNode.builder().setTypeKind(typeKind).build(); - } - - private static TypeNode createPrimitiveArrayType(TypeKind typeKind) { - if (typeKind.equals(TypeKind.OBJECT)) { - throw new IllegalArgumentException("Object is not a primitive type."); - } - return TypeNode.builder().setTypeKind(typeKind).setIsArray(true).build(); - } - private static boolean isPrimitiveType(TypeKind typeKind) { return !typeKind.equals(TypeKind.OBJECT); } diff --git a/src/main/java/com/google/api/generator/engine/ast/UnaryOperationExpr.java b/src/main/java/com/google/api/generator/engine/ast/UnaryOperationExpr.java index 74bda2f21d..3a968b92e0 100644 --- a/src/main/java/com/google/api/generator/engine/ast/UnaryOperationExpr.java +++ b/src/main/java/com/google/api/generator/engine/ast/UnaryOperationExpr.java @@ -22,10 +22,13 @@ public abstract class UnaryOperationExpr implements OperationExpr { public abstract Expr expr(); + @Override public abstract OperatorKind operatorKind(); + @Override public abstract TypeNode type(); + @Override public void accept(AstNodeVisitor visitor) { visitor.visit(this); } diff --git a/src/main/java/com/google/api/generator/engine/writer/ImportWriterVisitor.java b/src/main/java/com/google/api/generator/engine/writer/ImportWriterVisitor.java index 58fb2b9aa4..85274e34b9 100644 --- a/src/main/java/com/google/api/generator/engine/writer/ImportWriterVisitor.java +++ b/src/main/java/com/google/api/generator/engine/writer/ImportWriterVisitor.java @@ -74,7 +74,6 @@ public class ImportWriterVisitor implements AstNodeVisitor { private static final String DOT = "."; - private static final String NEWLINE = "\n"; private static final String PKG_JAVA_LANG = "java.lang"; private final Set staticImports = new TreeSet<>(); @@ -94,7 +93,7 @@ public void clear() { public void initialize(@Nonnull String currentPackage) { this.currentPackage = currentPackage; - this.currentClassName = null; + currentClassName = null; } public void initialize(@Nonnull String currentPackage, @Nonnull String currentClassName) { diff --git a/src/main/java/com/google/api/generator/engine/writer/JavaWriterVisitor.java b/src/main/java/com/google/api/generator/engine/writer/JavaWriterVisitor.java index a52b584da1..b1d750157e 100644 --- a/src/main/java/com/google/api/generator/engine/writer/JavaWriterVisitor.java +++ b/src/main/java/com/google/api/generator/engine/writer/JavaWriterVisitor.java @@ -81,7 +81,6 @@ public class JavaWriterVisitor implements AstNodeVisitor { private static final String BLOCK_COMMENT_START = "/*"; private static final String BLOCK_COMMENT_END = "*/"; private static final String DOT = "."; - private static final String ESCAPED_QUOTE = "\""; private static final String EQUALS = "="; private static final String LEFT_ANGLE = "<"; private static final String LEFT_BRACE = "{"; @@ -751,6 +750,7 @@ public void visit(BreakStatement breakStatement) { } /** =============================== COMMENT =============================== */ + @Override public void visit(LineComment lineComment) { // Split comments by new line and add `//` to each line. String formattedSource = @@ -759,6 +759,7 @@ public void visit(LineComment lineComment) { buffer.append(formattedSource); } + @Override public void visit(BlockComment blockComment) { // Split comments by new line and embrace the comment block with `/* */`. StringBuilder sourceComment = new StringBuilder(); @@ -772,6 +773,7 @@ public void visit(BlockComment blockComment) { buffer.append(JavaFormatter.format(sourceComment.toString())); } + @Override public void visit(JavaDocComment javaDocComment) { StringBuilder sourceComment = new StringBuilder(); sourceComment.append(JAVADOC_COMMENT_START).append(NEWLINE); @@ -865,7 +867,6 @@ public void visit(MethodDefinition methodDefinition) { buffer.append(THROWS); space(); - int numExceptionsThrown = methodDefinition.throwsExceptions().size(); Iterator exceptionIter = methodDefinition.throwsExceptions().iterator(); while (exceptionIter.hasNext()) { TypeNode exceptionType = exceptionIter.next(); diff --git a/src/main/java/com/google/api/generator/gapic/composer/comment/ServiceClientCommentComposer.java b/src/main/java/com/google/api/generator/gapic/composer/comment/ServiceClientCommentComposer.java index 8ffeace7c5..e8f8a05681 100644 --- a/src/main/java/com/google/api/generator/gapic/composer/comment/ServiceClientCommentComposer.java +++ b/src/main/java/com/google/api/generator/gapic/composer/comment/ServiceClientCommentComposer.java @@ -33,7 +33,6 @@ public class ServiceClientCommentComposer { // Tokens. - private static final String COLON = ":"; private static final String EMPTY_STRING = ""; private static final String API_EXCEPTION_TYPE_NAME = "com.google.api.gax.rpc.ApiException"; private static final String EXCEPTION_CONDITION = "if the remote call fails"; 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 ec8ef19be4..7f2c83e4a2 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 @@ -27,7 +27,6 @@ public class SettingsCommentComposer { private static final String COLON = ":"; - private static final String STUB_PATTERN = "%sStub"; private static final String BUILDER_CLASS_DOC_PATTERN = "Builder for %s."; private static final String CALL_SETTINGS_METHOD_DOC_PATTERN = "Returns the object with the settings used for calls to %s."; 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 f4e31a962e..224bece718 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 @@ -306,7 +306,7 @@ protected TypeNode getOperationsStubType(Service service) { private TypeStore createTypes(Service service) { - List concreteClazzes = + List> concreteClazzes = Arrays.asList( // Gax-java classes. BatchingCallSettings.class, diff --git a/src/main/java/com/google/api/generator/gapic/composer/common/AbstractServiceClientClassComposer.java b/src/main/java/com/google/api/generator/gapic/composer/common/AbstractServiceClientClassComposer.java index 6a9ec1b17a..031f1cc2dd 100644 --- a/src/main/java/com/google/api/generator/gapic/composer/common/AbstractServiceClientClassComposer.java +++ b/src/main/java/com/google/api/generator/gapic/composer/common/AbstractServiceClientClassComposer.java @@ -108,9 +108,6 @@ public abstract class AbstractServiceClientClassComposer implements ClassCompose private static final Reference LIST_REFERENCE = ConcreteReference.withClazz(List.class); private static final Reference MAP_REFERENCE = ConcreteReference.withClazz(Map.class); - private static final TypeNode OBJECTS_TYPE = - TypeNode.withReference(ConcreteReference.withClazz(Objects.class)); - private enum CallableMethodKind { REGULAR, LRO, @@ -363,7 +360,6 @@ private List createConstructorMethods( TypeNode stubSettingsType = typeStore.get(ClassNames.getServiceStubSettingsClassName(service)); TypeNode exceptionType = typeStore.get("IOException"); - TypeNode settingsType = typeStore.get(settingsName); VariableExpr settingsVarExpr = VariableExpr.withVariable( Variable.builder().setName("settings").setType(typeStore.get(settingsName)).build()); @@ -658,7 +654,6 @@ private static List createMethodVariants( lro.responseType().reference(), lro.metadataType().reference()))); } - String methodInputTypeName = methodInputType.reference().name(); for (List signature : method.methodSignatures()) { // Get the argument list. List arguments = @@ -1207,12 +1202,6 @@ private static ClassDefinition createNestedRpcPagedResponseClass( VariableExpr inputVarExpr = VariableExpr.withVariable( Variable.builder().setName("input").setType(methodPageType).build()); - TypeNode anonClassType = - TypeNode.withReference( - ConcreteReference.builder() - .setClazz(ApiFunction.class) - .setGenerics(Arrays.asList(methodPageType.reference(), thisClassType.reference())) - .build()); // Overrides ApiFunction.apply. // (https://github.com/googleapis/api-common-java/blob/debf25960dea0367b0d3b5e16d57d76c1d01947e/src/main/java/com/google/api/core/ApiFunction.java). @@ -1573,7 +1562,7 @@ static Expr createRequestBuilderExpr( rootFields.add(rootField); } Trie updatedTrie = - rootFieldToTrie.containsKey(rootField) ? rootFieldToTrie.get(rootField) : new Trie(); + rootFieldToTrie.containsKey(rootField) ? rootFieldToTrie.get(rootField) : new Trie<>(); List nestedFieldsWithChild = new ArrayList<>(arg.nestedFields()); nestedFieldsWithChild.add(arg.field()); updatedTrie.insert(nestedFieldsWithChild); @@ -1672,7 +1661,7 @@ private static String typeToSetterMethodName(TypeNode type) { } private static TypeStore createTypes(Service service, Map messageTypes) { - List concreteClazzes = + List> concreteClazzes = Arrays.asList( AbstractPagedListResponse.class, ApiFunction.class, @@ -1773,15 +1762,6 @@ private static boolean isProtoEmptyType(TypeNode type) { && type.reference().name().equals("Empty"); } - private static void updateGapicMetadata( - GapicContext context, String protoPackage, String javaPackage) { - context.updateGapicMetadata( - context.gapicMetadata().toBuilder() - .setProtoPackage(protoPackage) - .setLibraryPackage(javaPackage) - .build()); - } - private static void updateGapicMetadata( GapicContext context, Service service, 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 8309679eae..b38ca70edd 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 @@ -20,7 +20,6 @@ import com.google.api.gax.rpc.BidiStreamingCallable; import com.google.api.gax.rpc.ClientStreamingCallable; import com.google.api.gax.rpc.InvalidArgumentException; -import com.google.api.gax.rpc.OperationCallSettings; import com.google.api.gax.rpc.PagedCallSettings; import com.google.api.gax.rpc.ServerStreamingCallSettings; import com.google.api.gax.rpc.ServerStreamingCallable; @@ -851,7 +850,7 @@ protected abstract List createRpcLroExceptionTestCatchBody( */ private static TypeStore createStaticTypes() { - List concreteClazzes = + List> concreteClazzes = Arrays.asList( AbstractMessage.class, After.class, @@ -959,7 +958,7 @@ protected static TypeNode getCallableType(Method protoMethod) { !protoMethod.stream().equals(Method.Stream.NONE), "No callable type exists for non-streaming methods."); - Class callableClazz = ClientStreamingCallable.class; + Class callableClazz = ClientStreamingCallable.class; switch (protoMethod.stream()) { case BIDI: callableClazz = BidiStreamingCallable.class; 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 cd4f89cbb9..ccf15a1d64 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 @@ -324,7 +324,7 @@ private List createDefaultGetterMethods(Service service, TypeS .build()); BiFunction methodMakerFn = (methodDefBuilder, comment) -> methodDefBuilder.setHeaderCommentStatements(comment).build(); - Function typeMakerFn = + Function, TypeNode> typeMakerFn = c -> TypeNode.withReference(ConcreteReference.withClazz(c)); List javaMethods = new ArrayList<>(); @@ -750,7 +750,7 @@ private static MethodDefinition createNestedBuilderClassBuildMethod( } private static TypeStore createStaticTypes() { - List concreteClazzes = + List> concreteClazzes = Arrays.asList( ApiClientHeaderProvider.class, ApiFunction.class, @@ -815,7 +815,7 @@ private static TypeNode getOperationCallSettingsTypeHelper( Preconditions.checkState( protoMethod.hasLro(), String.format("Cannot get OperationCallSettings on non-LRO method %s", protoMethod.name())); - Class callSettingsClazz = + Class callSettingsClazz = isBuilder ? OperationCallSettings.Builder.class : OperationCallSettings.class; return TypeNode.withReference( ConcreteReference.builder() @@ -838,7 +838,8 @@ private static TypeNode getCallSettingsBuilderType(Method protoMethod, TypeStore private static TypeNode getCallSettingsTypeHelper( Method protoMethod, TypeStore typeStore, boolean isBuilder) { - Class callSettingsClazz = isBuilder ? UnaryCallSettings.Builder.class : UnaryCallSettings.class; + Class callSettingsClazz = + isBuilder ? UnaryCallSettings.Builder.class : UnaryCallSettings.class; if (protoMethod.isPaged()) { callSettingsClazz = isBuilder ? PagedCallSettings.Builder.class : PagedCallSettings.class; } else if (protoMethod.isBatching()) { 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 c54ccbde39..b50f15ff38 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 @@ -253,7 +253,7 @@ private static List createBackgroundResourceMethodOverrides() } private static TypeStore createTypes(Service service, Map messageTypes) { - List concreteClazzes = + List> concreteClazzes = Arrays.asList( BackgroundResource.class, BetaApi.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 d61456e1ad..7a38adba80 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 @@ -1278,7 +1278,6 @@ private ClassDefinition createNestedBuilderClass( Service service, @Nullable GapicServiceConfig serviceConfig, TypeStore typeStore) { // TODO(miraleung): Robustify this against a null serviceConfig. String thisClassName = ClassNames.getServiceStubSettingsClassName(service); - TypeNode outerThisClassType = typeStore.get(thisClassName); String className = "Builder"; @@ -1982,7 +1981,7 @@ private static MethodDefinition createNestedClassBuildMethod( } private static TypeStore createStaticTypes() { - List concreteClazzes = + List> concreteClazzes = Arrays.asList( ApiCallContext.class, ApiClientHeaderProvider.class, @@ -2140,7 +2139,7 @@ private static TypeNode getCallSettingsType( TypeStore typeStore, boolean isBatchingSettings, final boolean isSettingsBuilder) { - Function typeMakerFn = + Function, TypeNode> typeMakerFn = clz -> TypeNode.withReference(ConcreteReference.withClazz(clz)); // Default: No streaming. TypeNode callSettingsType = diff --git a/src/main/java/com/google/api/generator/gapic/composer/common/AbstractTransportServiceStubClassComposer.java b/src/main/java/com/google/api/generator/gapic/composer/common/AbstractTransportServiceStubClassComposer.java index d3b9eae6f9..3d3aafdaa9 100644 --- a/src/main/java/com/google/api/generator/gapic/composer/common/AbstractTransportServiceStubClassComposer.java +++ b/src/main/java/com/google/api/generator/gapic/composer/common/AbstractTransportServiceStubClassComposer.java @@ -106,7 +106,7 @@ public TransportContext getTransportContext() { } private static TypeStore createStaticTypes() { - List concreteClazzes = + List> concreteClazzes = Arrays.asList( BackgroundResource.class, BackgroundResourceAggregation.class, diff --git a/src/main/java/com/google/api/generator/gapic/composer/common/BatchingDescriptorComposer.java b/src/main/java/com/google/api/generator/gapic/composer/common/BatchingDescriptorComposer.java index 8de7d4c9c2..dc96c7bc43 100644 --- a/src/main/java/com/google/api/generator/gapic/composer/common/BatchingDescriptorComposer.java +++ b/src/main/java/com/google/api/generator/gapic/composer/common/BatchingDescriptorComposer.java @@ -66,7 +66,6 @@ public class BatchingDescriptorComposer { private static final TypeNode PARTITION_KEY_TYPE = toType(PartitionKey.class); private static final String ADD_ALL_METHOD_PATTERN = "addAll%s"; - private static final String BATCH_FOO_INDEX_PATTERN = "batch%sIndex"; private static final String GET_LIST_METHOD_PATTERN = "get%sList"; private static final String GET_COUNT_METHOD_PATTERN = "get%sCount"; @@ -231,8 +230,7 @@ private static MethodDefinition createGetRequestBuilderMethod( .setStatements( Arrays.asList( ExprStatement.withExpr( - builderVarExpr - .toBuilder() + builderVarExpr.toBuilder() .setIsDecl(true) .setScope(ScopeNode.PRIVATE) .build()))) @@ -272,8 +270,6 @@ private static MethodDefinition createSplitResponseMethod( VariableExpr.withVariable( Variable.builder().setType(batchedRequestIssuerType).setName("responder").build()); - String upperCamelBatchedFieldName = - JavaStyle.toUpperCamelCase(batchingSettings.batchedFieldName()); VariableExpr batchMessageIndexVarExpr = VariableExpr.withVariable( Variable.builder().setType(TypeNode.INT).setName("batchMessageIndex").build()); @@ -541,7 +537,7 @@ private static MethodDefinition createCountByteSMethod(Method method) { .build(); } - private static TypeNode toType(Class clazz) { + private static TypeNode toType(Class clazz) { return TypeNode.withReference(ConcreteReference.withClazz(clazz)); } diff --git a/src/main/java/com/google/api/generator/gapic/composer/common/RetrySettingsComposer.java b/src/main/java/com/google/api/generator/gapic/composer/common/RetrySettingsComposer.java index 4497495d67..e5e4ad4195 100644 --- a/src/main/java/com/google/api/generator/gapic/composer/common/RetrySettingsComposer.java +++ b/src/main/java/com/google/api/generator/gapic/composer/common/RetrySettingsComposer.java @@ -711,7 +711,7 @@ private static MethodInvocationExpr createDurationOfMillisExpr(ValueExpr valExpr } private static TypeStore createStaticTypes() { - List concreteClazzes = + List> concreteClazzes = Arrays.asList( BatchingSettings.class, org.threeten.bp.Duration.class, diff --git a/src/main/java/com/google/api/generator/gapic/composer/defaultvalue/DefaultValueComposer.java b/src/main/java/com/google/api/generator/gapic/composer/defaultvalue/DefaultValueComposer.java index 1b0ffc3c41..8862984755 100644 --- a/src/main/java/com/google/api/generator/gapic/composer/defaultvalue/DefaultValueComposer.java +++ b/src/main/java/com/google/api/generator/gapic/composer/defaultvalue/DefaultValueComposer.java @@ -41,7 +41,6 @@ import com.google.common.base.Preconditions; import com.google.longrunning.Operation; import com.google.protobuf.Any; -import com.google.protobuf.ByteString; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; @@ -55,8 +54,6 @@ public class DefaultValueComposer { private static TypeNode OPERATION_TYPE = TypeNode.withReference(ConcreteReference.withClazz(Operation.class)); private static TypeNode ANY_TYPE = TypeNode.withReference(ConcreteReference.withClazz(Any.class)); - private static TypeNode BYTESTRING_TYPE = - TypeNode.withReference(ConcreteReference.withClazz(ByteString.class)); public static Expr createDefaultValue( MethodArgument methodArg, 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 f3ad194c51..c82de5552c 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 @@ -73,7 +73,7 @@ public static GrpcServiceStubClassComposer instance() { } private static TypeStore createStaticTypes() { - List concreteClazzes = + List> concreteClazzes = Arrays.asList( GrpcCallSettings.class, GrpcOperationsStub.class, @@ -258,9 +258,6 @@ private LambdaExpr createRequestParamsExtractorClassInstance(Method method) { 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() diff --git a/src/main/java/com/google/api/generator/gapic/composer/grpc/MockServiceClassComposer.java b/src/main/java/com/google/api/generator/gapic/composer/grpc/MockServiceClassComposer.java index f1ac25fd06..7227b4fe4a 100644 --- a/src/main/java/com/google/api/generator/gapic/composer/grpc/MockServiceClassComposer.java +++ b/src/main/java/com/google/api/generator/gapic/composer/grpc/MockServiceClassComposer.java @@ -234,7 +234,7 @@ private static MethodDefinition createResetMethod(VariableExpr serviceImplVarExp } private static TypeStore createTypes(Service service) { - List concreteClazzes = + List> concreteClazzes = Arrays.asList( AbstractMessage.class, BetaApi.class, Generated.class, ServerServiceDefinition.class); TypeStore typeStore = new TypeStore(concreteClazzes); diff --git a/src/main/java/com/google/api/generator/gapic/composer/grpc/MockServiceImplClassComposer.java b/src/main/java/com/google/api/generator/gapic/composer/grpc/MockServiceImplClassComposer.java index 2f77f6aa75..e16cc875f4 100644 --- a/src/main/java/com/google/api/generator/gapic/composer/grpc/MockServiceImplClassComposer.java +++ b/src/main/java/com/google/api/generator/gapic/composer/grpc/MockServiceImplClassComposer.java @@ -596,7 +596,7 @@ private static Statement createHandleObjectStatement( } private static TypeStore createStaticTypes() { - List concreteClazzes = + List> concreteClazzes = Arrays.asList( AbstractMessage.class, ArrayList.class, 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 75bd4c0133..8cb761236a 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 @@ -96,7 +96,7 @@ public static AbstractServiceClientTestClassComposer instance() { } private static TypeStore createStaticTypes() { - List concreteClazzes = + List> concreteClazzes = Arrays.asList( GaxGrpcProperties.class, LocalChannelProvider.class, @@ -207,15 +207,12 @@ protected MethodDefinition createStartStaticServerMethod( varInitExprs.add(initServiceHelperExpr); varInitExprs.add(startServiceHelperExpr); - List body = new ArrayList<>(); - return MethodDefinition.builder() .setAnnotations(Arrays.asList(AnnotationNode.withType(FIXED_TYPESTORE.get("BeforeClass")))) .setScope(ScopeNode.PUBLIC) .setIsStatic(true) .setReturnType(TypeNode.VOID) .setName("startStaticServer") - .setBody(body) .setBody( varInitExprs.stream().map(e -> ExprStatement.withExpr(e)).collect(Collectors.toList())) .build(); 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 a80feffcd5..a897f3003d 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 @@ -51,7 +51,7 @@ protected ServiceStubSettingsClassComposer() { } private static TypeStore createStaticTypes() { - List concreteClazzes = + List> concreteClazzes = Arrays.asList( GaxGrpcProperties.class, GrpcTransportChannel.class, diff --git a/src/main/java/com/google/api/generator/gapic/composer/resourcename/ResourceNameHelperClassComposer.java b/src/main/java/com/google/api/generator/gapic/composer/resourcename/ResourceNameHelperClassComposer.java index 80801e31fe..f8c961ccab 100644 --- a/src/main/java/com/google/api/generator/gapic/composer/resourcename/ResourceNameHelperClassComposer.java +++ b/src/main/java/com/google/api/generator/gapic/composer/resourcename/ResourceNameHelperClassComposer.java @@ -1192,7 +1192,6 @@ private static MethodDefinition createGetFieldValuesMapMethod( .build(); // Outer if-block. - Expr thisExpr = ValueExpr.withValue(ThisObjectValue.withType(thisClassType)); IfStatement outerIfStatement = IfStatement.builder() .setConditionExpr(fieldValuesMapNullCheckExpr) @@ -1247,8 +1246,7 @@ private static MethodDefinition createToStringMethod( List instantiateArgExprs = new ArrayList<>(); List tokens = getTokenSet(tokenHierarchies).stream().collect(Collectors.toList()); - for (int i = 0; i < tokens.size(); i++) { - String token = tokens.get(i); + for (String token : tokens) { Preconditions.checkNotNull( patternTokenVarExprs.get(token), String.format( @@ -1572,7 +1570,6 @@ private static ClassDefinition createNestedBuilderClass( for (int i = 0; i < tokens.size(); i++) { String token = tokens.get(i); String upperCamelTokenName = JavaStyle.toUpperCamelCase(token); - String lowerCamelTokenName = JavaStyle.toLowerCamelCase(token); VariableExpr currClassTokenVarExpr = classMemberVarExprs.get(i); // Getter. @@ -1647,11 +1644,9 @@ private static ClassDefinition createNestedBuilderClass( .build()); } - for (int i = 0; i < tokens.size(); i++) { - String token = tokens.get(i); - String lowerCamelTokenName = JavaStyle.toLowerCamelCase(token); + for (VariableExpr memberVarExpr : classMemberVarExprs) { VariableExpr currClassTokenVarExpr = - classMemberVarExprs.get(i).toBuilder().setExprReferenceExpr(thisExpr).build(); + memberVarExpr.toBuilder().setExprReferenceExpr(thisExpr).build(); builderCtorBodyExprs.add( AssignmentExpr.builder() .setVariableExpr(currClassTokenVarExpr) @@ -1713,7 +1708,7 @@ private static ClassDefinition createNestedBuilderClass( } private static TypeStore createStaticTypes() { - List concreteClazzes = + List> concreteClazzes = Arrays.asList( ArrayList.class, BetaApi.class, diff --git a/src/main/java/com/google/api/generator/gapic/composer/rest/ServiceClientTestClassComposer.java b/src/main/java/com/google/api/generator/gapic/composer/rest/ServiceClientTestClassComposer.java index 893777e057..9df088bbd7 100644 --- a/src/main/java/com/google/api/generator/gapic/composer/rest/ServiceClientTestClassComposer.java +++ b/src/main/java/com/google/api/generator/gapic/composer/rest/ServiceClientTestClassComposer.java @@ -62,7 +62,6 @@ 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(); 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..4113c3446b 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 @@ -28,11 +28,11 @@ public class TypeStore { public TypeStore() {} - public TypeStore(List concreteClasses) { + public TypeStore(List> concreteClasses) { putConcreteClassses(concreteClasses); } - private void putConcreteClassses(List concreteClasses) { + private void putConcreteClassses(List> concreteClasses) { store.putAll( concreteClasses.stream() .collect( @@ -71,7 +71,7 @@ public void put( .build())); } - public void putAll(List concreteClasses) { + public void putAll(List> concreteClasses) { putConcreteClassses(concreteClasses); } diff --git a/src/main/java/com/google/api/generator/gapic/protoparser/BatchingSettingsConfigParser.java b/src/main/java/com/google/api/generator/gapic/protoparser/BatchingSettingsConfigParser.java index 79a1c9817d..f681399342 100644 --- a/src/main/java/com/google/api/generator/gapic/protoparser/BatchingSettingsConfigParser.java +++ b/src/main/java/com/google/api/generator/gapic/protoparser/BatchingSettingsConfigParser.java @@ -20,6 +20,7 @@ import com.google.common.base.Strings; import java.io.File; import java.io.IOException; +import java.nio.charset.StandardCharsets; import java.nio.file.Files; import java.nio.file.Paths; import java.util.ArrayList; @@ -69,7 +70,9 @@ static Optional> parse(String gapicYamlConfigFilePat String fileContents = null; try { - fileContents = new String(Files.readAllBytes(Paths.get(gapicYamlConfigFilePath))); + fileContents = + new String( + Files.readAllBytes(Paths.get(gapicYamlConfigFilePath)), StandardCharsets.UTF_8); } catch (IOException e) { return Optional.empty(); } @@ -104,7 +107,7 @@ private static Optional> parseFromMap(Map batchingYamlConfig = diff --git a/src/main/java/com/google/api/generator/gapic/protoparser/GapicLanguageSettingsParser.java b/src/main/java/com/google/api/generator/gapic/protoparser/GapicLanguageSettingsParser.java index 6836b3002a..e1cad0ef97 100644 --- a/src/main/java/com/google/api/generator/gapic/protoparser/GapicLanguageSettingsParser.java +++ b/src/main/java/com/google/api/generator/gapic/protoparser/GapicLanguageSettingsParser.java @@ -19,6 +19,7 @@ import com.google.common.base.Strings; import java.io.File; import java.io.IOException; +import java.nio.charset.StandardCharsets; import java.nio.file.Files; import java.nio.file.Paths; import java.util.Map; @@ -48,7 +49,9 @@ static Optional parse(String gapicYamlConfigFilePath) { String fileContents = null; try { - fileContents = new String(Files.readAllBytes(Paths.get(gapicYamlConfigFilePath))); + fileContents = + new String( + Files.readAllBytes(Paths.get(gapicYamlConfigFilePath)), StandardCharsets.UTF_8); } catch (IOException e) { return Optional.empty(); } diff --git a/src/main/java/com/google/api/generator/gapic/protoparser/GapicLroRetrySettingsParser.java b/src/main/java/com/google/api/generator/gapic/protoparser/GapicLroRetrySettingsParser.java index ff0cf7e462..b30e93791b 100644 --- a/src/main/java/com/google/api/generator/gapic/protoparser/GapicLroRetrySettingsParser.java +++ b/src/main/java/com/google/api/generator/gapic/protoparser/GapicLroRetrySettingsParser.java @@ -19,6 +19,7 @@ import com.google.common.base.Strings; import java.io.File; import java.io.IOException; +import java.nio.charset.StandardCharsets; import java.nio.file.Files; import java.nio.file.Paths; import java.util.ArrayList; @@ -56,7 +57,9 @@ static Optional> parse(String gapicYamlConfigFilePat String fileContents = null; try { - fileContents = new String(Files.readAllBytes(Paths.get(gapicYamlConfigFilePath))); + fileContents = + new String( + Files.readAllBytes(Paths.get(gapicYamlConfigFilePath)), StandardCharsets.UTF_8); } catch (IOException e) { return Optional.empty(); } diff --git a/src/main/java/com/google/api/generator/gapic/protoparser/MethodSignatureParser.java b/src/main/java/com/google/api/generator/gapic/protoparser/MethodSignatureParser.java index 4d7259790a..9ca9825def 100644 --- a/src/main/java/com/google/api/generator/gapic/protoparser/MethodSignatureParser.java +++ b/src/main/java/com/google/api/generator/gapic/protoparser/MethodSignatureParser.java @@ -284,15 +284,4 @@ private static Map parseTypeFromArgumentName( argumentFieldPathAcc, outputArgResourceNames); } - - private static Map createPatternResourceNameMap( - Map resourceNames) { - Map patternsToResourceNames = new HashMap<>(); - for (ResourceName resourceName : resourceNames.values()) { - for (String pattern : resourceName.patterns()) { - patternsToResourceNames.put(pattern, resourceName); - } - } - return patternsToResourceNames; - } } 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 1ccfc3d1eb..0338de6374 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 @@ -121,8 +121,8 @@ public static GapicContext parse(CodeGeneratorRequest request) { boolean willGenerateMetadata = PluginArgumentParser.hasMetadataFlag(request); Optional serviceConfigPathOpt = PluginArgumentParser.parseJsonConfigPath(request); - String serviceConfigPath = serviceConfigPathOpt.isPresent() ? serviceConfigPathOpt.get() : null; - Optional serviceConfigOpt = ServiceConfigParser.parse(serviceConfigPath); + Optional serviceConfigOpt = + ServiceConfigParser.parse(serviceConfigPathOpt.orElse(null)); if (serviceConfigOpt.isPresent()) { GapicServiceConfig serviceConfig = serviceConfigOpt.get(); serviceConfig.setLroRetrySettings(lroRetrySettingsOpt); @@ -134,9 +134,7 @@ public static GapicContext parse(CodeGeneratorRequest request) { Optional serviceYamlConfigPathOpt = PluginArgumentParser.parseServiceYamlConfigPath(request); Optional serviceYamlProtoOpt = - serviceYamlConfigPathOpt.isPresent() - ? ServiceYamlParser.parse(serviceYamlConfigPathOpt.get()) - : Optional.empty(); + serviceYamlConfigPathOpt.flatMap(ServiceYamlParser::parse); // Collect the resource references seen in messages. Set outputResourceReferencesSeen = new HashSet<>(); @@ -177,7 +175,7 @@ public static GapicContext parse(CodeGeneratorRequest request) { Function typeNameFn = r -> r.resourceTypeString().substring(r.resourceTypeString().indexOf("/") + 1); Function, Set> typeStringSetFn = - sr -> sr.stream().map(r -> typeNameFn.apply(r)).collect(Collectors.toSet()); + sr -> sr.stream().map(typeNameFn).collect(Collectors.toSet()); // Include all resource names present in message types for backwards-compatibility with the // monolith. In the future, this should be removed on a client library major semver update. @@ -208,9 +206,9 @@ public static GapicContext parse(CodeGeneratorRequest request) { .setMessages(messages) .setResourceNames(resourceNames) .setHelperResourceNames(outputArgResourceNames) - .setServiceConfig(serviceConfigOpt.isPresent() ? serviceConfigOpt.get() : null) + .setServiceConfig(serviceConfigOpt.orElse(null)) .setGapicMetadataEnabled(willGenerateMetadata) - .setServiceYamlProto(serviceYamlProtoOpt.isPresent() ? serviceYamlProtoOpt.get() : null) + .setServiceYamlProto(serviceYamlProtoOpt.orElse(null)) .setTransport(transport) .build(); } @@ -384,7 +382,7 @@ public static List parseServices( outputMixinServices.addAll( outputMixinServiceSet.stream() .sorted((s1, s2) -> s2.name().compareTo(s1.name())) - .collect(Collectors.toSet())); + .collect(Collectors.toList())); return services; } @@ -539,7 +537,7 @@ public static Map parseMessages( private static Map parseMessages( Descriptor messageDescriptor, Set outputResourceReferencesSeen) { - return parseMessages(messageDescriptor, outputResourceReferencesSeen, new ArrayList()); + return parseMessages(messageDescriptor, outputResourceReferencesSeen, new ArrayList<>()); } private static Map parseMessages( @@ -903,7 +901,7 @@ static String parsePageSizeFieldName( @VisibleForTesting static String sanitizeDefaultHost(String rawDefaultHost) { - if (rawDefaultHost.indexOf(COLON) >= 0) { + if (rawDefaultHost.contains(COLON)) { // A port is already present, just return the existing string. return rawDefaultHost; } diff --git a/src/main/java/com/google/api/generator/gapic/protoparser/ServiceYamlParser.java b/src/main/java/com/google/api/generator/gapic/protoparser/ServiceYamlParser.java index 839903d460..5b136b897f 100644 --- a/src/main/java/com/google/api/generator/gapic/protoparser/ServiceYamlParser.java +++ b/src/main/java/com/google/api/generator/gapic/protoparser/ServiceYamlParser.java @@ -21,6 +21,7 @@ import com.google.protobuf.util.JsonFormat; import java.io.File; import java.io.IOException; +import java.nio.charset.StandardCharsets; import java.nio.file.Files; import java.nio.file.Paths; import java.util.LinkedHashMap; @@ -37,7 +38,8 @@ public static Optional parse(String serviceYamlFilePath) String fileContents = null; try { - fileContents = new String(Files.readAllBytes(Paths.get(serviceYamlFilePath))); + fileContents = + new String(Files.readAllBytes(Paths.get(serviceYamlFilePath)), StandardCharsets.UTF_8); } catch (IOException e) { return Optional.empty(); } diff --git a/src/main/java/com/google/api/generator/gapic/protoparser/TypeParser.java b/src/main/java/com/google/api/generator/gapic/protoparser/TypeParser.java index 7a4542ee25..49b17d25db 100644 --- a/src/main/java/com/google/api/generator/gapic/protoparser/TypeParser.java +++ b/src/main/java/com/google/api/generator/gapic/protoparser/TypeParser.java @@ -37,8 +37,6 @@ import javax.annotation.Nonnull; public class TypeParser { - private static final String DOT = "."; - private static Reference REFERENCE_BYTE_STRING = ConcreteReference.withClazz(ByteString.class); private static TypeNode TYPE_NODE_BYTE_STRING = TypeNode.withReference(REFERENCE_BYTE_STRING); @@ -245,8 +243,6 @@ static Reference parseEnumReference(@Nonnull EnumDescriptor enumDescriptor) { @VisibleForTesting static TypeNode createListType(FieldDescriptor field) { - JavaType protoFieldType = field.getJavaType(); - Reference listReference = ConcreteReference.builder() .setClazz(List.class) @@ -259,7 +255,6 @@ static TypeNode createListType(FieldDescriptor field) { static TypeNode createMapType(FieldDescriptor field) { Preconditions.checkState( field.isMapField(), "createMapType can only be called on map-type fields"); - JavaType protoJavaType = field.getJavaType(); Descriptor type = field.getMessageType(); FieldDescriptor keyField = type.findFieldByName("key"); diff --git a/src/main/java/com/google/api/generator/gapic/protowriter/Writer.java b/src/main/java/com/google/api/generator/gapic/protowriter/Writer.java index 0113776cee..634174acca 100644 --- a/src/main/java/com/google/api/generator/gapic/protowriter/Writer.java +++ b/src/main/java/com/google/api/generator/gapic/protowriter/Writer.java @@ -24,6 +24,7 @@ import com.google.protobuf.compiler.PluginProtos.CodeGeneratorResponse; import com.google.protobuf.util.JsonFormat; import java.io.IOException; +import java.nio.charset.StandardCharsets; import java.util.List; import java.util.jar.JarEntry; import java.util.jar.JarOutputStream; @@ -61,7 +62,7 @@ public static CodeGeneratorResponse write( JarEntry jarEntry = new JarEntry(String.format("%s/%s.java", path, className)); try { jos.putNextEntry(jarEntry); - jos.write(code.getBytes()); + jos.write(code.getBytes(StandardCharsets.UTF_8)); } catch (IOException e) { throw new GapicWriterException( String.format( @@ -80,7 +81,7 @@ public static CodeGeneratorResponse write( JarEntry jarEntry = new JarEntry(String.format("%s/package-info.java", path)); try { jos.putNextEntry(jarEntry); - jos.write(code.getBytes()); + jos.write(code.getBytes(StandardCharsets.UTF_8)); } catch (IOException e) { throw new GapicWriterException("Could not write code for package-info.java"); } @@ -90,7 +91,8 @@ public static CodeGeneratorResponse write( jarEntry = new JarEntry(String.format("%s/gapic_metadata.json", path)); try { jos.putNextEntry(jarEntry); - jos.write(JsonFormat.printer().print(context.gapicMetadata()).getBytes()); + jos.write( + JsonFormat.printer().print(context.gapicMetadata()).getBytes(StandardCharsets.UTF_8)); } catch (IOException e) { throw new GapicWriterException("Could not write gapic_metadata.json"); } diff --git a/src/main/java/com/google/api/generator/util/Trie.java b/src/main/java/com/google/api/generator/util/Trie.java index 51a26180bc..4134b3f543 100644 --- a/src/main/java/com/google/api/generator/util/Trie.java +++ b/src/main/java/com/google/api/generator/util/Trie.java @@ -24,17 +24,17 @@ * A common-prefix trie. T represents the type of each "char" in a word (which is a T-typed list). */ public class Trie { - private class Node { - final T chr; + private class Node { + final U chr; // Maintain insertion order to enable deterministic test output. - Map> children = new LinkedHashMap<>(); + Map> children = new LinkedHashMap<>(); boolean isLeaf; Node() { chr = null; } - Node(T chr) { + Node(U chr) { this.chr = chr; } } @@ -42,18 +42,18 @@ private class Node { private Node root; public Trie() { - root = new Node(); + root = new Node<>(); } public void insert(List word) { Map> children = root.children; for (int i = 0; i < word.size(); i++) { T chr = word.get(i); - Node t; + Node t; if (children.containsKey(chr)) { t = children.get(chr); } else { - t = new Node(chr); + t = new Node<>(chr); children.put(chr, t); } children = t.children; @@ -65,7 +65,7 @@ public void insert(List word) { /** Returns true if the word is in the trie. */ public boolean search(List word) { - Node node = searchNode(word); + Node node = searchNode(word); return node != null && node.isLeaf; } @@ -119,11 +119,10 @@ private R dfsTraverseAndReduce( return parentPostprocFn.apply(node.chr, baseValue, leafReducedValue); } - private Node searchNode(List word) { + private Node searchNode(List word) { Map> children = root.children; - Node t = null; - for (int i = 0; i < word.size(); i++) { - T chr = word.get(i); + Node t = null; + for (T chr : word) { if (children.containsKey(chr)) { t = children.get(chr); children = t.children; diff --git a/src/test/java/com/google/api/generator/engine/JavaCodeGeneratorTest.java b/src/test/java/com/google/api/generator/engine/JavaCodeGeneratorTest.java index 6f1e80ca70..607ccd89f6 100644 --- a/src/test/java/com/google/api/generator/engine/JavaCodeGeneratorTest.java +++ b/src/test/java/com/google/api/generator/engine/JavaCodeGeneratorTest.java @@ -297,7 +297,7 @@ private VariableExpr createVarPublicDeclExpr(Variable var) { .build(); } - private NewObjectExpr createNewObjectExpr(Class clazz) { + private NewObjectExpr createNewObjectExpr(Class clazz) { return NewObjectExpr.builder() .setType(TypeNode.withReference(ConcreteReference.withClazz(clazz))) .setIsGeneric(true) @@ -460,11 +460,8 @@ private MethodDefinition createOverrideCreateBookMethod( } private MethodDefinition createAddShelfMethod() { - ConcreteReference integerUtilRef = - ConcreteReference.builder().setClazz(Integer.class).setIsStaticImport(true).build(); Variable nameVar = createVarFromType(TypeNode.STRING, "name"); Variable seriesDoubleNumVar = createVarFromType(TypeNode.DOUBLE, "seriesDoubleNum"); - Variable maxValueVar = createVarFromConcreteRef(integerUtilRef, "MAX_VALUE"); CastExpr seriesNumDoubleToIntExpr = CastExpr.builder() .setExpr(VariableExpr.withVariable(seriesDoubleNumVar)) diff --git a/src/test/java/com/google/api/generator/engine/ast/AnonymousClassExprTest.java b/src/test/java/com/google/api/generator/engine/ast/AnonymousClassExprTest.java index b53fa9e77b..9fab46d98d 100644 --- a/src/test/java/com/google/api/generator/engine/ast/AnonymousClassExprTest.java +++ b/src/test/java/com/google/api/generator/engine/ast/AnonymousClassExprTest.java @@ -14,9 +14,9 @@ package com.google.api.generator.engine.ast; -import static junit.framework.Assert.assertEquals; -import static junit.framework.Assert.assertTrue; +import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertThrows; +import static org.junit.Assert.assertTrue; import com.google.common.base.Function; import java.util.Arrays; @@ -103,10 +103,7 @@ public void validAnonymousClass_genericAndVariableExpr() { public void invalidAnonymousClass_primitiveType() { assertThrows( IllegalStateException.class, - () -> { - AnonymousClassExpr anonymousClassExpr = - AnonymousClassExpr.builder().setType(TypeNode.INT).build(); - }); + () -> AnonymousClassExpr.builder().setType(TypeNode.INT).build()); } @Test @@ -126,10 +123,7 @@ public void invalidAnonymousClass_staticMethod() { assertThrows( IllegalStateException.class, - () -> { - AnonymousClassExpr anonymousClassExpr = - AnonymousClassExpr.builder().setType(type).setMethods(Arrays.asList(method)).build(); - }); + () -> AnonymousClassExpr.builder().setType(type).setMethods(Arrays.asList(method)).build()); } @Test @@ -145,10 +139,7 @@ public void invalidAnonymousClass_explicitConstructor() { .build(); assertThrows( IllegalStateException.class, - () -> { - AnonymousClassExpr anonymousClassExpr = - AnonymousClassExpr.builder().setType(type).setMethods(Arrays.asList(method)).build(); - }); + () -> AnonymousClassExpr.builder().setType(type).setMethods(Arrays.asList(method)).build()); } @Test @@ -162,13 +153,11 @@ public void invalidAnonymousClass_staticVariableExpr() { ExprStatement exprStatement = ExprStatement.withExpr(variableExpr); assertThrows( IllegalStateException.class, - () -> { - AnonymousClassExpr anonymousClassExpr = - AnonymousClassExpr.builder() - .setType(type) - .setStatements(Arrays.asList(exprStatement)) - .build(); - }); + () -> + AnonymousClassExpr.builder() + .setType(type) + .setStatements(Arrays.asList(exprStatement)) + .build()); } private static AssignmentExpr createAssignmentExpr( diff --git a/src/test/java/com/google/api/generator/engine/ast/CastExprTest.java b/src/test/java/com/google/api/generator/engine/ast/CastExprTest.java index f39bff072a..04bb8a05ca 100644 --- a/src/test/java/com/google/api/generator/engine/ast/CastExprTest.java +++ b/src/test/java/com/google/api/generator/engine/ast/CastExprTest.java @@ -32,8 +32,6 @@ public void validCastExpr_basic() { @Test public void validCastExpr_basicNull() { - Variable variable = Variable.builder().setName("x").setType(TypeNode.STRING).build(); - VariableExpr variableExpr = VariableExpr.builder().setVariable(variable).build(); CastExpr.builder() .setType(TypeNode.withReference(ConcreteReference.withClazz(Object.class))) .setExpr(ValueExpr.createNullExpr()) diff --git a/src/test/java/com/google/api/generator/engine/ast/ConcreteReferenceTest.java b/src/test/java/com/google/api/generator/engine/ast/ConcreteReferenceTest.java index d45c9bdc37..6fdc65a937 100644 --- a/src/test/java/com/google/api/generator/engine/ast/ConcreteReferenceTest.java +++ b/src/test/java/com/google/api/generator/engine/ast/ConcreteReferenceTest.java @@ -14,9 +14,9 @@ package com.google.api.generator.engine.ast; -import static junit.framework.Assert.assertEquals; -import static junit.framework.Assert.assertFalse; -import static junit.framework.Assert.assertTrue; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; import java.util.ArrayList; import java.util.Arrays; diff --git a/src/test/java/com/google/api/generator/engine/ast/ForStatementTest.java b/src/test/java/com/google/api/generator/engine/ast/ForStatementTest.java index 7eb401637f..569eebb3c0 100644 --- a/src/test/java/com/google/api/generator/engine/ast/ForStatementTest.java +++ b/src/test/java/com/google/api/generator/engine/ast/ForStatementTest.java @@ -49,14 +49,12 @@ public void invalidForStatement() { MethodInvocationExpr.builder().setMethodName("getSomeStrings").build(); assertThrows( IllegalStateException.class, - () -> { - ForStatement forStatement = - ForStatement.builder() - .setLocalVariableExpr(variableExpr) - .setCollectionExpr(methodExpr) - .setBody(Arrays.asList(ExprStatement.withExpr(createAssignmentExpr()))) - .build(); - }); + () -> + ForStatement.builder() + .setLocalVariableExpr(variableExpr) + .setCollectionExpr(methodExpr) + .setBody(Arrays.asList(ExprStatement.withExpr(createAssignmentExpr()))) + .build()); } private static AssignmentExpr createAssignmentExpr() { diff --git a/src/test/java/com/google/api/generator/engine/ast/IdentifierNodeTest.java b/src/test/java/com/google/api/generator/engine/ast/IdentifierNodeTest.java index b4a7453337..ead7d8be37 100644 --- a/src/test/java/com/google/api/generator/engine/ast/IdentifierNodeTest.java +++ b/src/test/java/com/google/api/generator/engine/ast/IdentifierNodeTest.java @@ -14,7 +14,7 @@ package com.google.api.generator.engine.ast; -import static junit.framework.Assert.assertEquals; +import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertThrows; import com.google.api.generator.engine.ast.IdentifierNode.InvalidIdentifierException; diff --git a/src/test/java/com/google/api/generator/engine/ast/JavaDocCommentTest.java b/src/test/java/com/google/api/generator/engine/ast/JavaDocCommentTest.java index 8e969a4f45..0d3550971d 100644 --- a/src/test/java/com/google/api/generator/engine/ast/JavaDocCommentTest.java +++ b/src/test/java/com/google/api/generator/engine/ast/JavaDocCommentTest.java @@ -14,7 +14,7 @@ package com.google.api.generator.engine.ast; -import static junit.framework.Assert.assertEquals; +import static org.junit.Assert.assertEquals; import com.google.api.generator.testutils.LineFormatter; import java.util.Arrays; diff --git a/src/test/java/com/google/api/generator/engine/ast/NewObjectExprTest.java b/src/test/java/com/google/api/generator/engine/ast/NewObjectExprTest.java index 1bc2c48cd6..2287a75394 100644 --- a/src/test/java/com/google/api/generator/engine/ast/NewObjectExprTest.java +++ b/src/test/java/com/google/api/generator/engine/ast/NewObjectExprTest.java @@ -14,7 +14,7 @@ package com.google.api.generator.engine.ast; -import static junit.framework.Assert.assertEquals; +import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertThrows; import java.util.Arrays; diff --git a/src/test/java/com/google/api/generator/engine/ast/NullObjectValueTest.java b/src/test/java/com/google/api/generator/engine/ast/NullObjectValueTest.java index 22e3434ea3..fa9dfa2669 100644 --- a/src/test/java/com/google/api/generator/engine/ast/NullObjectValueTest.java +++ b/src/test/java/com/google/api/generator/engine/ast/NullObjectValueTest.java @@ -15,7 +15,7 @@ package com.google.api.generator.engine.ast; import static com.google.common.truth.Truth.assertThat; -import static junit.framework.Assert.assertEquals; +import static org.junit.Assert.assertEquals; import org.junit.Test; diff --git a/src/test/java/com/google/api/generator/engine/ast/PrimitiveValueTest.java b/src/test/java/com/google/api/generator/engine/ast/PrimitiveValueTest.java index 9c2f034d4c..37c3ae9cc4 100644 --- a/src/test/java/com/google/api/generator/engine/ast/PrimitiveValueTest.java +++ b/src/test/java/com/google/api/generator/engine/ast/PrimitiveValueTest.java @@ -15,7 +15,7 @@ package com.google.api.generator.engine.ast; import static com.google.common.truth.Truth.assertThat; -import static junit.framework.Assert.assertEquals; +import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertThrows; import com.google.api.generator.engine.ast.TypeNode.TypeKind; diff --git a/src/test/java/com/google/api/generator/engine/ast/ReferenceTest.java b/src/test/java/com/google/api/generator/engine/ast/ReferenceTest.java index 4fb0dca02d..b4e4b43496 100644 --- a/src/test/java/com/google/api/generator/engine/ast/ReferenceTest.java +++ b/src/test/java/com/google/api/generator/engine/ast/ReferenceTest.java @@ -14,8 +14,8 @@ package com.google.api.generator.engine.ast; -import static junit.framework.Assert.assertEquals; -import static junit.framework.Assert.assertFalse; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; import java.util.Arrays; import java.util.HashMap; diff --git a/src/test/java/com/google/api/generator/engine/ast/ThrowExprTest.java b/src/test/java/com/google/api/generator/engine/ast/ThrowExprTest.java index 7bc1589feb..cc4b38f3df 100644 --- a/src/test/java/com/google/api/generator/engine/ast/ThrowExprTest.java +++ b/src/test/java/com/google/api/generator/engine/ast/ThrowExprTest.java @@ -14,7 +14,7 @@ package com.google.api.generator.engine.ast; -import static junit.framework.Assert.assertEquals; +import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertThrows; import org.junit.Test; diff --git a/src/test/java/com/google/api/generator/engine/ast/TryCatchStatementTest.java b/src/test/java/com/google/api/generator/engine/ast/TryCatchStatementTest.java index f19722f182..9837c192f5 100644 --- a/src/test/java/com/google/api/generator/engine/ast/TryCatchStatementTest.java +++ b/src/test/java/com/google/api/generator/engine/ast/TryCatchStatementTest.java @@ -15,7 +15,7 @@ package com.google.api.generator.engine.ast; import static com.google.common.truth.Truth.assertThat; -import static junit.framework.Assert.assertEquals; +import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertThrows; import java.util.Arrays; @@ -86,11 +86,6 @@ public void validTryCatchStatement_withResources() { @Test public void validTryCatchStatement_sampleCode() { - Reference exceptionReference = ConcreteReference.withClazz(IllegalArgumentException.class); - TypeNode type = TypeNode.withReference(exceptionReference); - VariableExpr variableExpr = - VariableExpr.builder().setVariable(createVariable("e", type)).setIsDecl(true).build(); - TryCatchStatement tryCatch = TryCatchStatement.builder() .setTryBody(Arrays.asList(ExprStatement.withExpr(createAssignmentExpr()))) @@ -101,18 +96,12 @@ public void validTryCatchStatement_sampleCode() { @Test public void invalidTryCatchStatement_missingCatchVariable() { - Reference exceptionReference = ConcreteReference.withClazz(IllegalArgumentException.class); - TypeNode type = TypeNode.withReference(exceptionReference); - VariableExpr variableExpr = - VariableExpr.builder().setVariable(createVariable("e", type)).setIsDecl(true).build(); - assertThrows( IllegalStateException.class, - () -> { - TryCatchStatement.builder() - .setTryBody(Arrays.asList(ExprStatement.withExpr(createAssignmentExpr()))) - .build(); - }); + () -> + TryCatchStatement.builder() + .setTryBody(Arrays.asList(ExprStatement.withExpr(createAssignmentExpr()))) + .build()); } @Test @@ -124,13 +113,11 @@ public void invalidTryCatchStatement_catchVariableNotDecl() { assertThrows( IllegalStateException.class, - () -> { - TryCatchStatement tryCatch = - TryCatchStatement.builder() - .setTryBody(Arrays.asList(ExprStatement.withExpr(createAssignmentExpr()))) - .addCatch(variableExpr, Collections.emptyList()) - .build(); - }); + () -> + TryCatchStatement.builder() + .setTryBody(Arrays.asList(ExprStatement.withExpr(createAssignmentExpr()))) + .addCatch(variableExpr, Collections.emptyList()) + .build()); } @Test @@ -142,13 +129,11 @@ public void invalidTryCatchStatement_nonExceptionReference() { assertThrows( IllegalStateException.class, - () -> { - TryCatchStatement tryCatch = - TryCatchStatement.builder() - .setTryBody(Arrays.asList(ExprStatement.withExpr(createAssignmentExpr()))) - .addCatch(variableExpr, Collections.emptyList()) - .build(); - }); + () -> + TryCatchStatement.builder() + .setTryBody(Arrays.asList(ExprStatement.withExpr(createAssignmentExpr()))) + .addCatch(variableExpr, Collections.emptyList()) + .build()); } private static AssignmentExpr createAssignmentExpr() { diff --git a/src/test/java/com/google/api/generator/engine/ast/TypeNodeTest.java b/src/test/java/com/google/api/generator/engine/ast/TypeNodeTest.java index 77c649e72f..5b80fdedc0 100644 --- a/src/test/java/com/google/api/generator/engine/ast/TypeNodeTest.java +++ b/src/test/java/com/google/api/generator/engine/ast/TypeNodeTest.java @@ -15,9 +15,9 @@ package com.google.api.generator.engine.ast; import static com.google.common.truth.Truth.assertThat; -import static junit.framework.Assert.assertFalse; -import static junit.framework.Assert.assertTrue; +import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertThrows; +import static org.junit.Assert.assertTrue; import com.google.api.generator.engine.ast.TypeNode.TypeKind; import java.util.Arrays; diff --git a/src/test/java/com/google/api/generator/engine/ast/VaporReferenceTest.java b/src/test/java/com/google/api/generator/engine/ast/VaporReferenceTest.java index c8a662fdc9..486bc2efab 100644 --- a/src/test/java/com/google/api/generator/engine/ast/VaporReferenceTest.java +++ b/src/test/java/com/google/api/generator/engine/ast/VaporReferenceTest.java @@ -14,9 +14,9 @@ package com.google.api.generator.engine.ast; -import static junit.framework.Assert.assertEquals; -import static junit.framework.Assert.assertFalse; -import static junit.framework.Assert.assertTrue; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; import org.junit.Test; @@ -52,7 +52,6 @@ public void basic_isStaticImport() { public void basic_nested() { String pkg = "com.google.example.examples.library.v1"; String name = "Charles"; - String enclosingClassName = "Babbage"; Reference ref = VaporReference.builder() .setEnclosingClassNames("Babbage", "Ada") diff --git a/src/test/java/com/google/api/generator/engine/ast/VariableTest.java b/src/test/java/com/google/api/generator/engine/ast/VariableTest.java index 4f0b6c4743..b11cfd0662 100644 --- a/src/test/java/com/google/api/generator/engine/ast/VariableTest.java +++ b/src/test/java/com/google/api/generator/engine/ast/VariableTest.java @@ -15,7 +15,7 @@ package com.google.api.generator.engine.ast; import static com.google.common.truth.Truth.assertThat; -import static junit.framework.Assert.assertEquals; +import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertThrows; import com.google.api.generator.engine.ast.TypeNode.TypeKind; diff --git a/src/test/java/com/google/api/generator/engine/writer/ImportWriterVisitorTest.java b/src/test/java/com/google/api/generator/engine/writer/ImportWriterVisitorTest.java index 6b9d20ff0b..07be47a996 100644 --- a/src/test/java/com/google/api/generator/engine/writer/ImportWriterVisitorTest.java +++ b/src/test/java/com/google/api/generator/engine/writer/ImportWriterVisitorTest.java @@ -15,7 +15,7 @@ package com.google.api.generator.engine.writer; import static com.google.common.truth.Truth.assertThat; -import static junit.framework.Assert.assertEquals; +import static org.junit.Assert.assertEquals; import com.google.api.generator.engine.ast.AnnotationNode; import com.google.api.generator.engine.ast.AnonymousClassExpr; @@ -894,10 +894,6 @@ public void writeLambdaExprImports() { } /** =============================== HELPERS =============================== */ - private static TypeNode createType(Class clazz) { - return TypeNode.withReference(ConcreteReference.withClazz(clazz)); - } - private static Variable createVariable(String variableName, TypeNode type) { return Variable.builder().setName(variableName).setType(type).build(); } diff --git a/src/test/java/com/google/api/generator/engine/writer/JavaWriterVisitorTest.java b/src/test/java/com/google/api/generator/engine/writer/JavaWriterVisitorTest.java index 902f3ee4a8..39e448a263 100644 --- a/src/test/java/com/google/api/generator/engine/writer/JavaWriterVisitorTest.java +++ b/src/test/java/com/google/api/generator/engine/writer/JavaWriterVisitorTest.java @@ -15,7 +15,7 @@ package com.google.api.generator.engine.writer; import static com.google.common.truth.Truth.assertThat; -import static junit.framework.Assert.assertEquals; +import static org.junit.Assert.assertEquals; import com.google.api.generator.engine.ast.AnnotationNode; import com.google.api.generator.engine.ast.AnonymousClassExpr; @@ -334,7 +334,6 @@ public void writeVariableExpr_localFinalDecl() { @Test public void writeVariableExpr_scopedDecl() { - IdentifierNode identifier = IdentifierNode.builder().setName("x").build(); Variable variable = Variable.builder().setName("x").setType(TypeNode.INT).build(); VariableExpr expr = VariableExpr.builder() @@ -349,7 +348,6 @@ public void writeVariableExpr_scopedDecl() { @Test public void writeVariableExpr_scopedStaticFinalDecl() { - IdentifierNode identifier = IdentifierNode.builder().setName("x").build(); Variable variable = Variable.builder().setName("x").setType(TypeNode.BOOLEAN).build(); VariableExpr expr = VariableExpr.builder() @@ -366,7 +364,6 @@ public void writeVariableExpr_scopedStaticFinalDecl() { @Test public void writeVariableExpr_scopedStaticFinalVolatileDecl() { - IdentifierNode identifier = IdentifierNode.builder().setName("x").build(); Variable variable = Variable.builder().setName("x").setType(TypeNode.BOOLEAN).build(); VariableExpr expr = VariableExpr.builder() @@ -644,9 +641,6 @@ public void writeJavaDocComment_specialChar() { @Test public void writeTernaryExpr_basic() { - Variable variable = Variable.builder().setName("x").setType(TypeNode.INT).build(); - VariableExpr variableExpr = VariableExpr.builder().setVariable(variable).build(); - Variable conditionVariable = Variable.builder().setName("condition").setType(TypeNode.BOOLEAN).build(); VariableExpr conditionExpr = VariableExpr.builder().setVariable(conditionVariable).build(); @@ -1579,11 +1573,6 @@ public void writeTryCatchStatement_withResources() { @Test public void writeTryCatchStatement_sampleCodeNoCatch() { - Reference exceptionReference = ConcreteReference.withClazz(IllegalArgumentException.class); - TypeNode type = TypeNode.withReference(exceptionReference); - VariableExpr variableExpr = - VariableExpr.builder().setVariable(createVariable("e", type)).setIsDecl(true).build(); - TryCatchStatement tryCatch = TryCatchStatement.builder() .setTryBody( diff --git a/src/test/java/com/google/api/generator/gapic/composer/common/BatchingDescriptorComposerTest.java b/src/test/java/com/google/api/generator/gapic/composer/common/BatchingDescriptorComposerTest.java index f2ac7a5da5..50fdf0fac3 100644 --- a/src/test/java/com/google/api/generator/gapic/composer/common/BatchingDescriptorComposerTest.java +++ b/src/test/java/com/google/api/generator/gapic/composer/common/BatchingDescriptorComposerTest.java @@ -14,8 +14,8 @@ package com.google.api.generator.gapic.composer.common; -import static junit.framework.Assert.assertEquals; -import static junit.framework.Assert.assertTrue; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; import com.google.api.generator.engine.ast.Expr; import com.google.api.generator.engine.writer.JavaWriterVisitor; diff --git a/src/test/java/com/google/api/generator/gapic/composer/common/RetrySettingsComposerTest.java b/src/test/java/com/google/api/generator/gapic/composer/common/RetrySettingsComposerTest.java index d3fa5aa2e9..598f261f8a 100644 --- a/src/test/java/com/google/api/generator/gapic/composer/common/RetrySettingsComposerTest.java +++ b/src/test/java/com/google/api/generator/gapic/composer/common/RetrySettingsComposerTest.java @@ -15,8 +15,8 @@ package com.google.api.generator.gapic.composer.common; import static com.google.common.truth.Truth.assertThat; -import static junit.framework.Assert.assertEquals; -import static junit.framework.Assert.assertTrue; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; import com.google.api.gax.rpc.StatusCode; import com.google.api.generator.engine.ast.BlockStatement; @@ -42,7 +42,6 @@ import com.google.common.collect.ImmutableMap; import com.google.common.collect.ImmutableSet; import com.google.protobuf.Descriptors.FileDescriptor; -import com.google.protobuf.Descriptors.ServiceDescriptor; import com.google.showcase.v1beta1.EchoOuterClass; import java.nio.file.Path; import java.nio.file.Paths; @@ -142,7 +141,6 @@ public void paramDefinitionsBlock_basic() { @Test public void codesDefinitionsBlock_noConfigsFound() { FileDescriptor echoFileDescriptor = EchoOuterClass.getDescriptor(); - ServiceDescriptor echoServiceDescriptor = echoFileDescriptor.getServices().get(0); Map messageTypes = Parser.parseMessages(echoFileDescriptor); Map resourceNames = Parser.parseResourceNames(echoFileDescriptor); Set outputResourceNames = new HashSet<>(); @@ -179,7 +177,6 @@ public void codesDefinitionsBlock_noConfigsFound() { @Test public void codesDefinitionsBlock_basic() { FileDescriptor echoFileDescriptor = EchoOuterClass.getDescriptor(); - ServiceDescriptor echoServiceDescriptor = echoFileDescriptor.getServices().get(0); Map messageTypes = Parser.parseMessages(echoFileDescriptor); Map resourceNames = Parser.parseResourceNames(echoFileDescriptor); Set outputResourceNames = new HashSet<>(); @@ -219,7 +216,6 @@ public void codesDefinitionsBlock_basic() { @Test public void simpleBuilderExpr_basic() { FileDescriptor echoFileDescriptor = EchoOuterClass.getDescriptor(); - ServiceDescriptor echoServiceDescriptor = echoFileDescriptor.getServices().get(0); Map messageTypes = Parser.parseMessages(echoFileDescriptor); Map resourceNames = Parser.parseResourceNames(echoFileDescriptor); Set outputResourceNames = new HashSet<>(); @@ -301,7 +297,6 @@ public void simpleBuilderExpr_basic() { @Test public void lroBuilderExpr() { FileDescriptor echoFileDescriptor = EchoOuterClass.getDescriptor(); - ServiceDescriptor echoServiceDescriptor = echoFileDescriptor.getServices().get(0); Map messageTypes = Parser.parseMessages(echoFileDescriptor); Map resourceNames = Parser.parseResourceNames(echoFileDescriptor); Set outputResourceNames = new HashSet<>(); 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 fd4d5942a4..e9eb95721d 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 @@ -14,8 +14,8 @@ package com.google.api.generator.gapic.composer.common; -import static junit.framework.Assert.assertEquals; -import static junit.framework.Assert.assertTrue; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; import com.google.api.generator.gapic.model.GapicBatchingSettings; import com.google.api.generator.gapic.model.GapicContext; diff --git a/src/test/java/com/google/api/generator/gapic/composer/defaultvalue/DefaultValueComposerTest.java b/src/test/java/com/google/api/generator/gapic/composer/defaultvalue/DefaultValueComposerTest.java index f612b7112d..cf444a270d 100644 --- a/src/test/java/com/google/api/generator/gapic/composer/defaultvalue/DefaultValueComposerTest.java +++ b/src/test/java/com/google/api/generator/gapic/composer/defaultvalue/DefaultValueComposerTest.java @@ -14,7 +14,7 @@ package com.google.api.generator.gapic.composer.defaultvalue; -import static junit.framework.Assert.assertEquals; +import static org.junit.Assert.assertEquals; import com.google.api.generator.engine.ast.ConcreteReference; import com.google.api.generator.engine.ast.Expr; diff --git a/src/test/java/com/google/api/generator/gapic/composer/grpc/ServiceClientTestClassComposerTest.java b/src/test/java/com/google/api/generator/gapic/composer/grpc/ServiceClientTestClassComposerTest.java index d2c1a50708..9874286d82 100644 --- a/src/test/java/com/google/api/generator/gapic/composer/grpc/ServiceClientTestClassComposerTest.java +++ b/src/test/java/com/google/api/generator/gapic/composer/grpc/ServiceClientTestClassComposerTest.java @@ -15,7 +15,7 @@ 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 static org.junit.Assert.assertEquals; import com.google.api.generator.engine.writer.JavaWriterVisitor; import com.google.api.generator.gapic.model.GapicClass; diff --git a/src/test/java/com/google/api/generator/gapic/composer/grpc/ServiceStubSettingsClassComposerTest.java b/src/test/java/com/google/api/generator/gapic/composer/grpc/ServiceStubSettingsClassComposerTest.java index b319bf8b50..468c2d8219 100644 --- a/src/test/java/com/google/api/generator/gapic/composer/grpc/ServiceStubSettingsClassComposerTest.java +++ b/src/test/java/com/google/api/generator/gapic/composer/grpc/ServiceStubSettingsClassComposerTest.java @@ -14,7 +14,7 @@ package com.google.api.generator.gapic.composer.grpc; -import static junit.framework.Assert.assertEquals; +import static org.junit.Assert.assertEquals; import com.google.api.generator.engine.writer.JavaWriterVisitor; import com.google.api.generator.gapic.model.GapicClass; 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 7f4117a0b5..c54218a52e 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 @@ -15,7 +15,7 @@ package com.google.api.generator.gapic.composer.resourcename; import static com.google.common.truth.Truth.assertThat; -import static junit.framework.Assert.assertEquals; +import static org.junit.Assert.assertEquals; import com.google.api.generator.engine.writer.JavaWriterVisitor; import com.google.api.generator.gapic.composer.common.TestProtoLoader; @@ -23,7 +23,6 @@ import com.google.api.generator.gapic.model.GapicContext; 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.protoparser.Parser; import com.google.api.generator.test.framework.Assert; import com.google.api.generator.test.framework.Utils; @@ -96,9 +95,8 @@ public void generateResourceNameClass_echoFoobarMultiplePatterns() { Map messageTypes = Parser.parseMessages(echoFileDescriptor); Map resourceNames = Parser.parseResourceNames(echoFileDescriptor); Set outputResourceNames = new HashSet<>(); - List services = - Parser.parseService( - echoFileDescriptor, messageTypes, resourceNames, Optional.empty(), outputResourceNames); + Parser.parseService( + echoFileDescriptor, messageTypes, resourceNames, Optional.empty(), outputResourceNames); ResourceName foobarResname = resourceNames.get("showcase.googleapis.com/Foobar"); assertThat(outputResourceNames).contains(foobarResname); @@ -140,13 +138,8 @@ public void generateResourceNameClass_loggingOnePatternMultipleVariables() { resourceNames.putAll(Parser.parseResourceNames(commonResourcesFileDescriptor)); Set outputResourceNames = new HashSet<>(); - List services = - Parser.parseService( - serviceFileDescriptor, - messageTypes, - resourceNames, - Optional.empty(), - outputResourceNames); + Parser.parseService( + serviceFileDescriptor, messageTypes, resourceNames, Optional.empty(), outputResourceNames); ResourceName billingAccountLocationResname = resourceNames.get("logging.googleapis.com/BillingAccountLocation"); @@ -173,13 +166,8 @@ public void generateResourceNameClass_testingSessionOnePattern() { Map messageTypes = Parser.parseMessages(testingFileDescriptor); Map resourceNames = Parser.parseResourceNames(testingFileDescriptor); Set outputResourceNames = new HashSet<>(); - List services = - Parser.parseService( - testingFileDescriptor, - messageTypes, - resourceNames, - Optional.empty(), - outputResourceNames); + Parser.parseService( + testingFileDescriptor, messageTypes, resourceNames, Optional.empty(), outputResourceNames); ResourceName sessionResname = resourceNames.get("showcase.googleapis.com/Session"); assertThat(outputResourceNames).contains(sessionResname); @@ -204,13 +192,8 @@ public void generateResourceNameClass_testingBlueprintPatternWithNonSlashSeparat Map messageTypes = Parser.parseMessages(testingFileDescriptor); Map resourceNames = Parser.parseResourceNames(testingFileDescriptor); Set outputResourceNames = new HashSet<>(); - List services = - Parser.parseService( - testingFileDescriptor, - messageTypes, - resourceNames, - Optional.empty(), - outputResourceNames); + Parser.parseService( + testingFileDescriptor, messageTypes, resourceNames, Optional.empty(), outputResourceNames); ResourceName testResname = resourceNames.get("showcase.googleapis.com/Test"); assertThat(outputResourceNames).contains(testResname); diff --git a/src/test/java/com/google/api/generator/gapic/composer/resourcename/ResourceNameTokenizerTest.java b/src/test/java/com/google/api/generator/gapic/composer/resourcename/ResourceNameTokenizerTest.java index 44ea5579bf..b49e731db2 100644 --- a/src/test/java/com/google/api/generator/gapic/composer/resourcename/ResourceNameTokenizerTest.java +++ b/src/test/java/com/google/api/generator/gapic/composer/resourcename/ResourceNameTokenizerTest.java @@ -15,7 +15,7 @@ package com.google.api.generator.gapic.composer.resourcename; import static com.google.common.truth.Truth.assertThat; -import static junit.framework.Assert.assertEquals; +import static org.junit.Assert.assertEquals; import com.google.protobuf.Descriptors.FileDescriptor; import com.google.protobuf.Descriptors.ServiceDescriptor; diff --git a/src/test/java/com/google/api/generator/gapic/composer/rest/RestTestProtoLoader.java b/src/test/java/com/google/api/generator/gapic/composer/rest/RestTestProtoLoader.java index c2e8ab8726..13ef1cea69 100644 --- a/src/test/java/com/google/api/generator/gapic/composer/rest/RestTestProtoLoader.java +++ b/src/test/java/com/google/api/generator/gapic/composer/rest/RestTestProtoLoader.java @@ -14,8 +14,8 @@ package com.google.api.generator.gapic.composer.rest; -import static junit.framework.Assert.assertEquals; -import static junit.framework.Assert.assertTrue; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; import com.google.api.generator.gapic.composer.common.TestProtoLoader; import com.google.api.generator.gapic.model.GapicContext; diff --git a/src/test/java/com/google/api/generator/gapic/composer/samplecode/ServiceClientSampleCodeComposerTest.java b/src/test/java/com/google/api/generator/gapic/composer/samplecode/ServiceClientSampleCodeComposerTest.java index e3ca743d8d..397e0ec2c2 100644 --- a/src/test/java/com/google/api/generator/gapic/composer/samplecode/ServiceClientSampleCodeComposerTest.java +++ b/src/test/java/com/google/api/generator/gapic/composer/samplecode/ServiceClientSampleCodeComposerTest.java @@ -14,7 +14,7 @@ package com.google.api.generator.gapic.composer.samplecode; -import static junit.framework.Assert.assertEquals; +import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertThrows; import com.google.api.generator.engine.ast.ConcreteReference; @@ -32,7 +32,6 @@ import com.google.api.generator.gapic.protoparser.Parser; import com.google.api.generator.testutils.LineFormatter; import com.google.protobuf.Descriptors.FileDescriptor; -import com.google.protobuf.Descriptors.ServiceDescriptor; import com.google.showcase.v1beta1.EchoOuterClass; import java.util.Arrays; import java.util.Collections; @@ -55,7 +54,6 @@ public void composeClassHeaderMethodSampleCode_unaryRpc() { FileDescriptor echoFileDescriptor = EchoOuterClass.getDescriptor(); Map resourceNames = Parser.parseResourceNames(echoFileDescriptor); Map messageTypes = Parser.parseMessages(echoFileDescriptor); - ServiceDescriptor echoService = echoFileDescriptor.getServices().get(0); Set outputResourceNames = new HashSet<>(); List services = Parser.parseService( diff --git a/src/test/java/com/google/api/generator/gapic/composer/samplecode/SettingsSampleCodeComposerTest.java b/src/test/java/com/google/api/generator/gapic/composer/samplecode/SettingsSampleCodeComposerTest.java index b00985942f..a62d57275c 100644 --- a/src/test/java/com/google/api/generator/gapic/composer/samplecode/SettingsSampleCodeComposerTest.java +++ b/src/test/java/com/google/api/generator/gapic/composer/samplecode/SettingsSampleCodeComposerTest.java @@ -14,7 +14,7 @@ package com.google.api.generator.gapic.composer.samplecode; -import static junit.framework.Assert.assertEquals; +import static org.junit.Assert.assertEquals; import com.google.api.generator.engine.ast.TypeNode; import com.google.api.generator.engine.ast.VaporReference; diff --git a/src/test/java/com/google/api/generator/gapic/composer/utils/PackageCheckerTest.java b/src/test/java/com/google/api/generator/gapic/composer/utils/PackageCheckerTest.java index 9cde282e24..c8f220f65e 100644 --- a/src/test/java/com/google/api/generator/gapic/composer/utils/PackageCheckerTest.java +++ b/src/test/java/com/google/api/generator/gapic/composer/utils/PackageCheckerTest.java @@ -14,8 +14,8 @@ package com.google.api.generator.gapic.composer.utils; -import static junit.framework.Assert.assertFalse; -import static junit.framework.Assert.assertTrue; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; import org.junit.Test; diff --git a/src/test/java/com/google/api/generator/gapic/model/GapicServiceConfigTest.java b/src/test/java/com/google/api/generator/gapic/model/GapicServiceConfigTest.java index 61f9e45b02..6c5a0846e7 100644 --- a/src/test/java/com/google/api/generator/gapic/model/GapicServiceConfigTest.java +++ b/src/test/java/com/google/api/generator/gapic/model/GapicServiceConfigTest.java @@ -15,14 +15,13 @@ package com.google.api.generator.gapic.model; 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.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; import com.google.api.generator.gapic.protoparser.Parser; import com.google.api.generator.gapic.protoparser.ServiceConfigParser; import com.google.protobuf.Descriptors.FileDescriptor; -import com.google.protobuf.Descriptors.ServiceDescriptor; import com.google.protobuf.util.Durations; import com.google.rpc.Code; import com.google.showcase.v1beta1.EchoOuterClass; @@ -45,7 +44,6 @@ public class GapicServiceConfigTest { @Test public void serviceConfig_noConfigsFound() { FileDescriptor echoFileDescriptor = EchoOuterClass.getDescriptor(); - ServiceDescriptor echoServiceDescriptor = echoFileDescriptor.getServices().get(0); Service service = parseService(echoFileDescriptor); String jsonFilename = "retrying_grpc_service_config.json"; @@ -74,7 +72,6 @@ public void serviceConfig_noConfigsFound() { @Test public void serviceConfig_basic() { FileDescriptor echoFileDescriptor = EchoOuterClass.getDescriptor(); - ServiceDescriptor echoServiceDescriptor = echoFileDescriptor.getServices().get(0); Service service = parseService(echoFileDescriptor); String jsonFilename = "showcase_grpc_service_config.json"; @@ -129,7 +126,6 @@ public void serviceConfig_basic() { @Test public void serviceConfig_withBatchingSettings() { FileDescriptor echoFileDescriptor = EchoOuterClass.getDescriptor(); - ServiceDescriptor echoServiceDescriptor = echoFileDescriptor.getServices().get(0); Service service = parseService(echoFileDescriptor); String jsonFilename = "showcase_grpc_service_config.json"; @@ -203,12 +199,10 @@ public void serviceConfig_withBatchingSettings() { @Test public void serviceConfig_withLroRetrySettings() { FileDescriptor echoFileDescriptor = EchoOuterClass.getDescriptor(); - ServiceDescriptor echoServiceDescriptor = echoFileDescriptor.getServices().get(0); Service service = parseService(echoFileDescriptor); String jsonFilename = "showcase_grpc_service_config.json"; Path jsonPath = Paths.get(TESTDATA_DIRECTORY, jsonFilename); - Optional> batchingSettingsOpt = Optional.empty(); // Construct LRO retry settings. GapicLroRetrySettings origLroRetrySetting = diff --git a/src/test/java/com/google/api/generator/gapic/protoparser/BatchingSettingsConfigParserTest.java b/src/test/java/com/google/api/generator/gapic/protoparser/BatchingSettingsConfigParserTest.java index 92ba2e5094..3d3c16dc6e 100644 --- a/src/test/java/com/google/api/generator/gapic/protoparser/BatchingSettingsConfigParserTest.java +++ b/src/test/java/com/google/api/generator/gapic/protoparser/BatchingSettingsConfigParserTest.java @@ -15,9 +15,9 @@ package com.google.api.generator.gapic.protoparser; 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.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; import com.google.api.generator.gapic.model.GapicBatchingSettings; import java.nio.file.Path; diff --git a/src/test/java/com/google/api/generator/gapic/protoparser/GapicLanguageSettingsParserTest.java b/src/test/java/com/google/api/generator/gapic/protoparser/GapicLanguageSettingsParserTest.java index 111abd1a80..1db960c0ab 100644 --- a/src/test/java/com/google/api/generator/gapic/protoparser/GapicLanguageSettingsParserTest.java +++ b/src/test/java/com/google/api/generator/gapic/protoparser/GapicLanguageSettingsParserTest.java @@ -14,8 +14,8 @@ package com.google.api.generator.gapic.protoparser; -import static junit.framework.Assert.assertEquals; -import static junit.framework.Assert.assertTrue; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; import com.google.api.generator.gapic.model.GapicLanguageSettings; import java.nio.file.Path; diff --git a/src/test/java/com/google/api/generator/gapic/protoparser/GapicLroRetrySettingsParserTest.java b/src/test/java/com/google/api/generator/gapic/protoparser/GapicLroRetrySettingsParserTest.java index 262b266f53..664b7d2e69 100644 --- a/src/test/java/com/google/api/generator/gapic/protoparser/GapicLroRetrySettingsParserTest.java +++ b/src/test/java/com/google/api/generator/gapic/protoparser/GapicLroRetrySettingsParserTest.java @@ -14,8 +14,8 @@ package com.google.api.generator.gapic.protoparser; -import static junit.framework.Assert.assertEquals; -import static junit.framework.Assert.assertFalse; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; import com.google.api.generator.gapic.model.GapicLroRetrySettings; import java.nio.file.Path; 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 468e1e392f..31fc531555 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 @@ -15,9 +15,9 @@ package com.google.api.generator.gapic.protoparser; import static com.google.common.truth.Truth.assertThat; -import static junit.framework.Assert.assertEquals; -import static junit.framework.Assert.assertTrue; +import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertThrows; +import static org.junit.Assert.assertTrue; import com.google.api.generator.gapic.model.HttpBindings; import com.google.api.generator.gapic.model.HttpBindings.HttpBinding; diff --git a/src/test/java/com/google/api/generator/gapic/protoparser/MethodSignatureParserTest.java b/src/test/java/com/google/api/generator/gapic/protoparser/MethodSignatureParserTest.java index 4f141f6125..68a2bbc66b 100644 --- a/src/test/java/com/google/api/generator/gapic/protoparser/MethodSignatureParserTest.java +++ b/src/test/java/com/google/api/generator/gapic/protoparser/MethodSignatureParserTest.java @@ -14,16 +14,13 @@ package com.google.api.generator.gapic.protoparser; -import static junit.framework.Assert.assertEquals; -import static junit.framework.Assert.assertTrue; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; import com.google.api.generator.engine.ast.TypeNode; import com.google.api.generator.engine.ast.VaporReference; import com.google.api.generator.gapic.model.Field; import com.google.api.generator.gapic.model.MethodArgument; -import com.google.protobuf.Descriptors.FileDescriptor; -import com.google.protobuf.Descriptors.ServiceDescriptor; -import com.google.testgapic.v1beta1.LockerProto; import java.util.Arrays; import java.util.HashMap; import java.util.List; @@ -31,20 +28,9 @@ import java.util.function.BiFunction; import java.util.function.Function; import java.util.stream.Collectors; -import org.junit.Before; import org.junit.Test; public class MethodSignatureParserTest { - private static final String MAIN_PACKAGE = "com.google.testgapic.v1beta1"; - - private ServiceDescriptor lockerService; - private FileDescriptor lockerServiceFileDescriptor; - - @Before - public void setUp() { - lockerServiceFileDescriptor = LockerProto.getDescriptor(); - lockerService = lockerServiceFileDescriptor.getServices().get(0); - } @Test public void flattenMethodSignatures_basic() { diff --git a/src/test/java/com/google/api/generator/gapic/protoparser/ParserTest.java b/src/test/java/com/google/api/generator/gapic/protoparser/ParserTest.java index c9e6dbd3e2..428b5156d9 100644 --- a/src/test/java/com/google/api/generator/gapic/protoparser/ParserTest.java +++ b/src/test/java/com/google/api/generator/gapic/protoparser/ParserTest.java @@ -15,10 +15,10 @@ package com.google.api.generator.gapic.protoparser; 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.assertEquals; +import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertThrows; +import static org.junit.Assert.assertTrue; import com.google.api.generator.engine.ast.ConcreteReference; import com.google.api.generator.engine.ast.Reference; @@ -224,15 +224,6 @@ public void parseMethodSignatures_empty() { Map resourceNames = Parser.parseResourceNames(echoFileDescriptor); Set outputResourceNames = new HashSet<>(); - List methods = - Parser.parseMethods( - echoService, - ECHO_PACKAGE, - messageTypes, - resourceNames, - Optional.empty(), - outputResourceNames, - Transport.GRPC); assertThat( MethodSignatureParser.parseMethodSignatures( methodDescriptor, @@ -254,15 +245,6 @@ public void parseMethodSignatures_validArgstAndEmptyString() { Map resourceNames = Parser.parseResourceNames(echoFileDescriptor); Set outputResourceNames = new HashSet<>(); - List methods = - Parser.parseMethods( - echoService, - ECHO_PACKAGE, - messageTypes, - resourceNames, - Optional.empty(), - outputResourceNames, - Transport.GRPC); List> methodArgs = MethodSignatureParser.parseMethodSignatures( methodDescriptor, diff --git a/src/test/java/com/google/api/generator/gapic/protoparser/PluginArgumentParserTest.java b/src/test/java/com/google/api/generator/gapic/protoparser/PluginArgumentParserTest.java index f6a55f0602..2dcaa298cf 100644 --- a/src/test/java/com/google/api/generator/gapic/protoparser/PluginArgumentParserTest.java +++ b/src/test/java/com/google/api/generator/gapic/protoparser/PluginArgumentParserTest.java @@ -14,9 +14,9 @@ package com.google.api.generator.gapic.protoparser; -import static junit.framework.Assert.assertEquals; -import static junit.framework.Assert.assertFalse; -import static junit.framework.Assert.assertTrue; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; import java.util.Arrays; import org.junit.Test; diff --git a/src/test/java/com/google/api/generator/gapic/protoparser/ResourceNameParserTest.java b/src/test/java/com/google/api/generator/gapic/protoparser/ResourceNameParserTest.java index 36395ec10b..04b6622b5a 100644 --- a/src/test/java/com/google/api/generator/gapic/protoparser/ResourceNameParserTest.java +++ b/src/test/java/com/google/api/generator/gapic/protoparser/ResourceNameParserTest.java @@ -15,10 +15,10 @@ package com.google.api.generator.gapic.protoparser; 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.assertEquals; +import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertThrows; +import static org.junit.Assert.assertTrue; import com.google.api.generator.engine.ast.ConcreteReference; import com.google.api.generator.engine.ast.TypeNode; @@ -26,7 +26,6 @@ import com.google.api.generator.gapic.utils.ResourceNameConstants; import com.google.protobuf.Descriptors.Descriptor; import com.google.protobuf.Descriptors.FileDescriptor; -import com.google.protobuf.Descriptors.ServiceDescriptor; import com.google.testgapic.v1beta1.BadMessageResnameDefProto; import com.google.testgapic.v1beta1.LockerProto; import java.util.List; @@ -38,13 +37,11 @@ public class ResourceNameParserTest { private static final String MAIN_PACKAGE = "com.google.testgapic.v1beta1"; - private ServiceDescriptor lockerService; private FileDescriptor lockerServiceFileDescriptor; @Before public void setUp() { lockerServiceFileDescriptor = LockerProto.getDescriptor(); - lockerService = lockerServiceFileDescriptor.getServices().get(0); } @Test diff --git a/src/test/java/com/google/api/generator/gapic/protoparser/ResourceReferenceParserTest.java b/src/test/java/com/google/api/generator/gapic/protoparser/ResourceReferenceParserTest.java index 346431d2c5..5056192c1c 100644 --- a/src/test/java/com/google/api/generator/gapic/protoparser/ResourceReferenceParserTest.java +++ b/src/test/java/com/google/api/generator/gapic/protoparser/ResourceReferenceParserTest.java @@ -14,16 +14,15 @@ package com.google.api.generator.gapic.protoparser; -import static junit.framework.Assert.assertEquals; -import static junit.framework.Assert.assertFalse; -import static junit.framework.Assert.assertTrue; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; import com.google.api.generator.engine.ast.TypeNode; import com.google.api.generator.engine.ast.VaporReference; import com.google.api.generator.gapic.model.ResourceName; import com.google.api.generator.gapic.utils.ResourceNameConstants; import com.google.protobuf.Descriptors.FileDescriptor; -import com.google.protobuf.Descriptors.ServiceDescriptor; import com.google.testgapic.v1beta1.LockerProto; import java.util.Arrays; import java.util.HashMap; @@ -35,13 +34,11 @@ public class ResourceReferenceParserTest { private static final String MAIN_PACKAGE = "com.google.testgapic.v1beta1"; - private ServiceDescriptor lockerService; private FileDescriptor lockerServiceFileDescriptor; @Before public void setUp() { lockerServiceFileDescriptor = LockerProto.getDescriptor(); - lockerService = lockerServiceFileDescriptor.getServices().get(0); } @Test @@ -173,7 +170,6 @@ public void resolvePackages_resourcePackageIsSubpackageOfService() { @Test public void resolvePackages_resourcePackageIsSameAsService() { - String resourcePackage = "com.google.testgapic.v1beta1.common"; assertEquals(MAIN_PACKAGE, ResourceReferenceParser.resolvePackages(MAIN_PACKAGE, MAIN_PACKAGE)); } diff --git a/src/test/java/com/google/api/generator/gapic/protoparser/ServiceConfigParserTest.java b/src/test/java/com/google/api/generator/gapic/protoparser/ServiceConfigParserTest.java index d5688d545d..eb69209242 100644 --- a/src/test/java/com/google/api/generator/gapic/protoparser/ServiceConfigParserTest.java +++ b/src/test/java/com/google/api/generator/gapic/protoparser/ServiceConfigParserTest.java @@ -14,9 +14,9 @@ package com.google.api.generator.gapic.protoparser; -import static junit.framework.Assert.assertEquals; -import static junit.framework.Assert.assertFalse; -import static junit.framework.Assert.assertTrue; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; import com.google.protobuf.util.Durations; import com.google.rpc.Code; diff --git a/src/test/java/com/google/api/generator/gapic/protoparser/ServiceYamlParserTest.java b/src/test/java/com/google/api/generator/gapic/protoparser/ServiceYamlParserTest.java index 615aacc9b0..de432646fa 100644 --- a/src/test/java/com/google/api/generator/gapic/protoparser/ServiceYamlParserTest.java +++ b/src/test/java/com/google/api/generator/gapic/protoparser/ServiceYamlParserTest.java @@ -14,8 +14,8 @@ package com.google.api.generator.gapic.protoparser; -import static junit.framework.Assert.assertEquals; -import static junit.framework.Assert.assertTrue; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; import java.nio.file.Path; import java.nio.file.Paths; diff --git a/src/test/java/com/google/api/generator/gapic/protoparser/SourceCodeInfoParserTest.java b/src/test/java/com/google/api/generator/gapic/protoparser/SourceCodeInfoParserTest.java index a33f20c782..4be6c37fe4 100644 --- a/src/test/java/com/google/api/generator/gapic/protoparser/SourceCodeInfoParserTest.java +++ b/src/test/java/com/google/api/generator/gapic/protoparser/SourceCodeInfoParserTest.java @@ -15,7 +15,7 @@ package com.google.api.generator.gapic.protoparser; import static com.google.common.truth.Truth.assertThat; -import static junit.framework.Assert.assertEquals; +import static org.junit.Assert.assertEquals; import com.google.api.generator.gapic.model.SourceCodeInfoLocation; import com.google.protobuf.DescriptorProtos.FileDescriptorProto; diff --git a/src/test/java/com/google/api/generator/gapic/protoparser/TypeParserTest.java b/src/test/java/com/google/api/generator/gapic/protoparser/TypeParserTest.java index 096302e2c1..a79460e915 100644 --- a/src/test/java/com/google/api/generator/gapic/protoparser/TypeParserTest.java +++ b/src/test/java/com/google/api/generator/gapic/protoparser/TypeParserTest.java @@ -14,7 +14,7 @@ package com.google.api.generator.gapic.protoparser; -import static junit.framework.Assert.assertEquals; +import static org.junit.Assert.assertEquals; import com.google.api.generator.engine.ast.Reference; import com.google.protobuf.Descriptors.Descriptor; @@ -26,7 +26,6 @@ import org.junit.Test; public class TypeParserTest { - private static final String ECHO_PACKAGE = "com.google.showcase.v1beta1"; // TODO(miraleung): Backfill with more tests (e.g. field, message, methods) for Parser.java. @Test public void parseMessageType_basic() { diff --git a/src/test/java/com/google/api/generator/gapic/utils/JavaStyleTest.java b/src/test/java/com/google/api/generator/gapic/utils/JavaStyleTest.java index 10b65c9b9c..3cf7d647cc 100644 --- a/src/test/java/com/google/api/generator/gapic/utils/JavaStyleTest.java +++ b/src/test/java/com/google/api/generator/gapic/utils/JavaStyleTest.java @@ -15,7 +15,7 @@ package com.google.api.generator.gapic.utils; import static com.google.common.truth.Truth.assertThat; -import static junit.framework.Assert.assertEquals; +import static org.junit.Assert.assertEquals; import org.junit.Test; diff --git a/src/test/java/com/google/api/generator/test/framework/SingleJUnitTestRunner.java b/src/test/java/com/google/api/generator/test/framework/SingleJUnitTestRunner.java index a11ad6437a..eda4ae7f8c 100644 --- a/src/test/java/com/google/api/generator/test/framework/SingleJUnitTestRunner.java +++ b/src/test/java/com/google/api/generator/test/framework/SingleJUnitTestRunner.java @@ -28,7 +28,7 @@ public static void main(String... args) { throw new MissingRequiredArgException("Missing the JUnit class name argument."); } String className = args[0]; - Class clazz = null; + Class clazz = null; try { clazz = Class.forName(className); } catch (ClassNotFoundException e) { diff --git a/src/test/java/com/google/api/generator/test/framework/Utils.java b/src/test/java/com/google/api/generator/test/framework/Utils.java index 728be5f5b5..d38142a582 100644 --- a/src/test/java/com/google/api/generator/test/framework/Utils.java +++ b/src/test/java/com/google/api/generator/test/framework/Utils.java @@ -33,7 +33,7 @@ public class Utils { * @param fileName the name of saved file, usually it is test method name with suffix `.golden`. * @param codegen the generated code from JUnit test. */ - public static void saveCodegenToFile(Class clazz, String fileName, String codegen) { + public static void saveCodegenToFile(Class clazz, String fileName, String codegen) { // This system environment variable `TEST_OUTPUT_HOME` is used to specify a folder // which contains generated output from JUnit test. // It will be set when running `bazel run testTarget_update` command. @@ -51,15 +51,15 @@ public static void saveCodegenToFile(Class clazz, String fileName, String codege } } - private static String getTestoutGoldenDir(Class clazz) { + private static String getTestoutGoldenDir(Class clazz) { return clazz.getPackage().getName().replace(".", "/") + "/goldens/"; } - public static String getGoldenDir(Class clazz) { + public static String getGoldenDir(Class clazz) { return "src/test/java/" + clazz.getPackage().getName().replace(".", "/") + "/goldens/"; } - public static String getClassName(Class clazz) { + public static String getClassName(Class clazz) { return clazz.getSimpleName(); } diff --git a/src/test/java/com/google/api/generator/util/TrieTest.java b/src/test/java/com/google/api/generator/util/TrieTest.java index 8854ff7a2f..8769e522cb 100644 --- a/src/test/java/com/google/api/generator/util/TrieTest.java +++ b/src/test/java/com/google/api/generator/util/TrieTest.java @@ -14,9 +14,9 @@ package com.google.api.generator.util; -import static junit.framework.Assert.assertEquals; -import static junit.framework.Assert.assertFalse; -import static junit.framework.Assert.assertTrue; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; import com.google.api.generator.testutils.LineFormatter; import java.util.Arrays; @@ -69,7 +69,6 @@ public void insertAndSearch_multiStringTrie() { @Test public void dfsTraverseAndReduce_emptyTrie() { // Add up points in the tree, where each parent gets (num child node points) * 2 + 1. - int baseValue = 0; Function parentPreprocFn = nodeVal -> new Integer(0); BiFunction leafReduceFn = (nodeVal, accVal) -> new Integer(accVal + 1); @@ -84,7 +83,6 @@ public void dfsTraverseAndReduce_emptyTrie() { @Test public void dfsTraverseAndReduce_singleNodeTrie() { // Add up points in the tree, where each parent gets (num child node points) * 2 + 1. - int baseValue = 0; Function parentPreprocFn = nodeVal -> new Integer(0); BiFunction leafReduceFn = (nodeVal, accVal) -> new Integer(accVal + 1); From c30a7f9ff23fe519f28b850cbb038ab30e4cbad9 Mon Sep 17 00:00:00 2001 From: Vadym Matsishevskyi <25311427+vam-google@users.noreply.github.com> Date: Tue, 5 Oct 2021 19:29:15 -0700 Subject: [PATCH 9/9] Diregapic lro (#856) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * feat: enable self signed jwt for gapic clients (#794) * feat: enable self signed jwt for gapic clients * resolve comments * update gax version * update goldens * update golden files * chore: release 2.1.0 (#827) Co-authored-by: release-please[bot] <55107282+release-please[bot]@users.noreply.github.com> * feat: REGAPIC initial implementation (#824) This includes: 1) Proper GRPC transcoding 2) Mimimal REST Operations (go make it compilable) 3) Rely on resource names for tests values generation (to not fail http url path validation) 4) Empty Server Streaming method implementation * feat: REGAPIC Multitransport implementation (grpc+rest) (#833) 1) Fully backward compatible with grpc-only GAPIC 2) Strictly speaking not fully backward compatible with rest-only REGAPIC (but is compatible for practical cases). See below for details. 3) Introduces the concept of default transport (is necessary to preserve backward-compabitility). The default behavior assumes grpc transport. Needed to unblock DIREGAPIC LRO. To be reviewed after submission * fix: [bazel] fix rest transport handling in assembly rule (#835) * Portable String <--> bytes conversion (#841) * Fix development doc (#837) * Fix dev doc * Clarify BUILD.bazel location * Remove warnings (unused vars, dead code, missing annotations, missing generic reference, etc) (#840) * Remove warnings for test code (#842) * Remove extraneous call (#844) * Fix preserving sorted order of a collection (#845) * feat: Add REST AIP-151 LRO suport Depends on https://github.com/googleapis/gax-java/pull/1484 * chore(deps): update dependency gradle to v7 (#713) [![WhiteSource Renovate](https://app.renovatebot.com/images/banner.svg)](https://renovatebot.com) This PR contains the following updates: | Package | Update | Change | |---|---|---| | [gradle](https://gradle.org) ([source](https://togithub.com/gradle/gradle)) | major | `4.10.3` -> `7.0.2` | --- ### Release Notes
    gradle/gradle ### [`v7.0.2`](https://togithub.com/gradle/gradle/releases/v7.0.2) This is a patch release for Gradle 7.0. [This fixes an issue with files system watching on certain Linux distributions](https://togithub.com/gradle/gradle/milestone/177?closed=1). We recommend users upgrade to 7.0.2 instead of 7.0. #### Upgrade Instructions Switch your build to use Gradle 7.0.2 by updating your wrapper: ./gradlew wrapper --gradle-version=7.0.2 See the [Gradle 6.x upgrade guide](https://docs.gradle.org/7.0.1/userguide/upgrading_version\_6.html#changes\_7.0) to learn about deprecations, breaking changes and other considerations when upgrading to Gradle 7.0.1. #### Reporting Problems If you find a problem with this release, please file a bug on [GitHub Issues](https://togithub.com/gradle/gradle/issues) adhering to our issue guidelines. If you're not sure you're encountering a bug, please use the [forum](https://discuss.gradle.org/c/help-discuss). ### [`v7.0.1`](https://togithub.com/gradle/gradle/releases/v7.0.1) This is a patch release for Gradle 7.0. [This fixes several issues reported against 7.0](https://togithub.com/gradle/gradle/milestone/173?closed=1). We recommend users upgrade to 7.0.1 instead of 7.0. #### Upgrade Instructions Switch your build to use Gradle 7.0.1 by updating your wrapper: ./gradlew wrapper --gradle-version=7.0.1 See the [Gradle 6.x upgrade guide](https://docs.gradle.org/7.0.1/userguide/upgrading_version\_6.html#changes\_7.0) to learn about deprecations, breaking changes and other considerations when upgrading to Gradle 7.0.1. #### Reporting Problems If you find a problem with this release, please file a bug on [GitHub Issues](https://togithub.com/gradle/gradle/issues) adhering to our issue guidelines. If you're not sure you're encountering a bug, please use the [forum](https://discuss.gradle.org/c/help-discuss). ### [`v7.0`](https://togithub.com/gradle/gradle/compare/v6.9.0...v7.0.0) ### [`v6.9`](https://togithub.com/gradle/gradle/compare/v6.8.3...v6.9.0) ### [`v6.8.3`](https://togithub.com/gradle/gradle/releases/v6.8.3) This is a patch release for Gradle 6.8. This fixes [a critical bug](https://togithub.com/gradle/gradle/issues/16144) present in Gradle 6.8, 6.8.1 and 6.8.2. [All issues fixed in this patch release](https://togithub.com/gradle/gradle/milestone/171?closed=1) Please don’t use the original 6.8 release or previous patch releases, and instead upgrade to 6.8.3. ##### Upgrade Instructions Switch your build to use Gradle 6.8.3 by updating your wrapper: ./gradlew wrapper --gradle-version=6.8.3 --gradle-distribution-sha256-sum 7faa7198769f872826c8ef4f1450f839ec27f0b4d5d1e51bade63667cbccd205 See the [Gradle 6.x upgrade guide](https://docs.gradle.org/6.8.3/userguide/upgrading_version\_6.html#changes\_6.8) to learn about deprecations, breaking changes and other considerations when upgrading to Gradle 6.8.3. ##### Reporting Problems If you find a problem with this release, please file a bug on [GitHub Issues](https://togithub.com/gradle/gradle/issues) adhering to our issue guidelines. If you're not sure you're encountering a bug, please use the [forum](https://discuss.gradle.org/c/help-discuss). ### [`v6.8.2`](https://togithub.com/gradle/gradle/releases/v6.8.2) This is a patch release for Gradle 6.8. This fixes several bugs in Gradle 6.8.1. [All issues fixed in this patch release](https://togithub.com/gradle/gradle/milestone/170?closed=1) Please don’t use the original 6.8 release or the 6.8.1, and instead upgrade to 6.8.2. ##### Upgrade Instructions Switch your build to use Gradle 6.8.2 by updating your wrapper: `./gradlew wrapper --gradle-version=6.8.2` See the [Gradle 6.x upgrade guide](https://docs.gradle.org/6.8.2/userguide/upgrading_version\_6.html#changes\_6.8) to learn about deprecations, breaking changes and other considerations when upgrading to Gradle 6.8.2. ##### Reporting Problems If you find a problem with this release, please file a bug on [GitHub Issues](https://togithub.com/gradle/gradle/issues) adhering to our issue guidelines. If you're not sure you're encountering a bug, please use the [forum](https://discuss.gradle.org/c/help-discuss). ### [`v6.8.1`](https://togithub.com/gradle/gradle/releases/v6.8.1) This is a patch release for Gradle 6.8. This fixes several critical bugs in Gradle 6.8. [All issues fixed in this patch release](https://togithub.com/gradle/gradle/milestone/168?closed=1) We recommend that you use Gradle 6.8.1 over the initial release of Gradle 6.8. #### Upgrade Instructions Switch your build to use Gradle 6.8.1 by updating your wrapper: `./gradlew wrapper --gradle-version=6.8.1` See the [Gradle 6.x upgrade guide](https://docs.gradle.org/6.8.1/userguide/upgrading_version\_6.html#changes\_6.8) to learn about deprecations, breaking changes and other considerations when upgrading to Gradle 6.8.1. #### Reporting Problems If you find a problem with this release, please file a bug on [GitHub Issues](https://togithub.com/gradle/gradle/issues) adhering to our issue guidelines. If you're not sure you're encountering a bug, please use the [forum](https://discuss.gradle.org/c/help-discuss). ### [`v6.8`](https://togithub.com/gradle/gradle/compare/v6.7.1...v6.8.0) ### [`v6.7.1`](https://togithub.com/gradle/gradle/releases/v6.7.1) This is a patch release for Gradle 6.7. This fixes several critical bugs in Gradle 6.7. [All issues fixed in this patch release](https://togithub.com/gradle/gradle/milestone/160?closed=1) We recommend that you use Gradle 6.7.1 over the initial release of Gradle 6.7. #### Upgrade Instructions Switch your build to use Gradle 6.7.1 by updating your wrapper: `./gradlew wrapper --gradle-version=6.7.1` See the [Gradle 6.x upgrade guide](https://docs.gradle.org/6.7.1/userguide/upgrading_version\_6.html#changes\_6.7) to learn about deprecations, breaking changes and other considerations when upgrading to Gradle 6.7.1. #### Reporting Problems If you find a problem with this release, please file a bug on [GitHub Issues](https://togithub.com/gradle/gradle/issues) adhering to our issue guidelines. If you're not sure you're encountering a bug, please use the [forum](https://discuss.gradle.org/c/help-discuss). ### [`v6.7`](https://togithub.com/gradle/gradle/compare/v6.6.1...v6.7.0) ### [`v6.6.1`](https://togithub.com/gradle/gradle/releases/v6.6.1) This is a patch release for Gradle 6.6. This fixes several critical bugs in Gradle 6.6. [All issues fixed in this patch release](https://togithub.com/gradle/gradle/milestone/155?closed=1) We recommend that you use Gradle 6.6.1 over the initial release of Gradle 6.6. #### Upgrade Instructions Switch your build to use Gradle 6.6.1 by updating your wrapper: `./gradlew wrapper --gradle-version=6.6.1` See the [Gradle 6.x upgrade guide](https://docs.gradle.org/6.6.1/userguide/upgrading_version\_6.html#changes\_6.6) to learn about deprecations, breaking changes and other considerations when upgrading to Gradle 6.6.1. #### Reporting Problems If you find a problem with this release, please file a bug on [GitHub Issues](https://togithub.com/gradle/gradle/issues) adhering to our issue guidelines. If you're not sure you're encountering a bug, please use the [forum](https://discuss.gradle.org/c/help-discuss). ### [`v6.6`](https://togithub.com/gradle/gradle/compare/v6.5.1...v6.6.0) ### [`v6.5.1`](https://togithub.com/gradle/gradle/releases/v6.5.1) This is a patch release for Gradle 6.5. This fixes several critical bugs in Gradle 6.5: - Regression: Gradle 6.5 cached builds cause IllegalStateException [#​13367](https://togithub.com/gradle/gradle/issues/13367) - Regression: Compile classpath configuration is not deterministic [#​13555](https://togithub.com/gradle/gradle/issues/13555) - Regression: Class cast exception when GStrings are used with System.getProperty [#​13569](https://togithub.com/gradle/gradle/issues/13569) - And a number of dependency graph resolution errors ([#​13251](https://togithub.com/gradle/gradle/issues/13251), [#​13316](https://togithub.com/gradle/gradle/issues/13316), [#​13329](https://togithub.com/gradle/gradle/issues/13329), [#​13551](https://togithub.com/gradle/gradle/issues/13551)) [All issues fixed in this patch release](https://togithub.com/gradle/gradle/milestone/147?closed=1) We recommend that you use Gradle 6.5.1 over the initial release of Gradle 6.5. #### Upgrade Instructions Switch your build to use Gradle 6.5.1 by updating your wrapper: `./gradlew wrapper --gradle-version=6.5.1` See the [Gradle 6.x upgrade guide](https://docs.gradle.org/6.5.1/userguide/upgrading_version\_6.html#changes\_6.5) to learn about deprecations, breaking changes and other considerations when upgrading to Gradle 6.5.1. #### Reporting Problems If you find a problem with this release, please file a bug on [GitHub Issues](https://togithub.com/gradle/gradle/issues) adhering to our issue guidelines. If you're not sure you're encountering a bug, please use the [forum](https://discuss.gradle.org/c/help-discuss). ### [`v6.5`](https://togithub.com/gradle/gradle/compare/v6.4.1...v6.5.0) ### [`v6.4.1`](https://togithub.com/gradle/gradle/releases/v6.4.1) This is a patch release for Gradle 6.4. This fixes several critical bugs in Gradle 6.4: - Regression: Different daemons are used between IDE and CLI builds for the same project [#​13069](https://togithub.com/gradle/gradle/issues/13069) - Regression: Main-Class attribute always added to jar manifest when using application plugin [#​13057](https://togithub.com/gradle/gradle/issues/13057) [All issues fixed in this patch release](https://togithub.com/gradle/gradle/milestone/145?closed=1) We recommend that you use Gradle 6.4.1 over the initial release of Gradle 6.4. #### Upgrade Instructions Switch your build to use Gradle 6.4.1 by updating your wrapper: `./gradlew wrapper --gradle-version=6.4.1` See the [Gradle 6.x upgrade guide](https://docs.gradle.org/6.4.1/userguide/upgrading_version\_6.html#changes\_6.4) to learn about deprecations, breaking changes and other considerations when upgrading to Gradle 6.4.1. #### Reporting Problems If you find a problem with this release, please file a bug on [GitHub Issues](https://togithub.com/gradle/gradle/issues) adhering to our issue guidelines. If you're not sure you're encountering a bug, please use the [forum](https://discuss.gradle.org/c/help-discuss). ### [`v6.4`](https://togithub.com/gradle/gradle/compare/v6.3.0...v6.4.0) ### [`v6.3`](https://togithub.com/gradle/gradle/compare/v6.2.2...v6.3.0) ### [`v6.2.2`](https://togithub.com/gradle/gradle/releases/v6.2.2) This is a patch release for Gradle 6.2. This fixes a critical bug in Gradle 6.2: - Multi-project build use the properties of the rootProject for all included builds. [#​12381](https://togithub.com/gradle/gradle/issues/12381) [All issues fixed](https://togithub.com/gradle/gradle/milestone/134?closed=1) We recommend that you use Gradle 6.2.2 over the initial release of Gradle 6.2. [Read the full release notes](https://docs.gradle.org/6.2.2/release-notes.html) #### Upgrade Instructions Switch your build to use Gradle 6.2.2 by updating your wrapper: `./gradlew wrapper --gradle-version=6.2.2` See the [Gradle 6.x upgrade guide](https://docs.gradle.org/6.2.2/userguide/upgrading_version\_6.html#changes\_6.2) to learn about deprecations, breaking changes and other considerations when upgrading to Gradle 6.2.2. #### Reporting Problems If you find a problem with this release, please file a bug on [GitHub Issues](https://togithub.com/gradle/gradle/issues) adhering to our issue guidelines. If you're not sure you're encountering a bug, please use the [forum](https://discuss.gradle.org/c/help-discuss). ### [`v6.2.1`](https://togithub.com/gradle/gradle/releases/v6.2.1) This is a patch release for Gradle 6.2. This fixes several critical bugs in Gradle 6.2: - Project name disambiguation causes project / external dependency conflicts to be missed. [#​12315](https://togithub.com/gradle/gradle/issues/12315) - IdeaModelBuilder does not provide groovy-all as compile dep for buildSrc [#​12274](https://togithub.com/gradle/gradle/issues/12274) - Gradle crashes if GRADLE_RO_DEP_CACHE is set and it cannot create modules-2 directory within it [#​12293](https://togithub.com/gradle/gradle/issues/12293) [All issues fixed](https://togithub.com/gradle/gradle/milestone/133?closed=1) We recommend that you use Gradle 6.2.1 over the initial release of Gradle 6.2. [Read the full release notes](https://docs.gradle.org/6.2.1/release-notes.html) #### Upgrade Instructions Switch your build to use Gradle 6.2.1 by updating your wrapper: `./gradlew wrapper --gradle-version=6.2.1` See the [Gradle 6.x upgrade guide](https://docs.gradle.org/6.2.1/userguide/upgrading_version\_6.html#changes\_6.2) to learn about deprecations, breaking changes and other considerations when upgrading to Gradle 6.2.1. #### Reporting Problems If you find a problem with this release, please file a bug on [GitHub Issues](https://togithub.com/gradle/gradle/issues) adhering to our issue guidelines. If you're not sure you're encountering a bug, please use the [forum](https://discuss.gradle.org/c/help-discuss). ### [`v6.2`](https://togithub.com/gradle/gradle/compare/v6.1.1...v6.2.0) ### [`v6.1.1`](https://togithub.com/gradle/gradle/releases/v6.1.1) This is a patch release for Gradle 6.1. This fixes several critical bugs in Gradle 6.1: - Plugins using kotlin-dsl and compiled with 6.1 are incompatible with Gradle 6.0 [#​11947](https://togithub.com/gradle/gradle/issues/11947) - Missing fixed issues from Gradle 6.1 release notes [#​11954](https://togithub.com/gradle/gradle/issues/11954) - Memory regression when resolving large artifacts while computing checksums [#​11966](https://togithub.com/gradle/gradle/issues/11966) - Gradle 6.1 generates an empty .gradle and gradle directories on each execution in subproject directories [#​11971](https://togithub.com/gradle/gradle/issues/11971) [All issues fixed](https://togithub.com/gradle/gradle/issues?q=is%3Aclosed+milestone%3A6.1.1) We recommend that you use Gradle 6.1.1 over the initial release of Gradle 6.1. [Read the full release notes](https://docs.gradle.org/6.1.1/release-notes.html) #### Upgrade Instructions Switch your build to use Gradle 6.1.1 by updating your wrapper: `./gradlew wrapper --gradle-version=6.1.1` See the [Gradle 6.x upgrade guide](https://docs.gradle.org/6.1.1/userguide/upgrading_version\_6.html#changes\_6.1) to learn about deprecations, breaking changes and other considerations when upgrading to Gradle 6.1.x. #### Reporting Problems If you find a problem with this release, please file a bug on [GitHub Issues](https://togithub.com/gradle/gradle/issues) adhering to our issue guidelines. If you're not sure you're encountering a bug, please use the [forum](https://discuss.gradle.org/c/help-discuss). ### [`v6.1`](https://togithub.com/gradle/gradle/compare/v6.0.1...v6.1.0) ### [`v6.0.1`](https://togithub.com/gradle/gradle/releases/v6.0.1) This is a patch release for Gradle 6.0. This fixes several critical bugs in Gradle 6.0: - Incremental Java compilation is broken with Android 3.5.1 and Gradle 6.0 [#​11330](https://togithub.com/gradle/gradle/issues/11330) - Unable to use a Provider as an artifact for the maven-publish plugin [#​11054](https://togithub.com/gradle/gradle/issues/11054) - Implicit capabilities not always applied/detected [#​11300](https://togithub.com/gradle/gradle/issues/11300) - maven-metadata.xml SHA256 and SHA512 checksums prevent publishing to Nexus [#​11308](https://togithub.com/gradle/gradle/issues/11308) - Unable to properly resolve dynamic dependencies from mavenLocal() repo [#​11321](https://togithub.com/gradle/gradle/issues/11321) - Kotlin DSL: `fileTree(mapOf(...))` has unexpected behavior [#​11335](https://togithub.com/gradle/gradle/issues/11335) - Attribute disambiguation rule for 'org.gradle.category' can cause unexpected type exception [#​11365](https://togithub.com/gradle/gradle/issues/11365) [All issues fixed](https://togithub.com/gradle/gradle/issues?q=is%3Aclosed+milestone%3A6.0.1) We recommend that you use Gradle 6.0.1 over the initial release of Gradle 6.0. #### Upgrade Instructions Switch your build to use Gradle 6.0.1 by updating your wrapper properties: `./gradlew wrapper --gradle-version=6.0.1` Standalone downloads are available at https://gradle.org/install. #### Reporting Problems If you find a problem with Gradle, please file a bug on [GitHub Issues](https://togithub.com/gradle/gradle/issues) adhering to our issue guidelines. If you're not sure you're encountering a bug, please use the [forum](https://discuss.gradle.org/c/help-discuss). ### [`v5.6.4`](https://togithub.com/gradle/gradle/releases/v5.6.4) This bug-fix release contains all changes from 5.6.1 through 5.6.3 as well as: - Can't configure kotlinOptions after upgrade to gradle 5.6.3 using kotlin-dsl [#​11083](https://togithub.com/gradle/gradle/issues/11083) - Slow localhost look-up on macOS [#​11134](https://togithub.com/gradle/gradle/issues/11134) We recommend that you use Gradle 5.6.4 over any other 5.6.x release. #### Upgrade Instructions Switch your build to use Gradle 5.6.4 by updating your wrapper properties: `./gradlew wrapper --gradle-version=5.6.4` Standalone downloads are available at https://gradle.org/install. #### Reporting Problems If you find a problem with Gradle, please file a bug on [GitHub Issues](https://togithub.com/gradle/gradle/issues) adhering to our issue guidelines. If you're not sure you're encountering a bug, please use the [forum](https://discuss.gradle.org/c/help-discuss). ### [`v5.6.3`](https://togithub.com/gradle/gradle/releases/v5.6.3) This bug-fix release contains all changes from 5.6.1 and 5.6.2 as well as: - Let Kotlin DSL gracefully handle lambdas registered as extensions (5.6.3) [#​11014](https://togithub.com/gradle/gradle/issues/11014) - Gradle Module Metadata compatibility for unique snapshots [#​11050](https://togithub.com/gradle/gradle/issues/11050) - maven-publish publishes jars with wrong extension for known jar packagings like 'ejb' in 5.6 [#​10555](https://togithub.com/gradle/gradle/issues/10555) - Regression in 5.5 when using dependency constraints for non-jar dependencies without a POM [#​10948](https://togithub.com/gradle/gradle/issues/10948) - resolution failure when dependency locks and kotlin-dsl plugin are present [#​10697](https://togithub.com/gradle/gradle/issues/10697) - Non-Kotlin extensions crash the build when using Kotlin DSL + Kotlin plugins [#​10729](https://togithub.com/gradle/gradle/issues/10729) - Sporadic build failures with build-scan due to an overlapping ID assignment https://github.com/gradle/gradle/pull/10286 - Prevent StackOverflowException caused by excessive 'or' via PatternMatcher [#​10330](https://togithub.com/gradle/gradle/issues/10330) We recommend that you use Gradle 5.6.3 over any other 5.6.x release. #### Upgrade Instructions Switch your build to use Gradle 5.6.3 by updating your wrapper properties: `./gradlew wrapper --gradle-version=5.6.3` Standalone downloads are available at https://gradle.org/install. #### Reporting Problems If you find a problem with Gradle, please file a bug on [GitHub Issues](https://togithub.com/gradle/gradle/issues) adhering to our issue guidelines. If you're not sure you're encountering a bug, please use the [forum](https://discuss.gradle.org/c/help-discuss). ### [`v5.6.2`](https://togithub.com/gradle/gradle/releases/v5.6.2) This bug-fix release contains changes to Gradle 5.6.1: - Duplicate entry in generated .classpath file in Gradle >= 5.6 ([#​10393](https://togithub.com/gradle/gradle/issues/10393)) - Memory leak when using tasks that use Worker API and process isolation ([#​10411](https://togithub.com/gradle/gradle/issues/10411)) We recommend that you use Gradle 5.6.2 over 5.6.1. #### Upgrade Instructions Switch your build to use Gradle 5.6.2 by updating your wrapper properties: `./gradlew wrapper --gradle-version=5.6.2` Standalone downloads are available at https://gradle.org/install. #### Reporting Problems If you find a problem with Gradle, please file a bug on [GitHub Issues](https://togithub.com/gradle/gradle/issues) adhering to our issue guidelines. If you're not sure you're encountering a bug, please use the [forum](https://discuss.gradle.org/c/help-discuss). ### [`v5.6.1`](https://togithub.com/gradle/gradle/releases/v5.6.1) This bug-fix release contains changes to Gradle 5.6: - Unable to publish artifacts with custom classifier/extension from java project with Gradle 5.6 (https://github.com/gradle/gradle/issues/10287) - Regression in 5.6 signArchives (Duplicate key) (https://github.com/gradle/gradle/issues/10302) - Regression setting version for ArchiveTasks in 5.6 (https://github.com/gradle/gradle/issues/10311) - A failure occurred while executing org.jetbrains.kotlin.compilerRunner.GradleKotlinCompilerWork (https://github.com/gradle/gradle/issues/10317) - DirectoryFileTree breaks SourceTask since 5.6 (https://github.com/gradle/gradle/issues/10322) - Regression: Unable to pass java.util.Properties object using Worker API in Gradle 5.6 (https://github.com/gradle/gradle/issues/10323) - Unable to publish multiple publications with same coordinates (https://github.com/gradle/gradle/issues/10333) - Gradle 5.6 - Resolving resources from buildSrc or plugins (https://github.com/gradle/gradle/issues/10347) We recommend that you use Gradle 5.6.1 over 5.6. #### Upgrade Instructions Switch your build to use Gradle 5.6.1 by updating your wrapper properties: `./gradlew wrapper --gradle-version=5.6.1` Standalone downloads are available at https://gradle.org/install. #### Reporting Problems If you find a problem with Gradle, please file a bug on [GitHub Issues](https://togithub.com/gradle/gradle/issues) adhering to our issue guidelines. If you're not sure you're encountering a bug, please use the [forum](https://discuss.gradle.org/c/help-discuss). ### [`v5.5.1`](https://togithub.com/gradle/gradle/releases/v5.5.1) This bug-fix release contains three changes to Gradle 5.5: - Combination of errorprone-gradle-plugin and options.fork = true causes Java compilation to fail in Gradle 5.5 [#​9897](https://togithub.com/gradle/gradle/issues/9897) - Using dependency declaration `gradleKotlinDsl()` fails with 5.5 [#​9919](https://togithub.com/gradle/gradle/issues/9919) - Chain of transitives aligned by same platform can lead to broken resolution [#​9882](https://togithub.com/gradle/gradle/issues/9882) We recommend that you use Gradle 5.5.1 over 5.5. #### Upgrade Instructions Switch your build to use Gradle 5.5.1 by updating your wrapper properties: `./gradlew wrapper --gradle-version=5.5.1` Standalone downloads are available at https://gradle.org/install. #### Reporting Problems If you find a problem with Gradle, please file a bug on [GitHub Issues](https://togithub.com/gradle/gradle/issues) adhering to our issue guidelines. If you're not sure you're encountering a bug, please use the [forum](https://discuss.gradle.org/c/help-discuss). ### [`v5.4.1`](https://togithub.com/gradle/gradle/releases/v5.4.1) This bug-fix release contains two changes to Gradle 5.4: - Fix inconsistent classpath ordering when dependencies have lots of excludes - https://github.com/gradle/gradle/issues/9197 - Kotlin DSL IDEA script editor can't find JDK classes with Gradle 5.4 if *Gradle JVM* != *Project SDK* - https://github.com/gradle/gradle/issues/9195 We recommend that you use Gradle 5.4.1 over 5.4. #### Upgrade Instructions Switch your build to use Gradle 5.4.1 by updating your wrapper properties: `./gradlew wrapper --gradle-version=5.4.1` Standalone downloads are available at https://gradle.org/install. #### Reporting Problems If you find a problem with Gradle, please file a bug on [GitHub Issues](https://togithub.com/gradle/gradle/issues) adhering to our issue guidelines. If you're not sure you're encountering a bug, please use the [forum](https://discuss.gradle.org/c/help-discuss). ### [`v5.3.1`](https://togithub.com/gradle/gradle/releases/v5.3.1) This bug-fix release contains several changes to Gradle 5.3, notably: - Unable to use `java-platform` and `maven-publish` in multi-project: https://github.com/gradle/gradle/issues/8845 - Unexpected exception when adding a plugin on `buildSrc` compile classpath: https://github.com/gradle/kotlin-dsl/issues/1363 We recommend that you use Gradle 5.3.1 over 5.3. #### Upgrade Instructions Switch your build to use Gradle 5.3.1 by updating your wrapper properties: `./gradlew wrapper --gradle-version=5.3.1` Standalone downloads are available at https://gradle.org/install. #### Reporting Problems If you find a problem with Gradle, please file a bug on [GitHub Issues](https://togithub.com/gradle/gradle/issues) adhering to our issue guidelines. If you're not sure you're encountering a bug, please use the [forum](https://discuss.gradle.org/c/help-discuss). ### [`v5.2.1`](https://togithub.com/gradle/gradle/releases/v5.2.1) This bug-fix release contains several changes to Gradle 5.2, notably: - Checkstyle issues with a single source file: https://github.com/gradle/gradle/issues/8394 - BOM support conflicts: https://github.com/gradle/gradle/issues/8420 We recommend that you use Gradle 5.2.1 over 5.2. #### Upgrade Instructions Switch your build to use Gradle 5.2.1 by updating your wrapper properties: `./gradlew wrapper --gradle-version=5.2.1` Standalone downloads are available at https://gradle.org/install. #### Reporting Problems If you find a problem with Gradle, please file a bug on [GitHub Issues](https://togithub.com/gradle/gradle/issues) adhering to our issue guidelines. If you're not sure you're encountering a bug, please use the [forum](https://discuss.gradle.org/c/help-discuss). ### [`v5.1.1`](https://togithub.com/gradle/gradle/releases/v5.1.1) This bug-fix release contains several changes to Gradle 5.1, notably: - A daemon memory leak affecting all projects https://github.com/gradle/gradle/issues/8142 - Incremental Java compilation https://github.com/gradle/gradle/issues/8194 - A fix to Gradle's generated Javadoc in 5.1 https://github.com/gradle/gradle/issues/8183 We recommend that you use Gradle 5.1.1 over 5.1. #### Upgrade Instructions Switch your build to use Gradle 5.1.1 by updating your wrapper properties: `./gradlew wrapper --gradle-version=5.1.1` Standalone downloads are available at https://gradle.org/install. #### Reporting Problems If you find a problem with Gradle, please file a bug on [GitHub Issues](https://togithub.com/gradle/gradle/issues) adhering to our issue guidelines. If you're not sure you're encountering a bug, please use the [forum](https://discuss.gradle.org/c/help-discuss).
    --- ### Configuration πŸ“… **Schedule**: At any time (no schedule defined). 🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied. ♻️ **Rebasing**: Renovate will not automatically rebase this PR, because other commits have been found. πŸ”• **Ignore**: Close this PR and you won't be reminded about this update again. --- - [ ] If you want to rebase/retry this PR, check this box. --- This PR has been generated by [WhiteSource Renovate](https://renovate.whitesourcesoftware.com). View repository job log [here](https://app.renovatebot.com/dashboard#github/googleapis/gapic-generator-java). * chore(deps): update dependency bazel_skylib to v1.0.3 (#722) [![WhiteSource Renovate](https://app.renovatebot.com/images/banner.svg)](https://renovatebot.com) This PR contains the following updates: | Package | Type | Update | Change | |---|---|---|---| | [bazel_skylib](https://togithub.com/bazelbuild/bazel-skylib) | http_archive | patch | `1.0.2` -> `1.0.3` | --- ### Release Notes
    bazelbuild/bazel-skylib ### [`v1.0.3`](https://togithub.com/bazelbuild/bazel-skylib/releases/1.0.3) [Compare Source](https://togithub.com/bazelbuild/bazel-skylib/compare/1.0.2...1.0.3) **New Features** - copy_file: Add parameter to allow symlinks ([#​252](https://togithub.com/bazelbuild/bazel-skylib/issues/252)) - Create Gazelle language for Starlark ([#​251](https://togithub.com/bazelbuild/bazel-skylib/issues/251)) - Create a helper rule (`select_file`) for selecting a file from outputs of another rule ([#​233](https://togithub.com/bazelbuild/bazel-skylib/issues/233)) **Significant Changes** - Move Gazelle extension to //gazelle/bzl and change package name - Stop depending on rules_pkg through the federation. ([#​259](https://togithub.com/bazelbuild/bazel-skylib/issues/259)) **Incompatible Changes** - Remove links to maprules ([#​213](https://togithub.com/bazelbuild/bazel-skylib/issues/213)) - Remove old_sets.bzl ([#​231](https://togithub.com/bazelbuild/bazel-skylib/issues/231)) It has been deprecated for a while, the code is not really compatible with Bazel depset-related changes. **Contributors** Andrew Z Allen, Bocete, Bor Kae Hwang, irengrig, Jay Conrod, Jonathan B Coe, Marc Plano-Lesay, Robbert van Ginkel, Thomas Van Lenten, Yannic, and the Bazel team. **WORKSPACE setup** ``` load("@​bazel_tools//tools/build_defs/repo:http.bzl", "http_archive") http_archive( name = "bazel_skylib", urls = [ "https://github.com/bazelbuild/bazel-skylib/releases/download/1.0.3/bazel-skylib-1.0.3.tar.gz", "https://mirror.bazel.build/github.com/bazelbuild/bazel-skylib/releases/download/1.0.3/bazel-skylib-1.0.3.tar.gz", ], sha256 = "1c531376ac7e5a180e0237938a2536de0c54d93f5c278634818e0efc952dd56c", ) load("@​bazel_skylib//:workspace.bzl", "bazel_skylib_workspace") bazel_skylib_workspace() ``` **Using the rules** See [the source](https://togithub.com/bazelbuild/bazel-skylib/tree/1.0.3).
    --- ### Configuration πŸ“… **Schedule**: At any time (no schedule defined). 🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied. ♻️ **Rebasing**: Renovate will not automatically rebase this PR, because other commits have been found. πŸ”• **Ignore**: Close this PR and you won't be reminded about this update again. --- - [ ] If you want to rebase/retry this PR, check this box. --- This PR has been generated by [WhiteSource Renovate](https://renovate.whitesourcesoftware.com). View repository job log [here](https://app.renovatebot.com/dashboard#github/googleapis/gapic-generator-java). * chore(deps): update dependency bazel_skylib to v1.1.1 (#849) [![WhiteSource Renovate](https://app.renovatebot.com/images/banner.svg)](https://renovatebot.com) This PR contains the following updates: | Package | Type | Update | Change | |---|---|---|---| | [bazel_skylib](https://togithub.com/bazelbuild/bazel-skylib) | http_archive | minor | `1.0.3` -> `1.1.1` | --- ### Release Notes
    bazelbuild/bazel-skylib ### [`v1.1.1`](https://togithub.com/bazelbuild/bazel-skylib/releases/1.1.1) [Compare Source](https://togithub.com/bazelbuild/bazel-skylib/compare/1.0.3...1.1.1) Release 1.1.1 (initially tagged as 1.1.0) **New Features** - Gazelle: support relative imports ([#​271](https://togithub.com/bazelbuild/bazel-skylib/issues/271)) and imports from `@bazel_tools` ([#​273](https://togithub.com/bazelbuild/bazel-skylib/issues/273)) - Add partial.is_instance() ([#​276](https://togithub.com/bazelbuild/bazel-skylib/issues/276)) - Allow unittest.suite() to accept partial calls of test rules ([#​276](https://togithub.com/bazelbuild/bazel-skylib/issues/276)) - Allow specifying additional aspects to target under test in analysistest.make() ([#​299](https://togithub.com/bazelbuild/bazel-skylib/issues/299)) - Add Windows support for build_test ([#​302](https://togithub.com/bazelbuild/bazel-skylib/issues/302)) **Incompatible Changes** - structs.to_dict() ignores deprecated to_json()/to_proto() methods ([#​295](https://togithub.com/bazelbuild/bazel-skylib/issues/295)) **Contributors** aiuto, alandonovan, Alex Eagle, Alexandre Rostovtsev, Andrew Z Allen, c-parsons, Christopher Sauer, Daniel Wagner-Hall, David Sanderson, dmaclach, Laurent Le Brun, Mansur, Olek Wojnar, Philipp Wollermann, River, Samuel Giddins, Thaler Benedek **WORKSPACE setup** ``` load("@​bazel_tools//tools/build_defs/repo:http.bzl", "http_archive") http_archive( name = "bazel_skylib", urls = [ "https://github.com/bazelbuild/bazel-skylib/releases/download/1.1.1/bazel-skylib-1.1.1.tar.gz", "https://mirror.bazel.build/github.com/bazelbuild/bazel-skylib/releases/download/1.1.1/bazel-skylib-1.1.1.tar.gz", ], sha256 = "c6966ec828da198c5d9adbaa94c05e3a1c7f21bd012a0b29ba8ddbccb2c93b0d", ) load("@​bazel_skylib//:workspace.bzl", "bazel_skylib_workspace") bazel_skylib_workspace() ``` **Using the rules** See [the source](https://togithub.com/bazelbuild/bazel-skylib/tree/1.1.1).
    --- ### Configuration πŸ“… **Schedule**: At any time (no schedule defined). 🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied. β™» **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox. πŸ”• **Ignore**: Close this PR and you won't be reminded about this update again. --- - [ ] If you want to rebase/retry this PR, check this box. --- This PR has been generated by [WhiteSource Renovate](https://renovate.whitesourcesoftware.com). View repository job log [here](https://app.renovatebot.com/dashboard#github/googleapis/gapic-generator-java). * chore(deps): update dependency gradle to v7.2 (#848) [![WhiteSource Renovate](https://app.renovatebot.com/images/banner.svg)](https://renovatebot.com) This PR contains the following updates: | Package | Update | Change | |---|---|---| | [gradle](https://gradle.org) ([source](https://togithub.com/gradle/gradle)) | minor | `7.0.2` -> `7.2` | --- ### Release Notes
    gradle/gradle ### [`v7.2`](https://togithub.com/gradle/gradle/compare/v7.1.1...v7.2.0) ### [`v7.1.1`](https://togithub.com/gradle/gradle/releases/v7.1.1) This is a patch release for Gradle 7.1. It fixes the following issues: - [#​17488](https://togithub.com/gradle/gradle/issues/17488) Many Micronaut builds failing with NPE with Gradle 7.1 & JDK 8 - [#​17548](https://togithub.com/gradle/gradle/issues/17548) \[Configuration cache] Task not up-to-date for SantaTracker - [#​17542](https://togithub.com/gradle/gradle/issues/17542) \[Configuration cache] Filtered FC with mapped elements stored incorrectly We recommend users upgrade to 7.1.1 instead of 7.1. #### Upgrade Instructions Switch your build to use Gradle 7.1.1 by updating your wrapper: ./gradlew wrapper --gradle-version=7.1.1 See the [Gradle 7.x upgrade guide](https://docs.gradle.org/7.1.1/userguide/upgrading_version\_7.html#changes\_7.1) to learn about deprecations, breaking changes and other considerations when upgrading to Gradle 7.1.1. #### Reporting Problems If you find a problem with this release, please file a bug on [GitHub Issues](https://togithub.com/gradle/gradle/issues) adhering to our issue guidelines. If you're not sure you're encountering a bug, please use the [forum](https://discuss.gradle.org/c/help-discuss). ### [`v7.1`](https://togithub.com/gradle/gradle/compare/v7.0.2...v7.1.0)
    --- ### Configuration πŸ“… **Schedule**: At any time (no schedule defined). 🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied. β™» **Rebasing**: Renovate will not automatically rebase this PR, because other commits have been found. πŸ”• **Ignore**: Close this PR and you won't be reminded about this update again. --- - [ ] If you want to rebase/retry this PR, check this box. --- This PR has been generated by [WhiteSource Renovate](https://renovate.whitesourcesoftware.com). View repository job log [here](https://app.renovatebot.com/dashboard#github/googleapis/gapic-generator-java). * chore: rename default branch to main (#851) * feat: enable self signed JWT for http (#850) * chore: merge changes from master Co-authored-by: arithmetic1728 <58957152+arithmetic1728@users.noreply.github.com> Co-authored-by: release-please[bot] <55107282+release-please[bot]@users.noreply.github.com> Co-authored-by: Chanseok Oh Co-authored-by: WhiteSource Renovate Co-authored-by: Neenu Shaji --- ...tractServiceStubSettingsClassComposer.java | 10 ++++ .../ServiceStubSettingsClassComposer.java | 46 ------------------- .../goldens/ComplianceStubSettings.golden | 4 +- .../v1/stub/AddressesStubSettings.java | 4 +- .../v1/stub/RegionOperationsStubSettings.java | 4 +- 5 files changed, 19 insertions(+), 49 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 7a38adba80..7ec411185f 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 @@ -215,6 +215,16 @@ protected MethodDefinition createDefaultCredentialsProviderBuilderMethod() { .setArguments(DEFAULT_SERVICE_SCOPES_VAR_EXPR) .setReturnType(returnType) .build(); + // enable self signed JWT. + credsProviderBuilderExpr = + MethodInvocationExpr.builder() + .setExprReferenceExpr(credsProviderBuilderExpr) + .setMethodName("setUseJwtAccessWithScope") + .setArguments( + ValueExpr.withValue( + PrimitiveValue.builder().setType(TypeNode.BOOLEAN).setValue("true").build())) + .setReturnType(returnType) + .build(); return MethodDefinition.builder() .setHeaderCommentStatements( SettingsCommentComposer.DEFAULT_CREDENTIALS_PROVIDER_BUILDER_METHOD_COMMENT) 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 a897f3003d..5ace1ea0ea 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 @@ -14,21 +14,16 @@ package com.google.api.generator.gapic.composer.grpc; -import com.google.api.gax.core.GoogleCredentialsProvider; 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.generator.engine.ast.ConcreteReference; import com.google.api.generator.engine.ast.Expr; import com.google.api.generator.engine.ast.MethodDefinition; import com.google.api.generator.engine.ast.MethodInvocationExpr; -import com.google.api.generator.engine.ast.PrimitiveValue; import com.google.api.generator.engine.ast.ScopeNode; 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.comment.SettingsCommentComposer; import com.google.api.generator.gapic.composer.common.AbstractServiceStubSettingsClassComposer; import com.google.api.generator.gapic.composer.store.TypeStore; import com.google.api.generator.gapic.model.Service; @@ -74,47 +69,6 @@ protected Expr initializeTransportProviderBuilder( .build(); } - @Override - protected MethodDefinition createDefaultCredentialsProviderBuilderMethod() { - TypeNode returnType = - TypeNode.withReference( - ConcreteReference.withClazz(GoogleCredentialsProvider.Builder.class)); - MethodInvocationExpr credsProviderBuilderExpr = - MethodInvocationExpr.builder() - .setStaticReferenceType(FIXED_TYPESTORE.get("GoogleCredentialsProvider")) - .setMethodName("newBuilder") - .build(); - credsProviderBuilderExpr = - MethodInvocationExpr.builder() - .setExprReferenceExpr(credsProviderBuilderExpr) - .setMethodName("setScopesToApply") - .setArguments(DEFAULT_SERVICE_SCOPES_VAR_EXPR) - .setReturnType(returnType) - .build(); - - // This section is specific to GAPIC clients. It sets UseJwtAccessWithScope value to true to - // enable self signed JWT feature. - credsProviderBuilderExpr = - MethodInvocationExpr.builder() - .setExprReferenceExpr(credsProviderBuilderExpr) - .setMethodName("setUseJwtAccessWithScope") - .setArguments( - ValueExpr.withValue( - PrimitiveValue.builder().setType(TypeNode.BOOLEAN).setValue("true").build())) - .setReturnType(returnType) - .build(); - - return MethodDefinition.builder() - .setHeaderCommentStatements( - SettingsCommentComposer.DEFAULT_CREDENTIALS_PROVIDER_BUILDER_METHOD_COMMENT) - .setScope(ScopeNode.PUBLIC) - .setIsStatic(true) - .setReturnType(returnType) - .setName("defaultCredentialsProviderBuilder") - .setReturnExpr(credsProviderBuilderExpr) - .build(); - } - @Override protected List createApiClientHeaderProviderBuilderMethods( Service service, TypeStore typeStore) { diff --git a/src/test/java/com/google/api/generator/gapic/composer/rest/goldens/ComplianceStubSettings.golden b/src/test/java/com/google/api/generator/gapic/composer/rest/goldens/ComplianceStubSettings.golden index a858c0123e..fe74c48c98 100644 --- a/src/test/java/com/google/api/generator/gapic/composer/rest/goldens/ComplianceStubSettings.golden +++ b/src/test/java/com/google/api/generator/gapic/composer/rest/goldens/ComplianceStubSettings.golden @@ -135,7 +135,9 @@ public class ComplianceStubSettings extends StubSettings /** Returns a builder for the default credentials for this service. */ public static GoogleCredentialsProvider.Builder defaultCredentialsProviderBuilder() { - return GoogleCredentialsProvider.newBuilder().setScopesToApply(DEFAULT_SERVICE_SCOPES); + return GoogleCredentialsProvider.newBuilder() + .setScopesToApply(DEFAULT_SERVICE_SCOPES) + .setUseJwtAccessWithScope(true); } /** Returns a builder for the default ChannelProvider for this service. */ diff --git a/test/integration/goldens/compute/com/google/cloud/compute/v1/stub/AddressesStubSettings.java b/test/integration/goldens/compute/com/google/cloud/compute/v1/stub/AddressesStubSettings.java index 517743de7d..b998276981 100644 --- a/test/integration/goldens/compute/com/google/cloud/compute/v1/stub/AddressesStubSettings.java +++ b/test/integration/goldens/compute/com/google/cloud/compute/v1/stub/AddressesStubSettings.java @@ -307,7 +307,9 @@ public static List getDefaultServiceScopes() { /** Returns a builder for the default credentials for this service. */ public static GoogleCredentialsProvider.Builder defaultCredentialsProviderBuilder() { - return GoogleCredentialsProvider.newBuilder().setScopesToApply(DEFAULT_SERVICE_SCOPES); + return GoogleCredentialsProvider.newBuilder() + .setScopesToApply(DEFAULT_SERVICE_SCOPES) + .setUseJwtAccessWithScope(true); } /** Returns a builder for the default ChannelProvider for this service. */ diff --git a/test/integration/goldens/compute/com/google/cloud/compute/v1/stub/RegionOperationsStubSettings.java b/test/integration/goldens/compute/com/google/cloud/compute/v1/stub/RegionOperationsStubSettings.java index 3c57601386..365c834255 100644 --- a/test/integration/goldens/compute/com/google/cloud/compute/v1/stub/RegionOperationsStubSettings.java +++ b/test/integration/goldens/compute/com/google/cloud/compute/v1/stub/RegionOperationsStubSettings.java @@ -132,7 +132,9 @@ public static List getDefaultServiceScopes() { /** Returns a builder for the default credentials for this service. */ public static GoogleCredentialsProvider.Builder defaultCredentialsProviderBuilder() { - return GoogleCredentialsProvider.newBuilder().setScopesToApply(DEFAULT_SERVICE_SCOPES); + return GoogleCredentialsProvider.newBuilder() + .setScopesToApply(DEFAULT_SERVICE_SCOPES) + .setUseJwtAccessWithScope(true); } /** Returns a builder for the default ChannelProvider for this service. */