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 c1e499fbec..564e6dad4f 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 @@ -1090,21 +1090,25 @@ private static MethodDefinition createToStringMethod( List> tokenHierarchies) { boolean hasVariants = tokenHierarchies.size() > 1; if (!hasVariants) { - String token = getTokenSet(tokenHierarchies).stream().collect(Collectors.toList()).get(0); - String javaTokenVarName = JavaStyle.toLowerCamelCase(token); - Preconditions.checkNotNull( - patternTokenVarExprs.get(token), - String.format( - "No expression found for token %s amongst values %s", - javaTokenVarName, patternTokenVarExprs.toString())); + + List instantiateArgExprs = new ArrayList<>(); + List tokens = getTokenSet(tokenHierarchies).stream().collect(Collectors.toList()); + for (int i = 0; i < tokens.size(); i++) { + String token = tokens.get(i); + Preconditions.checkNotNull( + patternTokenVarExprs.get(token), + String.format( + "No expression found for token %s amongst values %s", + token, patternTokenVarExprs.toString())); + instantiateArgExprs.add(ValueExpr.withValue(StringObjectValue.withValue(token))); + instantiateArgExprs.add(patternTokenVarExprs.get(token)); + } MethodInvocationExpr returnInstantiateExpr = MethodInvocationExpr.builder() .setExprReferenceExpr(templateFinalVarExprs.get(0)) .setMethodName("instantiate") - .setArguments( - ValueExpr.withValue(StringObjectValue.withValue(token)), - patternTokenVarExprs.get(token)) + .setArguments(instantiateArgExprs) .setReturnType(TypeNode.STRING) .build(); return MethodDefinition.builder() diff --git a/src/test/java/com/google/api/generator/gapic/composer/ResourceNameHelperClassComposerTest.java b/src/test/java/com/google/api/generator/gapic/composer/ResourceNameHelperClassComposerTest.java index cf29462c31..f29ea0ec7e 100644 --- a/src/test/java/com/google/api/generator/gapic/composer/ResourceNameHelperClassComposerTest.java +++ b/src/test/java/com/google/api/generator/gapic/composer/ResourceNameHelperClassComposerTest.java @@ -25,13 +25,19 @@ import com.google.api.generator.gapic.protoparser.Parser; import com.google.api.generator.test.framework.Assert; import com.google.api.generator.test.framework.Utils; +import com.google.logging.v2.LogEntryProto; +import com.google.logging.v2.LoggingConfigProto; +import com.google.logging.v2.LoggingMetricsProto; +import com.google.logging.v2.LoggingProto; import com.google.protobuf.Descriptors.FileDescriptor; import com.google.protobuf.Descriptors.ServiceDescriptor; import com.google.showcase.v1beta1.EchoOuterClass; import com.google.showcase.v1beta1.TestingOuterClass; +import google.cloud.CommonResources; import java.nio.file.Path; import java.nio.file.Paths; import java.util.Arrays; +import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Map; @@ -95,7 +101,6 @@ public void generateResourceNameClass_echoFoobarMultiplePatterns() { ResourceName foobarResname = resourceNames.get("showcase.googleapis.com/Foobar"); assertThat(outputResourceNames).contains(foobarResname); - Service echoProtoService = services.get(0); GapicClass clazz = ResourceNameHelperClassComposer.instance().generate(foobarResname); JavaWriterVisitor visitor = new JavaWriterVisitor(); @@ -105,6 +110,55 @@ public void generateResourceNameClass_echoFoobarMultiplePatterns() { Assert.assertCodeEquals(goldenFilePath, visitor.write()); } + @Test + public void generateResourceNameClass_loggingOnePatternMultipleVariables() { + FileDescriptor serviceFileDescriptor = LoggingConfigProto.getDescriptor(); + ServiceDescriptor serviceDescriptor = serviceFileDescriptor.getServices().get(0); + assertEquals(serviceDescriptor.getName(), "ConfigServiceV2"); + + List protoFiles = + Arrays.asList( + serviceFileDescriptor, + LoggingProto.getDescriptor(), + LogEntryProto.getDescriptor(), + LoggingConfigProto.getDescriptor(), + LoggingMetricsProto.getDescriptor()); + + Map resourceNames = new HashMap<>(); + Map messageTypes = new HashMap<>(); + for (FileDescriptor fileDescriptor : protoFiles) { + resourceNames.putAll(Parser.parseResourceNames(fileDescriptor)); + messageTypes.putAll(Parser.parseMessages(fileDescriptor)); + } + + // Additional resource names. + FileDescriptor commonResourcesFileDescriptor = CommonResources.getDescriptor(); + resourceNames.putAll(Parser.parseResourceNames(commonResourcesFileDescriptor)); + + Set outputResourceNames = new HashSet<>(); + List services = + Parser.parseService( + serviceFileDescriptor, + messageTypes, + resourceNames, + Optional.empty(), + outputResourceNames); + + ResourceName billingAccountLocationResname = + resourceNames.get("logging.googleapis.com/BillingAccountLocation"); + assertThat(outputResourceNames).contains(billingAccountLocationResname); + + GapicClass clazz = + ResourceNameHelperClassComposer.instance().generate(billingAccountLocationResname); + + JavaWriterVisitor visitor = new JavaWriterVisitor(); + clazz.classDefinition().accept(visitor); + Utils.saveCodegenToFile(this.getClass(), "BillingAccountLocationName.golden", visitor.write()); + Path goldenFilePath = + Paths.get(ComposerConstants.GOLDENFILES_DIRECTORY, "BillingAccountLocationName.golden"); + Assert.assertCodeEquals(goldenFilePath, visitor.write()); + } + @Test public void generateResourceNameClass_testingSessionOnePattern() { FileDescriptor testingFileDescriptor = TestingOuterClass.getDescriptor(); @@ -125,7 +179,6 @@ public void generateResourceNameClass_testingSessionOnePattern() { ResourceName sessionResname = resourceNames.get("showcase.googleapis.com/Session"); assertThat(outputResourceNames).contains(sessionResname); - Service testingProtoService = services.get(0); GapicClass clazz = ResourceNameHelperClassComposer.instance().generate(sessionResname); JavaWriterVisitor visitor = new JavaWriterVisitor(); @@ -134,5 +187,4 @@ public void generateResourceNameClass_testingSessionOnePattern() { Path goldenFilePath = Paths.get(ComposerConstants.GOLDENFILES_DIRECTORY, "SessionName.golden"); Assert.assertCodeEquals(goldenFilePath, visitor.write()); } - // TODO(miraleung): Add more tests for a single pattern. } diff --git a/src/test/java/com/google/api/generator/gapic/composer/goldens/BillingAccountLocationName.golden b/src/test/java/com/google/api/generator/gapic/composer/goldens/BillingAccountLocationName.golden new file mode 100644 index 0000000000..94fd7c738d --- /dev/null +++ b/src/test/java/com/google/api/generator/gapic/composer/goldens/BillingAccountLocationName.golden @@ -0,0 +1,173 @@ +package com.google.logging.v2; + +import com.google.api.pathtemplate.PathTemplate; +import com.google.api.resourcenames.ResourceName; +import com.google.common.base.Preconditions; +import com.google.common.collect.ImmutableMap; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.Objects; +import javax.annotation.Generated; + +// AUTO-GENERATED DOCUMENTATION AND CLASS. +@Generated("by gapic-generator-java") +public class BillingAccountLocationName implements ResourceName { + private static final PathTemplate BILLING_ACCOUNT_LOCATION = + PathTemplate.createWithoutUrlEncoding( + "billingAccounts/{billing_account}/locations/{location}"); + private volatile Map fieldValuesMap; + private final String billingAccount; + private final String location; + + private BillingAccountLocationName(Builder builder) { + billingAccount = Preconditions.checkNotNull(builder.getBillingAccount()); + location = Preconditions.checkNotNull(builder.getLocation()); + } + + public String getBillingAccount() { + return billingAccount; + } + + public String getLocation() { + return location; + } + + public static Builder newBuilder() { + return new Builder(); + } + + public Builder toBuilder() { + return new Builder(this); + } + + public static BillingAccountLocationName of(String billingAccount, String location) { + return newBuilder().setBillingAccount(billingAccount).setLocation(location).build(); + } + + public static String format(String billingAccount, String location) { + return newBuilder().setBillingAccount(billingAccount).setLocation(location).build().toString(); + } + + public static BillingAccountLocationName parse(String formattedString) { + if (formattedString.isEmpty()) { + return null; + } + Map matchMap = + BILLING_ACCOUNT_LOCATION.validatedMatch( + formattedString, + "BillingAccountLocationName.parse: formattedString not in valid format"); + return of(matchMap.get("billing_account"), matchMap.get("location")); + } + + public static List parseList(List formattedStrings) { + List list = new ArrayList<>(formattedStrings.size()); + for (String formattedString : formattedStrings) { + list.add(parse(formattedString)); + } + return list; + } + + public static List toStringList(List values) { + List list = new ArrayList<>(values.size()); + for (BillingAccountLocationName value : values) { + if (Objects.isNull(value)) { + list.add(""); + } else { + list.add(value.toString()); + } + } + return list; + } + + public static boolean isParsableFrom(String formattedString) { + return BILLING_ACCOUNT_LOCATION.matches(formattedString); + } + + @Override + public Map getFieldValuesMap() { + if (Objects.isNull(fieldValuesMap)) { + synchronized (this) { + if (Objects.isNull(fieldValuesMap)) { + ImmutableMap.Builder fieldMapBuilder = ImmutableMap.builder(); + if (!Objects.isNull(billingAccount)) { + fieldMapBuilder.put("billing_account", billingAccount); + } + if (!Objects.isNull(location)) { + fieldMapBuilder.put("location", location); + } + fieldValuesMap = fieldMapBuilder.build(); + } + } + } + return fieldValuesMap; + } + + public String getFieldValue(String fieldName) { + return getFieldValuesMap().get(fieldName); + } + + @Override + public String toString() { + return BILLING_ACCOUNT_LOCATION.instantiate( + "billing_account", billingAccount, "location", location); + } + + @Override + public boolean equals(Object o) { + if (o == this) { + return true; + } + if (o != null || getClass() == o.getClass()) { + BillingAccountLocationName that = ((BillingAccountLocationName) o); + return Objects.equals(this.billingAccount, that.billingAccount) + && Objects.equals(this.location, that.location); + } + return false; + } + + @Override + public int hashCode() { + int h = 1; + h *= 1000003; + h ^= Objects.hashCode(billingAccount); + h *= 1000003; + h ^= Objects.hashCode(location); + return h; + } + + /** Builder for billingAccounts/{billing_account}/locations/{location}. */ + public static class Builder { + private String billingAccount; + private String location; + + private Builder() {} + + public String getBillingAccount() { + return billingAccount; + } + + public String getLocation() { + return location; + } + + public Builder setBillingAccount(String billingAccount) { + this.billingAccount = billingAccount; + return this; + } + + public Builder setLocation(String location) { + this.location = location; + return this; + } + + private Builder(BillingAccountLocationName billingAccountLocationName) { + billingAccount = billingAccountLocationName.billingAccount; + location = billingAccountLocationName.location; + } + + public BillingAccountLocationName build() { + return new BillingAccountLocationName(this); + } + } +} diff --git a/test/integration/goldens/logging/BillingAccountLocationName.java b/test/integration/goldens/logging/BillingAccountLocationName.java index 3d108a3a4b..ead5f6cdec 100644 --- a/test/integration/goldens/logging/BillingAccountLocationName.java +++ b/test/integration/goldens/logging/BillingAccountLocationName.java @@ -125,7 +125,8 @@ public String getFieldValue(String fieldName) { @Override public String toString() { - return BILLING_ACCOUNT_LOCATION.instantiate("billing_account", billingAccount); + return BILLING_ACCOUNT_LOCATION.instantiate( + "billing_account", billingAccount, "location", location); } @Override diff --git a/test/integration/goldens/logging/FolderLocationName.java b/test/integration/goldens/logging/FolderLocationName.java index 526f0d1b62..24d56ee303 100644 --- a/test/integration/goldens/logging/FolderLocationName.java +++ b/test/integration/goldens/logging/FolderLocationName.java @@ -123,7 +123,7 @@ public String getFieldValue(String fieldName) { @Override public String toString() { - return FOLDER_LOCATION.instantiate("folder", folder); + return FOLDER_LOCATION.instantiate("folder", folder, "location", location); } @Override diff --git a/test/integration/goldens/logging/LocationName.java b/test/integration/goldens/logging/LocationName.java index 9074b6586d..9bc33a8940 100644 --- a/test/integration/goldens/logging/LocationName.java +++ b/test/integration/goldens/logging/LocationName.java @@ -123,7 +123,7 @@ public String getFieldValue(String fieldName) { @Override public String toString() { - return PROJECT_LOCATION.instantiate("project", project); + return PROJECT_LOCATION.instantiate("project", project, "location", location); } @Override diff --git a/test/integration/goldens/logging/LogMetricName.java b/test/integration/goldens/logging/LogMetricName.java index 104ecc3266..1d7150abad 100644 --- a/test/integration/goldens/logging/LogMetricName.java +++ b/test/integration/goldens/logging/LogMetricName.java @@ -123,7 +123,7 @@ public String getFieldValue(String fieldName) { @Override public String toString() { - return PROJECT_METRIC.instantiate("project", project); + return PROJECT_METRIC.instantiate("project", project, "metric", metric); } @Override diff --git a/test/integration/goldens/logging/OrganizationLocationName.java b/test/integration/goldens/logging/OrganizationLocationName.java index 08dbc40fd5..2f9cde61d8 100644 --- a/test/integration/goldens/logging/OrganizationLocationName.java +++ b/test/integration/goldens/logging/OrganizationLocationName.java @@ -123,7 +123,7 @@ public String getFieldValue(String fieldName) { @Override public String toString() { - return ORGANIZATION_LOCATION.instantiate("organization", organization); + return ORGANIZATION_LOCATION.instantiate("organization", organization, "location", location); } @Override diff --git a/test/integration/goldens/redis/InstanceName.java b/test/integration/goldens/redis/InstanceName.java index f2fb7dfe5a..ac6e5b1ce5 100644 --- a/test/integration/goldens/redis/InstanceName.java +++ b/test/integration/goldens/redis/InstanceName.java @@ -138,7 +138,8 @@ public String getFieldValue(String fieldName) { @Override public String toString() { - return PROJECT_LOCATION_INSTANCE.instantiate("project", project); + return PROJECT_LOCATION_INSTANCE.instantiate( + "project", project, "location", location, "instance", instance); } @Override diff --git a/test/integration/goldens/redis/LocationName.java b/test/integration/goldens/redis/LocationName.java index d781b0b94b..89cad0d585 100644 --- a/test/integration/goldens/redis/LocationName.java +++ b/test/integration/goldens/redis/LocationName.java @@ -123,7 +123,7 @@ public String getFieldValue(String fieldName) { @Override public String toString() { - return PROJECT_LOCATION.instantiate("project", project); + return PROJECT_LOCATION.instantiate("project", project, "location", location); } @Override