Skip to content

Commit

Permalink
fix: Use parent type instead of child_type in method doc sample (#862)
Browse files Browse the repository at this point in the history
Fixes: #852.
  • Loading branch information
meltsufin committed Nov 3, 2021
1 parent 64d8374 commit 6a39c7f
Show file tree
Hide file tree
Showing 20 changed files with 2,114 additions and 133 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@
import com.google.api.generator.gapic.model.ResourceName;
import com.google.api.generator.gapic.utils.JavaStyle;
import com.google.api.generator.gapic.utils.ResourceNameConstants;
import com.google.api.generator.gapic.utils.ResourceReferenceUtils;
import com.google.common.annotations.VisibleForTesting;
import com.google.common.base.Preconditions;
import com.google.longrunning.Operation;
Expand All @@ -48,6 +49,7 @@
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.stream.Collectors;

public class DefaultValueComposer {
Expand Down Expand Up @@ -76,6 +78,7 @@ public static Expr createDefaultValue(
Expr defValue =
createDefaultValue(
resourceName,
methodArg.field().resourceReference().isChildType(),
resourceNames.values().stream().collect(Collectors.toList()),
methodArg.field().name());

Expand Down Expand Up @@ -175,17 +178,46 @@ static Expr createDefaultValue(Field f, boolean useExplicitInitTypeInGenerics) {
}

public static Expr createDefaultValue(
ResourceName resourceName, List<ResourceName> resnames, String fieldOrMessageName) {
return createDefaultValueResourceHelper(resourceName, resnames, fieldOrMessageName, true);
ResourceName resourceName,
boolean isChildType,
List<ResourceName> resnames,
String fieldOrMessageName) {
return createDefaultValueResourceHelper(
resourceName, isChildType, resnames, fieldOrMessageName, true);
}

private static Optional<ResourceName> findParentResource(
ResourceName childResource, List<ResourceName> resourceNames) {
Map<String, ResourceName> patternToResourceName = new HashMap<>();

for (ResourceName resourceName : resourceNames) {
for (String parentPattern : resourceName.patterns()) {
patternToResourceName.put(parentPattern, resourceName);
}
}

for (String childPattern : childResource.patterns()) {
Optional<String> parentPattern = ResourceReferenceUtils.parseParentPattern(childPattern);
if (parentPattern.isPresent() && patternToResourceName.containsKey(parentPattern.get())) {
return Optional.of(patternToResourceName.get(parentPattern.get()));
}
}

return Optional.empty();
}

@VisibleForTesting
static Expr createDefaultValueResourceHelper(
ResourceName resourceName,
boolean isChildType,
List<ResourceName> resnames,
String fieldOrMessageName,
boolean allowAnonResourceNameClass) {

if (isChildType) {
resourceName = findParentResource(resourceName, resnames).orElse(resourceName);
}

boolean hasOnePattern = resourceName.patterns().size() == 1;
if (resourceName.isOnlyWildcard()) {
List<ResourceName> unexaminedResnames = new ArrayList<>(resnames);
Expand All @@ -195,7 +227,7 @@ static Expr createDefaultValueResourceHelper(
continue;
}
unexaminedResnames.remove(resname);
return createDefaultValue(resname, unexaminedResnames, fieldOrMessageName);
return createDefaultValue(resname, false, unexaminedResnames, fieldOrMessageName);
}

if (unexaminedResnames.isEmpty()) {
Expand Down Expand Up @@ -283,6 +315,7 @@ public static Expr createSimpleMessageBuilderExpr(
defaultExpr =
createDefaultValueResourceHelper(
resourceNames.get(field.resourceReference().resourceTypeString()),
field.resourceReference().isChildType(),
resourceNames.values().stream().collect(Collectors.toList()),
message.name(),
/* allowAnonResourceNameClass = */ false);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1293,6 +1293,7 @@ private static List<Expr> createRpcMethodArgumentDefaultValueExprs(
.setExprReferenceExpr(
DefaultValueComposer.createDefaultValue(
resourceNames.get(arg.field().resourceReference().resourceTypeString()),
arg.field().resourceReference().isChildType(),
resourceNameList,
arg.field().name()))
.setMethodName("toString")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -881,7 +881,9 @@ static String parsePageSizeFieldName(
// with monolith-gnerated libraries.
String pagedFieldName = null;

if (inputMessage.fieldMap().containsKey("page_token")
if (inputMessage != null
&& inputMessage.fieldMap().containsKey("page_token")
&& outputMessage != null
&& outputMessage.fieldMap().containsKey("next_page_token")) {
// List of potential field names representing page size.
// page_size gets priority over max_results if both are present
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
import com.google.api.generator.gapic.model.ResourceName;
import com.google.api.generator.gapic.model.ResourceReference;
import com.google.api.generator.gapic.utils.JavaStyle;
import com.google.api.generator.gapic.utils.ResourceNameConstants;
import com.google.api.generator.gapic.utils.ResourceReferenceUtils;
import com.google.api.pathtemplate.PathTemplate;
import com.google.common.annotations.VisibleForTesting;
import com.google.common.base.Preconditions;
Expand Down Expand Up @@ -108,7 +108,7 @@ static Optional<ResourceName> parseParentResourceName(
String resourceTypeString,
@Nullable String description,
Map<String, ResourceName> patternsToResourceNames) {
Optional<String> parentPatternOpt = parseParentPattern(pattern);
Optional<String> parentPatternOpt = ResourceReferenceUtils.parseParentPattern(pattern);
if (!parentPatternOpt.isPresent()) {
return Optional.empty();
}
Expand Down Expand Up @@ -178,31 +178,6 @@ static Optional<ResourceName> parseParentResourceName(
return Optional.of(parentResourceName);
}

@VisibleForTesting
static Optional<String> parseParentPattern(String pattern) {
String[] tokens = pattern.split(SLASH);
String lastToken = tokens[tokens.length - 1];
if (lastToken.equals(ResourceNameConstants.DELETED_TOPIC_LITERAL)
|| lastToken.equals(ResourceNameConstants.WILDCARD_PATTERN)) {
return Optional.empty();
}

int lastTokenIndex = tokens.length - 2;
int minLengthWithParent = 4;
// Singleton patterns, e.g. projects/{project}/agent.
if (!lastToken.contains("{")) {
minLengthWithParent = 3;
lastTokenIndex = tokens.length - 1;
}

// No fully-formed parent. Expected: ancestors/{ancestor}/childNodes/{child_node}.
if (tokens.length < minLengthWithParent) {
return Optional.empty();
}

return Optional.of(String.join(SLASH, Arrays.asList(tokens).subList(0, lastTokenIndex)));
}

@VisibleForTesting
static String resolvePackages(String resourceNamePackage, String servicePackage) {
return resourceNamePackage.contains(servicePackage) ? resourceNamePackage : servicePackage;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
// 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.utils;

import java.util.Arrays;
import java.util.Optional;

public final class ResourceReferenceUtils {

private static final String SLASH = "/";

private ResourceReferenceUtils() {}

public static Optional<String> parseParentPattern(String pattern) {
String[] tokens = pattern.split(SLASH);
String lastToken = tokens[tokens.length - 1];
if (lastToken.equals(ResourceNameConstants.DELETED_TOPIC_LITERAL)
|| lastToken.equals(ResourceNameConstants.WILDCARD_PATTERN)) {
return Optional.empty();
}

int lastTokenIndex = tokens.length - 2;
int minLengthWithParent = 4;
// Singleton patterns, e.g. projects/{project}/agent.
if (!lastToken.contains("{")) {
minLengthWithParent = 3;
lastTokenIndex = tokens.length - 1;
}

// No fully-formed parent. Expected: ancestors/{ancestor}/childNodes/{child_node}.
if (tokens.length < minLengthWithParent) {
return Optional.empty();
}

return Optional.of(String.join(SLASH, Arrays.asList(tokens).subList(0, lastTokenIndex)));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@
import com.google.pubsub.v1.PubsubProto;
import com.google.showcase.v1beta1.EchoOuterClass;
import com.google.showcase.v1beta1.IdentityOuterClass;
import com.google.showcase.v1beta1.MessagingOuterClass;
import com.google.showcase.v1beta1.TestingOuterClass;
import com.google.testdata.v1.DeprecatedServiceOuterClass;
import google.cloud.CommonResources;
Expand All @@ -51,6 +52,7 @@
import java.util.Set;

public class TestProtoLoader {

private static final TestProtoLoader INSTANCE =
new TestProtoLoader(Transport.GRPC, "src/test/java/com/google/api/generator/gapic/testdata/");
private final String testFilesDirectory;
Expand Down Expand Up @@ -170,6 +172,27 @@ public GapicContext parseShowcaseIdentity() {
.build();
}

public GapicContext parseShowcaseMessaging() {
FileDescriptor fileDescriptor = MessagingOuterClass.getDescriptor();
ServiceDescriptor messagingService = fileDescriptor.getServices().get(0);
assertEquals(messagingService.getName(), "Messaging");

Map<String, Message> messageTypes = Parser.parseMessages(fileDescriptor);
Map<String, ResourceName> resourceNames = Parser.parseResourceNames(fileDescriptor);
Set<ResourceName> outputResourceNames = new HashSet<>();
List<Service> services =
Parser.parseService(
fileDescriptor, messageTypes, resourceNames, Optional.empty(), outputResourceNames);

return GapicContext.builder()
.setMessages(messageTypes)
.setResourceNames(resourceNames)
.setServices(services)
.setHelperResourceNames(outputResourceNames)
.setTransport(transport)
.build();
}

public GapicContext parseShowcaseTesting() {
FileDescriptor testingFileDescriptor = TestingOuterClass.getDescriptor();
ServiceDescriptor testingService = testingFileDescriptor.getServices().get(0);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -161,6 +161,7 @@ public void defaultValue_resourceNameWithOnePattern() {
Expr expr =
DefaultValueComposer.createDefaultValue(
resourceName,
false,
typeStringsToResourceNames.values().stream().collect(Collectors.toList()),
"ignored");
expr.accept(writerVisitor);
Expand All @@ -177,6 +178,7 @@ public void defaultValue_resourceNameWithMultiplePatterns() {
Expr expr =
DefaultValueComposer.createDefaultValue(
resourceName,
false,
typeStringsToResourceNames.values().stream().collect(Collectors.toList()),
"ignored");
expr.accept(writerVisitor);
Expand All @@ -194,6 +196,7 @@ public void defaultValue_resourceNameWithWildcardPattern() {
Expr expr =
DefaultValueComposer.createDefaultValue(
resourceName,
false,
typeStringsToResourceNames.values().stream().collect(Collectors.toList()),
"ignored");
expr.accept(writerVisitor);
Expand All @@ -216,6 +219,7 @@ public void defaultValue_wildcardResourceNameWithOnlyDeletedTopic() {
Expr expr =
DefaultValueComposer.createDefaultValue(
resourceName,
false,
typeStringsToResourceNames.values().stream().collect(Collectors.toList()),
"ignored");
expr.accept(writerVisitor);
Expand All @@ -236,6 +240,7 @@ public void defaultValue_resourceNameWithOnlyWildcards_valueOnly() {
Expr expr =
DefaultValueComposer.createDefaultValueResourceHelper(
resourceName,
false,
Collections.emptyList(),
fallbackField,
/* allowAnonResourceNameClass = */ false);
Expand All @@ -257,7 +262,7 @@ public void defaultValue_resourceNameWithOnlyWildcards_allowAnonResourceNameClas
String fallbackField = "foobar";
Expr expr =
DefaultValueComposer.createDefaultValue(
resourceName, Collections.emptyList(), fallbackField);
resourceName, false, Collections.emptyList(), fallbackField);
expr.accept(writerVisitor);
String expected =
LineFormatter.lines(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -78,4 +78,17 @@ public void generateServiceClasses_bookshopNameConflicts() {
Path goldenFilePath = Paths.get(Utils.getGoldenDir(this.getClass()), "BookshopClient.golden");
assertCodeEquals(goldenFilePath, visitor.write());
}

@Test
public void generateServiceClasses_childTypeParentInJavadoc() {
GapicContext context = GrpcTestProtoLoader.instance().parseShowcaseMessaging();
Service protoService = context.services().get(0);
GapicClass clazz = ServiceClientClassComposer.instance().generate(context, protoService);

JavaWriterVisitor visitor = new JavaWriterVisitor();
clazz.classDefinition().accept(visitor);
Utils.saveCodegenToFile(this.getClass(), "MessagingClient.golden", visitor.write());
Path goldenFilePath = Paths.get(Utils.getGoldenDir(this.getClass()), "MessagingClient.golden");
assertCodeEquals(goldenFilePath, visitor.write());
}
}
Loading

0 comments on commit 6a39c7f

Please sign in to comment.