diff --git a/src/main/java/com/google/api/generator/engine/ast/ConcreteReference.java b/src/main/java/com/google/api/generator/engine/ast/ConcreteReference.java index 58494fe7a5..bb92b2bebf 100644 --- a/src/main/java/com/google/api/generator/engine/ast/ConcreteReference.java +++ b/src/main/java/com/google/api/generator/engine/ast/ConcreteReference.java @@ -89,11 +89,18 @@ public String pakkage() { public abstract boolean useFullName(); @Override - public String enclosingClassName() { + public ImmutableList enclosingClassNames() { if (!hasEnclosingClass()) { - return null; + return ImmutableList.of(); } - return clazz().getEnclosingClass().getSimpleName(); + // The innermost type will be the last element in the list. + ImmutableList.Builder listBuilder = new ImmutableList.Builder<>(); + Class currentClz = clazz(); + while (currentClz.getEnclosingClass() != null) { + listBuilder.add(currentClz.getEnclosingClass().getSimpleName()); + currentClz = currentClz.getEnclosingClass(); + } + return listBuilder.build(); } @Override diff --git a/src/main/java/com/google/api/generator/engine/ast/Reference.java b/src/main/java/com/google/api/generator/engine/ast/Reference.java index ed26731f0f..7031b5cbe6 100644 --- a/src/main/java/com/google/api/generator/engine/ast/Reference.java +++ b/src/main/java/com/google/api/generator/engine/ast/Reference.java @@ -30,7 +30,7 @@ public interface Reference { boolean useFullName(); @Nullable - String enclosingClassName(); + ImmutableList enclosingClassNames(); @Nullable Reference wildcardUpperBound(); diff --git a/src/main/java/com/google/api/generator/engine/ast/VaporReference.java b/src/main/java/com/google/api/generator/engine/ast/VaporReference.java index cd9361ebe3..a2f0176c36 100644 --- a/src/main/java/com/google/api/generator/engine/ast/VaporReference.java +++ b/src/main/java/com/google/api/generator/engine/ast/VaporReference.java @@ -15,9 +15,9 @@ package com.google.api.generator.engine.ast; import com.google.auto.value.AutoValue; -import com.google.common.base.Strings; import com.google.common.collect.ImmutableList; import java.util.Arrays; +import java.util.Collections; import java.util.List; import java.util.Objects; import javax.annotation.Nullable; @@ -43,7 +43,7 @@ public abstract class VaporReference implements Reference { @Nullable @Override - public abstract String enclosingClassName(); + public abstract ImmutableList enclosingClassNames(); @Nullable public abstract Reference supertypeReference(); @@ -56,9 +56,9 @@ public Reference wildcardUpperBound() { @Override public String fullName() { - // TODO(unsupported): Nested classes with depth greater than 1. if (hasEnclosingClass()) { - return String.format("%s.%s.%s", pakkage(), enclosingClassName(), plainName()); + return String.format( + "%s.%s.%s", pakkage(), String.join(DOT, enclosingClassNames()), plainName()); } return String.format("%s.%s", pakkage(), plainName()); } @@ -68,7 +68,7 @@ public String fullName() { @Override public boolean hasEnclosingClass() { - return !Strings.isNullOrEmpty(enclosingClassName()); + return !enclosingClassNames().isEmpty(); } @Override @@ -86,7 +86,7 @@ public boolean isSupertypeOrEquals(Reference other) { VaporReference ref = (VaporReference) other; return pakkage().equals(ref.pakkage()) && plainName().equals(ref.plainName()) - && Objects.equals(enclosingClassName(), ref.enclosingClassName()); + && Objects.equals(enclosingClassNames(), ref.enclosingClassNames()); } @Override @@ -112,14 +112,14 @@ public boolean equals(Object o) { return pakkage().equals(ref.pakkage()) && name().equals(ref.name()) && generics().equals(ref.generics()) - && Objects.equals(enclosingClassName(), ref.enclosingClassName()); + && Objects.equals(enclosingClassNames(), ref.enclosingClassNames()); } @Override public int hashCode() { int hash = 17 * pakkage().hashCode() + 19 * name().hashCode() + 23 * generics().hashCode(); - if (!Strings.isNullOrEmpty(enclosingClassName())) { - hash += 29 * enclosingClassName().hashCode(); + if (!enclosingClassNames().isEmpty()) { + hash += 29 * enclosingClassNames().hashCode(); } return hash; } @@ -133,7 +133,8 @@ public static Builder builder() { return new AutoValue_VaporReference.Builder() .setUseFullName(false) .setGenerics(ImmutableList.of()) - .setIsStaticImport(false); + .setIsStaticImport(false) + .setEnclosingClassNames(Collections.emptyList()); } // Private. @@ -153,7 +154,11 @@ public Builder setGenerics(Reference... references) { public abstract Builder setGenerics(List clazzes); - public abstract Builder setEnclosingClassName(String enclosingClassName); + public Builder setEnclosingClassNames(String... enclosingClassNames) { + return setEnclosingClassNames(Arrays.asList(enclosingClassNames)); + } + + public abstract Builder setEnclosingClassNames(List enclosingClassNames); public abstract Builder setIsStaticImport(boolean isStaticImport); @@ -166,8 +171,7 @@ public Builder setGenerics(Reference... references) { abstract ImmutableList generics(); - @Nullable - abstract String enclosingClassName(); + abstract ImmutableList enclosingClassNames(); abstract boolean isStaticImport(); @@ -180,11 +184,11 @@ public VaporReference build() { setPlainName(name()); - setIsStaticImport(enclosingClassName() != null && isStaticImport()); + setIsStaticImport(!enclosingClassNames().isEmpty() && isStaticImport()); StringBuilder sb = new StringBuilder(); - if (enclosingClassName() != null && !isStaticImport()) { - sb.append(enclosingClassName()); + if (!enclosingClassNames().isEmpty() && !isStaticImport()) { + sb.append(String.join(DOT, enclosingClassNames())); sb.append(DOT); } diff --git a/src/main/java/com/google/api/generator/engine/writer/ImportWriterVisitor.java b/src/main/java/com/google/api/generator/engine/writer/ImportWriterVisitor.java index af456a33db..a040823e7b 100644 --- a/src/main/java/com/google/api/generator/engine/writer/ImportWriterVisitor.java +++ b/src/main/java/com/google/api/generator/engine/writer/ImportWriterVisitor.java @@ -68,6 +68,7 @@ import javax.annotation.Nullable; public class ImportWriterVisitor implements AstNodeVisitor { + private static final String DOT = "."; private static final String NEWLINE = "\n"; private static final String PKG_JAVA_LANG = "java.lang"; @@ -423,7 +424,8 @@ private void references(List refs) { if (ref.isStaticImport() && !Strings.isNullOrEmpty(currentClassName) - && ref.enclosingClassName().equals(currentClassName)) { + && !ref.enclosingClassNames().isEmpty() + && ref.enclosingClassNames().contains(currentClassName)) { continue; } @@ -432,7 +434,8 @@ private void references(List refs) { staticImports.add(ref.fullName()); } else { if (ref.hasEnclosingClass()) { - imports.add(String.format("%s.%s", ref.pakkage(), ref.enclosingClassName())); + imports.add( + String.format("%s.%s", ref.pakkage(), String.join(DOT, ref.enclosingClassNames()))); } else { imports.add(ref.fullName()); } diff --git a/src/main/java/com/google/api/generator/gapic/composer/BatchingDescriptorComposer.java b/src/main/java/com/google/api/generator/gapic/composer/BatchingDescriptorComposer.java index 5d15f481e0..4202809ce1 100644 --- a/src/main/java/com/google/api/generator/gapic/composer/BatchingDescriptorComposer.java +++ b/src/main/java/com/google/api/generator/gapic/composer/BatchingDescriptorComposer.java @@ -153,7 +153,7 @@ private static MethodDefinition createGetRequestBuilderMethod( TypeNode builderType = TypeNode.withReference( VaporReference.builder() - .setEnclosingClassName(method.inputType().reference().name()) + .setEnclosingClassNames(method.inputType().reference().name()) .setName("Builder") .setPakkage(method.inputType().reference().pakkage()) .build()); diff --git a/src/main/java/com/google/api/generator/gapic/composer/GrpcServiceStubClassComposer.java b/src/main/java/com/google/api/generator/gapic/composer/GrpcServiceStubClassComposer.java index 0d688dfc47..b556f03dcb 100644 --- a/src/main/java/com/google/api/generator/gapic/composer/GrpcServiceStubClassComposer.java +++ b/src/main/java/com/google/api/generator/gapic/composer/GrpcServiceStubClassComposer.java @@ -1049,7 +1049,7 @@ private static Map createDynamicTypes(Service service, String VaporReference.builder() .setName(String.format(PAGED_RESPONSE_TYPE_NAME_PATTERN, m.name())) .setPakkage(service.pakkage()) - .setEnclosingClassName(String.format("%sClient", service.name())) + .setEnclosingClassNames(String.format("%sClient", service.name())) .setIsStaticImport(true) .build())))); return types; diff --git a/src/main/java/com/google/api/generator/gapic/composer/ResourceNameHelperClassComposer.java b/src/main/java/com/google/api/generator/gapic/composer/ResourceNameHelperClassComposer.java index 8fcb09896b..c1e499fbec 100644 --- a/src/main/java/com/google/api/generator/gapic/composer/ResourceNameHelperClassComposer.java +++ b/src/main/java/com/google/api/generator/gapic/composer/ResourceNameHelperClassComposer.java @@ -1575,7 +1575,7 @@ private static Map createDynamicTypes( VaporReference.builder() .setName("Builder") .setPakkage(resourceName.pakkage()) - .setEnclosingClassName(thisClassName) + .setEnclosingClassNames(thisClassName) .setIsStaticImport(true) .build())); @@ -1591,7 +1591,7 @@ private static Map createDynamicTypes( VaporReference.builder() .setName(s) .setPakkage(resourceName.pakkage()) - .setEnclosingClassName(thisClassName) + .setEnclosingClassNames(thisClassName) .setIsStaticImport(true) .build())))); } 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 87850c88a2..22c541cfba 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 @@ -1441,7 +1441,7 @@ private static Map createVaporTypes(Service service) { VaporReference.builder() .setName( String.format(t, JavaStyle.toUpperCamelCase(method.name()))) - .setEnclosingClassName(getClientClassName(service.name())) + .setEnclosingClassNames(getClientClassName(service.name())) .setPakkage(service.pakkage()) .setIsStaticImport(true) // Same class, so they won't be imported. .build())))); @@ -1466,7 +1466,7 @@ private static Map createVaporTypes(Service service) { VaporReference.builder() .setName(String.format(PAGED_RESPONSE_TYPE_NAME_PATTERN, m.name())) .setPakkage(service.pakkage()) - .setEnclosingClassName(getClientClassName(service.name())) + .setEnclosingClassNames(getClientClassName(service.name())) .setIsStaticImport(true) .build())))); return types; diff --git a/src/main/java/com/google/api/generator/gapic/composer/ServiceClientTestClassComposer.java b/src/main/java/com/google/api/generator/gapic/composer/ServiceClientTestClassComposer.java index 3c18458963..0b2b9cf020 100644 --- a/src/main/java/com/google/api/generator/gapic/composer/ServiceClientTestClassComposer.java +++ b/src/main/java/com/google/api/generator/gapic/composer/ServiceClientTestClassComposer.java @@ -1749,7 +1749,7 @@ private static Map createDynamicTypes(Service service) { VaporReference.builder() .setName(String.format(PAGED_RESPONSE_TYPE_NAME_PATTERN, m.name())) .setPakkage(service.pakkage()) - .setEnclosingClassName(getClientClassName(service.name())) + .setEnclosingClassNames(getClientClassName(service.name())) .setIsStaticImport(true) .build())))); return types; @@ -1864,7 +1864,7 @@ private static TypeNode getPagedResponseType(Method method, Service service) { VaporReference.builder() .setName(String.format(PAGED_RESPONSE_TYPE_NAME_PATTERN, method.name())) .setPakkage(service.pakkage()) - .setEnclosingClassName(getClientClassName(service.name())) + .setEnclosingClassNames(getClientClassName(service.name())) .setIsStaticImport(true) .build()); } diff --git a/src/main/java/com/google/api/generator/gapic/composer/ServiceSettingsClassComposer.java b/src/main/java/com/google/api/generator/gapic/composer/ServiceSettingsClassComposer.java index accb22d978..45f625f32f 100644 --- a/src/main/java/com/google/api/generator/gapic/composer/ServiceSettingsClassComposer.java +++ b/src/main/java/com/google/api/generator/gapic/composer/ServiceSettingsClassComposer.java @@ -230,7 +230,7 @@ private static MethodDefinition createCreatorMethod( TypeNode.withReference( VaporReference.builder() .setName("Builder") - .setEnclosingClassName(String.format("%sSettings", service.name())) + .setEnclosingClassNames(String.format("%sSettings", service.name())) .setPakkage(service.pakkage()) .build()); Expr returnMethodExpr = @@ -712,7 +712,7 @@ private static Map createDynamicTypes(Service service) { TypeNode.withReference( VaporReference.builder() .setName(BUILDER_CLASS_NAME) - .setEnclosingClassName(getThisClassName(service.name())) + .setEnclosingClassNames(getThisClassName(service.name())) .setPakkage(service.pakkage()) .setIsStaticImport(true) .build())); @@ -729,7 +729,7 @@ private static Map createDynamicTypes(Service service) { VaporReference.builder() .setName(String.format(PAGED_RESPONSE_TYPE_NAME_PATTERN, m.name())) .setPakkage(service.pakkage()) - .setEnclosingClassName(getClientClassName(service.name())) + .setEnclosingClassNames(getClientClassName(service.name())) .setIsStaticImport(true) .build())))); return types; @@ -828,7 +828,7 @@ private static TypeNode getStubSettingsBuilderType(Service service) { VaporReference.builder() .setPakkage(service.pakkage()) .setName(BUILDER_CLASS_NAME) - .setEnclosingClassName(getStubSettingsClassName(service.name())) + .setEnclosingClassNames(getStubSettingsClassName(service.name())) .build()); } diff --git a/src/main/java/com/google/api/generator/gapic/composer/ServiceStubClassComposer.java b/src/main/java/com/google/api/generator/gapic/composer/ServiceStubClassComposer.java index 6afbf9256b..ce1f79727e 100644 --- a/src/main/java/com/google/api/generator/gapic/composer/ServiceStubClassComposer.java +++ b/src/main/java/com/google/api/generator/gapic/composer/ServiceStubClassComposer.java @@ -262,7 +262,7 @@ private static Map createTypes( VaporReference.builder() .setName(String.format(PAGED_RESPONSE_TYPE_NAME_PATTERN, m.name())) .setPakkage(service.pakkage()) - .setEnclosingClassName(getClientClassName(service.name())) + .setEnclosingClassNames(getClientClassName(service.name())) .setIsStaticImport(true) .build())))); diff --git a/src/main/java/com/google/api/generator/gapic/composer/ServiceStubSettingsClassComposer.java b/src/main/java/com/google/api/generator/gapic/composer/ServiceStubSettingsClassComposer.java index 2b35fcf842..ede0311809 100644 --- a/src/main/java/com/google/api/generator/gapic/composer/ServiceStubSettingsClassComposer.java +++ b/src/main/java/com/google/api/generator/gapic/composer/ServiceStubSettingsClassComposer.java @@ -133,6 +133,7 @@ public class ServiceStubSettingsClassComposer { private static final String OPERATION_SETTINGS_LITERAL = "OperationSettings"; private static final String SETTINGS_LITERAL = "Settings"; + private static final String DOT = "."; private static final String LEFT_BRACE = "{"; private static final String RIGHT_BRACE = "}"; private static final String SLASH = "/"; @@ -1369,7 +1370,7 @@ private static List createNestedClassConstructorMethods( t -> TypeNode.withReference( VaporReference.builder() - .setName(t.reference().enclosingClassName()) + .setName(String.join(DOT, t.reference().enclosingClassNames())) .setPakkage(t.reference().pakkage()) .build()); List ctorBodyStatements = new ArrayList<>(); @@ -1845,7 +1846,7 @@ private static Map createDynamicTypes(Service service, String VaporReference.builder() .setName(NESTED_BUILDER_CLASS_NAME) .setPakkage(pakkage) - .setEnclosingClassName(thisClassName) + .setEnclosingClassNames(thisClassName) .setIsStaticImport(true) .build())); @@ -1874,7 +1875,7 @@ private static Map createDynamicTypes(Service service, String VaporReference.builder() .setName(getPagedResponseTypeName(m.name())) .setPakkage(service.pakkage()) - .setEnclosingClassName(String.format("%sClient", service.name())) + .setEnclosingClassNames(String.format("%sClient", service.name())) .setIsStaticImport(true) .build())))); diff --git a/src/main/java/com/google/api/generator/gapic/model/Message.java b/src/main/java/com/google/api/generator/gapic/model/Message.java index b9a613d000..14c9b9cf12 100644 --- a/src/main/java/com/google/api/generator/gapic/model/Message.java +++ b/src/main/java/com/google/api/generator/gapic/model/Message.java @@ -19,6 +19,7 @@ import com.google.auto.value.AutoValue; import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableMap; +import java.util.Collections; import java.util.List; import java.util.Map; import java.util.stream.Collectors; @@ -41,6 +42,11 @@ public abstract class Message { @Nullable public abstract ResourceName resource(); + // The nested types in left-to-right order, if any. + // Example: com.google.Foo.Bar.Car.ThisType will have the outer types listed in the order + // [Foo, Bar, Car]. + public abstract ImmutableList outerNestedTypes(); + public abstract Builder toBuilder(); public boolean hasResource() { @@ -60,7 +66,7 @@ public Field findAndUnwrapFirstRepeatedField() { } public static Builder builder() { - return new AutoValue_Message.Builder(); + return new AutoValue_Message.Builder().setOuterNestedTypes(Collections.emptyList()); } @AutoValue.Builder @@ -73,6 +79,8 @@ public abstract static class Builder { public abstract Builder setResource(ResourceName resource); + public abstract Builder setOuterNestedTypes(List outerNestedTypes); + abstract Builder setFieldMap(Map fieldMap); abstract ImmutableList fields(); 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 3f56eac203..53578d3d0e 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 @@ -215,22 +215,40 @@ public static Map parseMessages(CodeGeneratorRequest request) { } public static Map parseMessages(FileDescriptor fileDescriptor) { - String pakkage = TypeParser.getPackage(fileDescriptor); - return fileDescriptor.getMessageTypes().stream() - .collect( - Collectors.toMap( - md -> md.getName(), - md -> - Message.builder() - .setType( - TypeNode.withReference( - VaporReference.builder() - .setName(md.getName()) - .setPakkage(pakkage) - .build())) - .setName(md.getName()) - .setFields(parseFields(md)) - .build())); + // TODO(miraleung): Preserve nested type and package data in the type key. + Map messages = new HashMap<>(); + for (Descriptor messageDescriptor : fileDescriptor.getMessageTypes()) { + messages.putAll(parseMessages(messageDescriptor)); + } + return messages; + } + + private static Map parseMessages(Descriptor messageDescriptor) { + return parseMessages(messageDescriptor, new ArrayList()); + } + + private static Map parseMessages( + Descriptor messageDescriptor, List outerNestedTypes) { + Map messages = new HashMap<>(); + String messageName = messageDescriptor.getName(); + if (!messageDescriptor.getNestedTypes().isEmpty()) { + for (Descriptor nestedMessage : messageDescriptor.getNestedTypes()) { + outerNestedTypes.add(messageName); + messages.putAll(parseMessages(nestedMessage, outerNestedTypes)); + } + } + String pakkage = TypeParser.getPackage(messageDescriptor.getFile()); + messages.put( + messageName, + Message.builder() + .setType( + TypeNode.withReference( + VaporReference.builder().setName(messageName).setPakkage(pakkage).build())) + .setName(messageName) + .setFields(parseFields(messageDescriptor)) + .setOuterNestedTypes(outerNestedTypes) + .build()); + return messages; } /** diff --git a/src/main/java/com/google/api/generator/gapic/protoparser/TypeParser.java b/src/main/java/com/google/api/generator/gapic/protoparser/TypeParser.java index ae8439a647..a5f45faad9 100644 --- a/src/main/java/com/google/api/generator/gapic/protoparser/TypeParser.java +++ b/src/main/java/com/google/api/generator/gapic/protoparser/TypeParser.java @@ -28,6 +28,7 @@ import com.google.protobuf.Descriptors.FieldDescriptor; import com.google.protobuf.Descriptors.FieldDescriptor.JavaType; import com.google.protobuf.Descriptors.FileDescriptor; +import java.util.ArrayList; import java.util.Arrays; import java.util.List; import java.util.Map; @@ -115,16 +116,21 @@ static Reference parseFieldReference(FieldDescriptor field) { @VisibleForTesting static Reference parseMessageReference(@Nonnull Descriptor messageDescriptor) { // TODO(miraleung): Handle deeper levels of nesting. - String pakkage = getPackage(messageDescriptor.getFile()); - VaporReference.Builder messageReferenceBuilder = - VaporReference.builder().setName(messageDescriptor.getName()).setPakkage(pakkage); - - boolean isNestedType = messageDescriptor.getContainingType() != null; - if (isNestedType) { - String enclosingClassName = messageDescriptor.getContainingType().getName(); - messageReferenceBuilder.setEnclosingClassName(enclosingClassName); + List outerNestedTypeNames = new ArrayList<>(); + Descriptor containingType = messageDescriptor.getContainingType(); + while (containingType != null) { + // Outermost type in the nested type hierarchy lies at index 0. + outerNestedTypeNames.add(0, containingType.getName()); + containingType = containingType.getContainingType(); } - Reference messageReference = messageReferenceBuilder.build(); + + String pakkage = getPackage(messageDescriptor.getFile()); + Reference messageReference = + VaporReference.builder() + .setName(messageDescriptor.getName()) + .setPakkage(pakkage) + .setEnclosingClassNames(outerNestedTypeNames) + .build(); String protoPackage = messageDescriptor.getFile().getPackage(); Preconditions.checkState( messageReference @@ -142,17 +148,22 @@ static Reference parseMessageReference(@Nonnull Descriptor messageDescriptor) { static Reference parseEnumReference(@Nonnull EnumDescriptor enumDescriptor) { // This is similar to parseMessageReference, but we make it a separate method because // EnumDescriptor and Descriptor are sibling types. + List outerNestedTypeNames = new ArrayList<>(); + Descriptor containingType = enumDescriptor.getContainingType(); + while (containingType != null) { + // Outermost type in the nested type hierarchy lies at index 0. + outerNestedTypeNames.add(0, containingType.getName()); + containingType = containingType.getContainingType(); + } + // TODO(miraleung): Handle deeper levels of nesting. String pakkage = getPackage(enumDescriptor.getFile()); - VaporReference.Builder enumReferenceBuilder = - VaporReference.builder().setName(enumDescriptor.getName()).setPakkage(pakkage); - - boolean isNestedType = enumDescriptor.getContainingType() != null; - if (isNestedType) { - String enclosingClassName = enumDescriptor.getContainingType().getName(); - enumReferenceBuilder.setEnclosingClassName(enclosingClassName); - } - Reference enumReference = enumReferenceBuilder.build(); + Reference enumReference = + VaporReference.builder() + .setName(enumDescriptor.getName()) + .setPakkage(pakkage) + .setEnclosingClassNames(outerNestedTypeNames) + .build(); String protoPackage = enumDescriptor.getFile().getPackage(); Preconditions.checkState( enumReference diff --git a/src/test/java/com/google/api/generator/engine/ast/VaporReferenceTest.java b/src/test/java/com/google/api/generator/engine/ast/VaporReferenceTest.java index 59a09a3a25..042e4b4582 100644 --- a/src/test/java/com/google/api/generator/engine/ast/VaporReferenceTest.java +++ b/src/test/java/com/google/api/generator/engine/ast/VaporReferenceTest.java @@ -55,12 +55,14 @@ public void basic_nested() { String enclosingClassName = "Babbage"; Reference ref = VaporReference.builder() - .setEnclosingClassName(enclosingClassName) + .setEnclosingClassNames("Babbage", "Ada") .setName(name) .setPakkage(pkg) .build(); - assertEquals(ref.name(), String.format("%s.%s", enclosingClassName, name)); - assertEquals(ref.fullName(), String.format("%s.%s.%s", pkg, enclosingClassName, name)); + + assertEquals(ref.name(), "Babbage.Ada.Charles"); + assertTrue(ref.hasEnclosingClass()); + assertEquals(ref.fullName(), String.format("%s.%s.%s.%s", pkg, "Babbage", "Ada", name)); assertTrue(ref.hasEnclosingClass()); assertTrue(ref.isFromPackage(pkg)); assertFalse(ref.isFromPackage("com.google.example.library")); @@ -74,7 +76,7 @@ public void basic_nestedAndStaticImport() { String enclosingClassName = "Babbage"; Reference ref = VaporReference.builder() - .setEnclosingClassName(enclosingClassName) + .setEnclosingClassNames(enclosingClassName) .setName(name) .setPakkage(pkg) .setIsStaticImport(true) @@ -109,7 +111,7 @@ public void enclosingClass() { VaporReference.builder() .setName(name) .setPakkage(pkg) - .setEnclosingClassName(enclosingName) + .setEnclosingClassNames(enclosingName) .build(); assertTrue(ref.hasEnclosingClass()); assertEquals(ref.fullName(), String.format("%s.%s.%s", pkg, enclosingName, name)); diff --git a/src/test/java/com/google/api/generator/gapic/protoparser/BUILD.bazel b/src/test/java/com/google/api/generator/gapic/protoparser/BUILD.bazel index b4af740184..7df82d359f 100644 --- a/src/test/java/com/google/api/generator/gapic/protoparser/BUILD.bazel +++ b/src/test/java/com/google/api/generator/gapic/protoparser/BUILD.bazel @@ -13,6 +13,7 @@ TESTS = [ "ServiceConfigParserTest", "ServiceYamlParserTest", "SourceCodeInfoParserTest", + "TypeParserTest", ] filegroup( diff --git a/src/test/java/com/google/api/generator/gapic/protoparser/TypeParserTest.java b/src/test/java/com/google/api/generator/gapic/protoparser/TypeParserTest.java new file mode 100644 index 0000000000..37ace31584 --- /dev/null +++ b/src/test/java/com/google/api/generator/gapic/protoparser/TypeParserTest.java @@ -0,0 +1,55 @@ +// Copyright 2020 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.protoparser; + +import static junit.framework.Assert.assertEquals; + +import com.google.api.generator.engine.ast.Reference; +import com.google.protobuf.Descriptors.Descriptor; +import com.google.protobuf.Descriptors.FileDescriptor; +import com.google.protobuf.Descriptors.MethodDescriptor; +import com.google.protobuf.Descriptors.ServiceDescriptor; +import com.google.showcase.v1beta1.EchoOuterClass; +import com.google.testgapic.v1beta1.NestedMessageProto; +import org.junit.Test; + +public class TypeParserTest { + private static final String ECHO_PACKAGE = "com.google.showcase.v1beta1"; + // TODO(miraleung): Backfill with more tests (e.g. field, message, methods) for Parser.java. + @Test + public void parseMessageType_basic() { + FileDescriptor echoFileDescriptor = EchoOuterClass.getDescriptor(); + ServiceDescriptor echoService = echoFileDescriptor.getServices().get(0); + assertEquals(echoService.getName(), "Echo"); + + MethodDescriptor echoMethodDescriptor = echoService.getMethods().get(0); + Reference reference = TypeParser.parseMessageReference(echoMethodDescriptor.getInputType()); + assertEquals("com.google.showcase.v1beta1.EchoRequest", reference.fullName()); + } + + @Test + public void parseMessageType_nested() { + FileDescriptor fileDescriptor = NestedMessageProto.getDescriptor(); + Descriptor messageDescriptor = fileDescriptor.getMessageTypes().get(0); + assertEquals("Outer", messageDescriptor.getName()); + messageDescriptor = messageDescriptor.getNestedTypes().get(0); + assertEquals("Middle", messageDescriptor.getName()); + messageDescriptor = messageDescriptor.getNestedTypes().get(0); + assertEquals("Inner", messageDescriptor.getName()); + + Reference reference = TypeParser.parseMessageReference(messageDescriptor); + assertEquals("com.google.testgapic.v1beta1.Outer.Middle.Inner", reference.fullName()); + } +} diff --git a/src/test/java/com/google/api/generator/gapic/testdata/BUILD.bazel b/src/test/java/com/google/api/generator/gapic/testdata/BUILD.bazel index 9b425d8013..4909db60e6 100644 --- a/src/test/java/com/google/api/generator/gapic/testdata/BUILD.bazel +++ b/src/test/java/com/google/api/generator/gapic/testdata/BUILD.bazel @@ -60,6 +60,7 @@ proto_library( srcs = [ "bad_message_resname_def.proto", "locker.proto", + "nested_message.proto", ], deps = [ "@com_google_googleapis//google/api:annotations_proto", diff --git a/src/test/java/com/google/api/generator/gapic/testdata/nested_message.proto b/src/test/java/com/google/api/generator/gapic/testdata/nested_message.proto new file mode 100644 index 0000000000..1b2bae113e --- /dev/null +++ b/src/test/java/com/google/api/generator/gapic/testdata/nested_message.proto @@ -0,0 +1,36 @@ +// Copyright 2018 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 +// +// https://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. + +syntax = "proto3"; + +package google.testgapic; + +option java_package = "com.google.testgapic.v1beta1"; +option java_multiple_files = true; +option java_outer_classname = "NestedMessageProto"; + +message Outer { + string name = 1; + + Middle middle = 2; + + Middle.Inner innermost = 3; + + message Middle { + int32 x = 4; + message Inner { + int32 y = 5; + } + } +}