diff --git a/src/main/java/com/google/api/generator/gapic/composer/ServiceClientClassComposer.java b/src/main/java/com/google/api/generator/gapic/composer/ServiceClientClassComposer.java index e792c624fc..1083220cb3 100644 --- a/src/main/java/com/google/api/generator/gapic/composer/ServiceClientClassComposer.java +++ b/src/main/java/com/google/api/generator/gapic/composer/ServiceClientClassComposer.java @@ -20,6 +20,7 @@ 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.BidiStreamingCallable; @@ -40,6 +41,7 @@ import com.google.api.generator.engine.ast.MethodInvocationExpr; import com.google.api.generator.engine.ast.NewObjectExpr; import com.google.api.generator.engine.ast.NullObjectValue; +import com.google.api.generator.engine.ast.PrimitiveValue; import com.google.api.generator.engine.ast.Reference; import com.google.api.generator.engine.ast.ReferenceConstructorExpr; import com.google.api.generator.engine.ast.ScopeNode; @@ -916,6 +918,9 @@ private static List createNestedPagingClasses( createNestedRpcPagedResponseClass(method, repeatedResponseType, messageTypes, types)); nestedClasses.add( createNestedRpcPageClass(method, repeatedResponseType, messageTypes, types)); + nestedClasses.add( + createNestedRpcFixedSizeCollectionClass( + method, repeatedResponseType, messageTypes, types)); } return nestedClasses; @@ -1264,6 +1269,115 @@ private static ClassDefinition createNestedRpcPageClass( .build(); } + private static ClassDefinition createNestedRpcFixedSizeCollectionClass( + Method method, + TypeNode repeatedResponseType, + Map messageTypes, + Map types) { + String upperJavaMethodName = JavaStyle.toUpperCamelCase(method.name()); + String className = String.format("%sFixedSizeCollection", upperJavaMethodName); + TypeNode classType = types.get(className); + TypeNode methodPageType = types.get(String.format("%sPage", upperJavaMethodName)); + + TypeNode classExtendsType = + TypeNode.withReference( + ConcreteReference.builder() + .setClazz(AbstractFixedSizeCollection.class) + .setGenerics( + Arrays.asList( + method.inputType(), + method.outputType(), + repeatedResponseType, + methodPageType, + classType) + .stream() + .map(t -> t.reference()) + .collect(Collectors.toList())) + .build()); + + // Private constructor. + VariableExpr pagesVarExpr = + VariableExpr.withVariable( + Variable.builder() + .setName("pages") + .setType( + TypeNode.withReference( + ConcreteReference.builder() + .setClazz(List.class) + .setGenerics(Arrays.asList(methodPageType.reference())) + .build())) + .build()); + VariableExpr collectionSizeVarExpr = + VariableExpr.withVariable( + Variable.builder().setName("collectionSize").setType(TypeNode.INT).build()); + + MethodDefinition privateCtor = + MethodDefinition.constructorBuilder() + .setScope(ScopeNode.PRIVATE) + .setReturnType(classType) + .setArguments( + Arrays.asList(pagesVarExpr, collectionSizeVarExpr).stream() + .map(e -> e.toBuilder().setIsDecl(true).build()) + .collect(Collectors.toList())) + .setBody( + Arrays.asList( + ExprStatement.withExpr( + ReferenceConstructorExpr.superBuilder() + .setType(classExtendsType) + .setArguments(pagesVarExpr, collectionSizeVarExpr) + .build()))) + .build(); + + // createEmptyCollection method. + MethodDefinition createEmptyCollectionMethod = + MethodDefinition.builder() + .setScope(ScopeNode.PRIVATE) + .setIsStatic(true) + .setReturnType(classType) + .setName("createEmptyCollection") + .setReturnExpr( + NewObjectExpr.builder() + .setType(classType) + .setArguments( + ValueExpr.withValue(NullObjectValue.create()), + ValueExpr.withValue( + PrimitiveValue.builder().setType(TypeNode.INT).setValue("0").build())) + .build()) + .build(); + + // createCollection method. + MethodDefinition createCollectionMethod = + MethodDefinition.builder() + .setIsOverride(true) + .setScope(ScopeNode.PROTECTED) + .setReturnType(classType) + .setName("createCollection") + .setArguments( + Arrays.asList(pagesVarExpr, collectionSizeVarExpr).stream() + .map(e -> e.toBuilder().setIsDecl(true).build()) + .collect(Collectors.toList())) + .setReturnExpr( + NewObjectExpr.builder() + .setType(classType) + .setArguments(pagesVarExpr, collectionSizeVarExpr) + .build()) + .build(); + + List javaMethods = new ArrayList<>(); + javaMethods.add(privateCtor); + javaMethods.add(createEmptyCollectionMethod); + javaMethods.add(createCollectionMethod); + + return ClassDefinition.builder() + .setIsNested(true) + .setScope(ScopeNode.PUBLIC) + .setIsStatic(true) + .setExtendsType(classExtendsType) + .setName(className) + .setMethods(javaMethods) + .build(); + } + private static Map createTypes( Service service, Map messageTypes) { Map types = new HashMap<>(); diff --git a/src/test/java/com/google/api/generator/gapic/composer/ServiceClientClassComposerTest.java b/src/test/java/com/google/api/generator/gapic/composer/ServiceClientClassComposerTest.java index 3f65027bd1..371b184823 100644 --- a/src/test/java/com/google/api/generator/gapic/composer/ServiceClientClassComposerTest.java +++ b/src/test/java/com/google/api/generator/gapic/composer/ServiceClientClassComposerTest.java @@ -70,6 +70,7 @@ public void generateServiceClasses() { + "import com.google.api.core.BetaApi;\n" + "import com.google.api.gax.core.BackgroundResource;\n" + "import com.google.api.gax.longrunning.OperationFuture;\n" + + "import com.google.api.gax.paging.AbstractFixedSizeCollection;\n" + "import com.google.api.gax.paging.AbstractPage;\n" + "import com.google.api.gax.paging.AbstractPagedListResponse;\n" + "import com.google.api.gax.rpc.BidiStreamingCallable;\n" @@ -86,6 +87,7 @@ public void generateServiceClasses() { + "import com.google.showcase.v1beta1.stub.EchoStub;\n" + "import com.google.showcase.v1beta1.stub.EchoStubSettings;\n" + "import java.io.IOException;\n" + + "import java.util.List;\n" + "import java.util.Objects;\n" + "import java.util.concurrent.TimeUnit;\n" + "import javax.annotation.Generated;\n" @@ -505,5 +507,29 @@ public void generateServiceClasses() { + " return super.createPageAsync(context, futureResponse);\n" + " }\n" + " }\n" + + "\n" + + " public static class PagedExpandFixedSizeCollection\n" + + " extends AbstractFixedSizeCollection<\n" + + " PagedExpandRequest,\n" + + " PagedExpandResponse,\n" + + " EchoResponse,\n" + + " PagedExpandPage,\n" + + " PagedExpandFixedSizeCollection> {\n" + + "\n" + + " private PagedExpandFixedSizeCollection(List pages, int" + + " collectionSize) {\n" + + " super(pages, collectionSize);\n" + + " }\n" + + "\n" + + " private static PagedExpandFixedSizeCollection createEmptyCollection() {\n" + + " return new PagedExpandFixedSizeCollection(null, 0);\n" + + " }\n" + + "\n" + + " @Override\n" + + " protected PagedExpandFixedSizeCollection createCollection(\n" + + " List pages, int collectionSize) {\n" + + " return new PagedExpandFixedSizeCollection(pages, collectionSize);\n" + + " }\n" + + " }\n" + "}\n"; }