Skip to content

Commit

Permalink
feat: Add DIREGAPIC-specific pagination (#767)
Browse files Browse the repository at this point in the history
  • Loading branch information
vam-google authored Jun 17, 2021
1 parent bc6eb85 commit 1294c29
Show file tree
Hide file tree
Showing 18 changed files with 783 additions and 159 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -333,15 +333,21 @@ private MethodDefinition createRpcTestMethod(
String mockServiceVarName = getMockServiceVarName(rpcService);
if (method.isPaged()) {
Message methodOutputMessage = messageTypes.get(method.outputType().reference().fullName());
Field repeatedPagedResultsField = methodOutputMessage.findAndUnwrapFirstRepeatedField();
Field repeatedPagedResultsField = methodOutputMessage.findAndUnwrapPaginatedRepeatedField();
Preconditions.checkNotNull(
repeatedPagedResultsField,
String.format(
"No repeated field found for paged method %s with output message type %s",
method.name(), methodOutputMessage.name()));

// Must be a non-repeated type.
repeatedResponseType = repeatedPagedResultsField.type();
if (repeatedPagedResultsField.isMap()) {
repeatedResponseType =
TypeNode.withReference(repeatedPagedResultsField.type().reference().generics().get(1));
} else {
// Must be a non-repeated type.
repeatedResponseType = repeatedPagedResultsField.type();
}

responsesElementVarExpr =
VariableExpr.withVariable(
Variable.builder().setType(repeatedResponseType).setName("responsesElement").build());
Expand All @@ -364,7 +370,7 @@ private MethodDefinition createRpcTestMethod(
Expr expectedResponseValExpr = null;
if (method.isPaged()) {
Message methodOutputMessage = messageTypes.get(method.outputType().reference().fullName());
Field firstRepeatedField = methodOutputMessage.findAndUnwrapFirstRepeatedField();
Field firstRepeatedField = methodOutputMessage.findAndUnwrapPaginatedRepeatedField();
Preconditions.checkNotNull(
firstRepeatedField,
String.format(
Expand All @@ -373,7 +379,10 @@ private MethodDefinition createRpcTestMethod(

expectedResponseValExpr =
DefaultValueComposer.createSimplePagedResponse(
method.outputType(), firstRepeatedField.name(), responsesElementVarExpr);
method.outputType(),
firstRepeatedField.name(),
responsesElementVarExpr,
firstRepeatedField.isMap());
} else {
if (messageTypes.containsKey(methodOutputType.reference().fullName())) {
expectedResponseValExpr =
Expand Down Expand Up @@ -516,6 +525,9 @@ private MethodDefinition createRpcTestMethod(
}

if (method.isPaged()) {
Message methodOutputMessage = messageTypes.get(method.outputType().reference().fullName());
Field repeatedPagedResultsField = methodOutputMessage.findAndUnwrapPaginatedRepeatedField();

// Assign the resources variable.
VariableExpr resourcesVarExpr =
VariableExpr.withVariable(
Expand All @@ -524,7 +536,7 @@ private MethodDefinition createRpcTestMethod(
TypeNode.withReference(
ConcreteReference.builder()
.setClazz(List.class)
.setGenerics(Arrays.asList(repeatedResponseType.reference()))
.setGenerics(Arrays.asList(repeatedPagedResultsField.type().reference()))
.build()))
.setName("resources")
.build());
Expand Down Expand Up @@ -570,8 +582,6 @@ private MethodDefinition createRpcTestMethod(
.build());

// Assert the responses are equivalent.
Message methodOutputMessage = messageTypes.get(method.outputType().reference().fullName());
Field repeatedPagedResultsField = methodOutputMessage.findAndUnwrapFirstRepeatedField();
Preconditions.checkNotNull(
repeatedPagedResultsField,
String.format(
Expand All @@ -580,19 +590,52 @@ private MethodDefinition createRpcTestMethod(

Expr zeroExpr =
ValueExpr.withValue(PrimitiveValue.builder().setType(TypeNode.INT).setValue("0").build());
Expr expectedPagedResponseExpr =
MethodInvocationExpr.builder()
.setExprReferenceExpr(expectedResponseVarExpr)
.setMethodName(
String.format(
"get%sList", JavaStyle.toUpperCamelCase(repeatedPagedResultsField.name())))
.build();
expectedPagedResponseExpr =
MethodInvocationExpr.builder()
.setExprReferenceExpr(expectedPagedResponseExpr)
.setMethodName("get")
.setArguments(zeroExpr)
.build();

// Generated code:
// Assert.assertEquals(
// expectedResponse.getItemsMap().entrySet().iterator().next(), resources.get(0));
// )
Expr expectedPagedResponseExpr;
if (repeatedPagedResultsField.isMap()) {
expectedPagedResponseExpr =
MethodInvocationExpr.builder()
.setMethodName("next")
.setExprReferenceExpr(
MethodInvocationExpr.builder()
.setMethodName("iterator")
.setExprReferenceExpr(
MethodInvocationExpr.builder()
.setMethodName("entrySet")
.setExprReferenceExpr(
MethodInvocationExpr.builder()
.setExprReferenceExpr(expectedResponseVarExpr)
.setMethodName(
String.format(
"get%sMap",
JavaStyle.toUpperCamelCase(
repeatedPagedResultsField.name())))
.build())
.build())
.build())
.build();

} else {
// Generated code:
// Assert.assertEquals(expectedResponse.getItemsList().get(0), resources.get(0));
expectedPagedResponseExpr =
MethodInvocationExpr.builder()
.setExprReferenceExpr(expectedResponseVarExpr)
.setMethodName(
String.format(
"get%sList", JavaStyle.toUpperCamelCase(repeatedPagedResultsField.name())))
.build();
expectedPagedResponseExpr =
MethodInvocationExpr.builder()
.setExprReferenceExpr(expectedPagedResponseExpr)
.setMethodName("get")
.setArguments(zeroExpr)
.build();
}
Expr actualPagedResponseExpr =
MethodInvocationExpr.builder()
.setExprReferenceExpr(resourcesVarExpr)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -306,8 +306,7 @@ private static List<Statement> createClassStatements(
// Assign DEFAULT_SERVICE_SCOPES.
statements.add(SettingsCommentComposer.DEFAULT_SCOPES_COMMENT);
VariableExpr defaultServiceScopesDeclVarExpr =
DEFAULT_SERVICE_SCOPES_VAR_EXPR
.toBuilder()
DEFAULT_SERVICE_SCOPES_VAR_EXPR.toBuilder()
.setIsDecl(true)
.setScope(ScopeNode.PRIVATE)
.setIsStatic(true)
Expand Down Expand Up @@ -403,7 +402,7 @@ private static List<Expr> createPagingStaticAssignExprs(
"No method found for message type %s for method %s among %s",
pagedResponseMessageKey, method.name(), messageTypes.keySet()));

Field repeatedPagedResultsField = pagedResponseMessage.findAndUnwrapFirstRepeatedField();
Field repeatedPagedResultsField = pagedResponseMessage.findAndUnwrapPaginatedRepeatedField();
Preconditions.checkNotNull(
repeatedPagedResultsField,
String.format(
Expand Down Expand Up @@ -512,7 +511,7 @@ private static Expr createPagedListDescriptorAssignExpr(
returnExpr =
MethodInvocationExpr.builder()
.setExprReferenceExpr(newBuilderExpr)
.setMethodName("setPageSize")
.setMethodName("set" + JavaStyle.toUpperCamelCase(method.pageSizeFieldName()))
.setArguments(pageSizeVarExpr)
.build();
returnExpr =
Expand Down Expand Up @@ -543,7 +542,7 @@ private static Expr createPagedListDescriptorAssignExpr(
.setReturnExpr(
MethodInvocationExpr.builder()
.setExprReferenceExpr(payloadVarExpr)
.setMethodName("getPageSize")
.setMethodName("get" + JavaStyle.toUpperCamelCase(method.pageSizeFieldName()))
.setReturnType(returnType)
.build())
.build());
Expand Down Expand Up @@ -573,14 +572,56 @@ private static Expr createPagedListDescriptorAssignExpr(
.setClazz(Iterable.class)
.setGenerics(Arrays.asList(repeatedResponseType.reference()))
.build());
Expr getResponsesListExpr =
MethodInvocationExpr.builder()
.setExprReferenceExpr(payloadVarExpr)
.setMethodName(
String.format("get%sList", JavaStyle.toUpperCamelCase(repeatedFieldName)))
.setReturnType(returnType)
.build();

Expr getResponsesExpr;
Expr elseExpr;
Expr thenExpr;
if (repeatedResponseType.reference() != null
&& "java.util.Map.Entry".equals(repeatedResponseType.reference().fullName())) {
getResponsesExpr =
MethodInvocationExpr.builder()
.setExprReferenceExpr(payloadVarExpr)
.setMethodName(
String.format("get%sMap", JavaStyle.toUpperCamelCase(repeatedFieldName)))
.setReturnType(returnType)
.build();
thenExpr =
MethodInvocationExpr.builder()
.setStaticReferenceType(
TypeNode.withReference(ConcreteReference.withClazz(Collections.class)))
.setGenerics(Arrays.asList(repeatedResponseType.reference()))
.setMethodName("emptySet")
.setReturnType(returnType)
.build();
elseExpr =
MethodInvocationExpr.builder()
.setMethodName("entrySet")
.setExprReferenceExpr(
MethodInvocationExpr.builder()
.setExprReferenceExpr(payloadVarExpr)
.setMethodName(
String.format("get%sMap", JavaStyle.toUpperCamelCase(repeatedFieldName)))
.build())
.setReturnType(returnType)
.build();
} else {
getResponsesExpr =
MethodInvocationExpr.builder()
.setExprReferenceExpr(payloadVarExpr)
.setMethodName(
String.format("get%sList", JavaStyle.toUpperCamelCase(repeatedFieldName)))
.setReturnType(returnType)
.build();
thenExpr =
MethodInvocationExpr.builder()
.setStaticReferenceType(
TypeNode.withReference(ConcreteReference.withClazz(ImmutableList.class)))
.setGenerics(Arrays.asList(repeatedResponseType.reference()))
.setMethodName("of")
.setReturnType(returnType)
.build();
elseExpr = getResponsesExpr;
}
// While protobufs should not be null, this null-check is needed to protect against NPEs
// in paged iteration on clients that use legacy HTTP/JSON types, as these clients can
// actually return null instead of an empty list.
Expand All @@ -589,21 +630,13 @@ private static Expr createPagedListDescriptorAssignExpr(
// Relevant discussion where this check was first added:
// https://github.com/googleapis/google-cloud-java/pull/4499#discussion_r257057409
Expr conditionExpr =
RelationalOperationExpr.equalToWithExprs(getResponsesListExpr, ValueExpr.createNullExpr());
Expr thenExpr =
MethodInvocationExpr.builder()
.setStaticReferenceType(
TypeNode.withReference(ConcreteReference.withClazz(ImmutableList.class)))
.setGenerics(Arrays.asList(repeatedResponseType.reference()))
.setMethodName("of")
.setReturnType(returnType)
.build();
RelationalOperationExpr.equalToWithExprs(getResponsesExpr, ValueExpr.createNullExpr());

returnExpr =
TernaryExpr.builder()
.setConditionExpr(conditionExpr)
.setThenExpr(thenExpr)
.setElseExpr(getResponsesListExpr)
.setElseExpr(elseExpr)
.build();
anonClassMethods.add(
methodStarterBuilder
Expand All @@ -623,8 +656,7 @@ private static Expr createPagedListDescriptorAssignExpr(
// Declare and assign the variable.
return AssignmentExpr.builder()
.setVariableExpr(
pagedListDescVarExpr
.toBuilder()
pagedListDescVarExpr.toBuilder()
.setIsDecl(true)
.setScope(ScopeNode.PRIVATE)
.setIsStatic(true)
Expand Down Expand Up @@ -763,8 +795,7 @@ private static Expr createPagedListResponseFactoryAssignExpr(

return AssignmentExpr.builder()
.setVariableExpr(
pagedListResponseFactoryVarExpr
.toBuilder()
pagedListResponseFactoryVarExpr.toBuilder()
.setIsDecl(true)
.setScope(ScopeNode.PRIVATE)
.setIsStatic(true)
Expand Down Expand Up @@ -818,8 +849,7 @@ private MethodDefinition createCreateStubMethod(Service service, TypeStore typeS
// Set up the if-statement.
Expr tRansportNameExpr =
MethodInvocationExpr.builder()
.setStaticReferenceType(
getTransportContext().transportChannelType())
.setStaticReferenceType(getTransportContext().transportChannelType())
.setMethodName(getTransportContext().transportGetterName())
.build();

Expand All @@ -842,7 +872,8 @@ private MethodDefinition createCreateStubMethod(Service service, TypeStore typeS
Expr createExpr =
MethodInvocationExpr.builder()
.setStaticReferenceType(
typeStore.get(getTransportContext().classNames().getTransportServiceStubClassName(service)))
typeStore.get(
getTransportContext().classNames().getTransportServiceStubClassName(service)))
.setMethodName("create")
.setArguments(
ValueExpr.withValue(
Expand Down Expand Up @@ -995,7 +1026,8 @@ private List<MethodDefinition> createDefaultHelperAndGetterMethods(
return javaMethods;
}

private static List<MethodDefinition> createBuilderHelperMethods(Service service, TypeStore typeStore) {
private static List<MethodDefinition> createBuilderHelperMethods(
Service service, TypeStore typeStore) {
List<MethodDefinition> javaMethods = new ArrayList<>();
// Create the newBuilder() method.
final TypeNode builderReturnType = typeStore.get(NESTED_BUILDER_CLASS_NAME);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1042,7 +1042,7 @@ private static List<ClassDefinition> createNestedPagingClasses(
}
// Find the repeated field.
Message methodOutputMessage = messageTypes.get(method.outputType().reference().fullName());
Field repeatedPagedResultsField = methodOutputMessage.findAndUnwrapFirstRepeatedField();
Field repeatedPagedResultsField = methodOutputMessage.findAndUnwrapPaginatedRepeatedField();
Preconditions.checkNotNull(
repeatedPagedResultsField,
String.format(
Expand Down
Loading

0 comments on commit 1294c29

Please sign in to comment.