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 f2811a2e4d..fb7f089d3e 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 @@ -63,6 +63,7 @@ import java.util.Set; import java.util.function.Function; import java.util.stream.Collectors; +import java.util.stream.IntStream; public class Parser { private static final String COMMA = ","; @@ -547,17 +548,8 @@ static LongrunningOperation parseLro( OperationInfo lroInfo = methodDescriptor.getOptions().getExtension(OperationsProto.operationInfo); - String responseTypeName = lroInfo.getResponseType(); - String responseTypePackage = ""; - if (responseTypeName.contains(DOT)) { - responseTypeName = responseTypeName.substring(responseTypeName.lastIndexOf(DOT) + 1); - } - - String metadataTypeName = lroInfo.getMetadataType(); - if (metadataTypeName.contains(DOT)) { - metadataTypeName = metadataTypeName.substring(metadataTypeName.lastIndexOf(DOT) + 1); - } - + String responseTypeName = parseNestedProtoTypeName(lroInfo.getResponseType()); + String metadataTypeName = parseNestedProtoTypeName(lroInfo.getMetadataType()); Message responseMessage = messageTypes.get(responseTypeName); Message metadataMessage = messageTypes.get(metadataTypeName); Preconditions.checkNotNull( @@ -722,4 +714,24 @@ private static String parseServiceJavaPackage(CodeGeneratorRequest request) { !Strings.isNullOrEmpty(finalJavaPackage), "No service Java package found"); return finalJavaPackage; } + + /** + * Retrieves the nested type name from a fully-qualified protobuf type name. Example: + * google.ads.googleads.v3.resources.MutateJob.MutateJobMetadata > MutateJob.MutateJobMetadata. + */ + @VisibleForTesting + static String parseNestedProtoTypeName(String fullyQualifiedName) { + if (!fullyQualifiedName.contains(DOT)) { + return fullyQualifiedName; + } + // Find the first component in CapitalCamelCase. Assumes that proto package + // components must be in all lowercase and type names are in CapitalCamelCase. + String[] components = fullyQualifiedName.split("\\."); + List nestedTypeComponents = + IntStream.range(0, components.length) + .filter(i -> Character.isUpperCase(components[i].charAt(0))) + .mapToObj(i -> components[i]) + .collect(Collectors.toList()); + return String.join(".", nestedTypeComponents); + } } 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 4315edc1a0..62a5026ee0 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 @@ -447,6 +447,18 @@ public void sanitizeDefaultHost_basic() { assertEquals(String.format("%s:443", defaultHost), Parser.sanitizeDefaultHost(defaultHost)); } + @Test + public void parseNestedProtoTypeName() { + assertEquals("MutateJobMetadata", Parser.parseNestedProtoTypeName("MutateJobMetadata")); + assertEquals( + "MutateJob.MutateJobMetadata", + Parser.parseNestedProtoTypeName("MutateJob.MutateJobMetadata")); + assertEquals( + "MutateJob.MutateJobMetadata", + Parser.parseNestedProtoTypeName( + "google.ads.googleads.v3.resources.MutateJob.MutateJobMetadata")); + } + private void assertMethodArgumentEquals( String name, TypeNode type, List nestedFields, MethodArgument argument) { assertEquals(name, argument.name());