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 committed Jun 17, 2021
1 parent bc6eb85 commit 1294c29
Show file tree
Hide file tree
Showing 18 changed files with 783 additions and 159 deletions.
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
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
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

0 comments on commit 1294c29

Please sign in to comment.