From f228417100e52ba681523976fc73eadc7dc37a79 Mon Sep 17 00:00:00 2001 From: Summer Ji Date: Tue, 6 Oct 2020 23:28:55 -0700 Subject: [PATCH] [ggj][codegen](1/2)feat: Add equals() method in ResourceName (#358) * Add Equals method in ResourceName --- .../ResourceNameHelperClassComposer.java | 117 ++++++++++++++++++ .../gapic/composer/goldens/FoobarName.golden | 15 +++ .../gapic/composer/goldens/SessionName.golden | 12 ++ 3 files changed, 144 insertions(+) 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 f686469607..2ae659617b 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 @@ -17,6 +17,7 @@ import com.google.api.core.BetaApi; import com.google.api.generator.engine.ast.AnnotationNode; import com.google.api.generator.engine.ast.AssignmentExpr; +import com.google.api.generator.engine.ast.CastExpr; import com.google.api.generator.engine.ast.ClassDefinition; import com.google.api.generator.engine.ast.CommentStatement; import com.google.api.generator.engine.ast.ConcreteReference; @@ -30,7 +31,9 @@ import com.google.api.generator.engine.ast.MethodInvocationExpr; import com.google.api.generator.engine.ast.NewObjectExpr; import com.google.api.generator.engine.ast.NullObjectValue; +import com.google.api.generator.engine.ast.PrimitiveValue; import com.google.api.generator.engine.ast.Reference; +import com.google.api.generator.engine.ast.RelationalOperationExpr; import com.google.api.generator.engine.ast.ReturnExpr; import com.google.api.generator.engine.ast.ScopeNode; import com.google.api.generator.engine.ast.Statement; @@ -57,6 +60,7 @@ import java.util.Arrays; import java.util.Collections; import java.util.HashMap; +import java.util.Iterator; import java.util.LinkedHashSet; import java.util.List; import java.util.Map; @@ -269,6 +273,7 @@ private static List createClassMethods( createFieldValueGetterMethods(resourceName, patternTokenVarExprs, tokenHierarchies, types)); javaMethods.add( createToStringMethod(templateFinalVarExprs, patternTokenVarExprs, tokenHierarchies)); + javaMethods.add(createEqualsMethod(resourceName, tokenHierarchies, types)); return javaMethods; } @@ -1140,6 +1145,118 @@ private static MethodDefinition createToStringMethod( .build(); } + private static MethodDefinition createEqualsMethod( + ResourceName resourceName, List> tokenHierarchies, Map types) { + // Create method definition variables. + Variable oVariable = Variable.builder().setType(TypeNode.OBJECT).setName("o").build(); + VariableExpr argVarExpr = + VariableExpr.builder().setIsDecl(false).setVariable(oVariable).build(); + TypeNode thisClassType = types.get(getThisClassName(resourceName)); + ValueExpr thisValueExpr = ValueExpr.withValue(ThisObjectValue.withType(thisClassType)); + ValueExpr trueValueExpr = + ValueExpr.withValue( + PrimitiveValue.builder().setType(TypeNode.BOOLEAN).setValue("true").build()); + + // Create first if statement's return expression + ReturnExpr returnTrueExpr = ReturnExpr.withExpr(trueValueExpr); + + // Create second if statement's condition expression + RelationalOperationExpr oEqualsThisExpr = + RelationalOperationExpr.equalToWithExprs(argVarExpr, thisValueExpr); + RelationalOperationExpr oNotEqualsNullExpr = + RelationalOperationExpr.notEqualToWithExprs( + argVarExpr, ValueExpr.withValue(NullObjectValue.create())); + MethodInvocationExpr getClassMethodInvocationExpr = + MethodInvocationExpr.builder().setMethodName("getClass").build(); + RelationalOperationExpr getClassEqualsExpr = + RelationalOperationExpr.equalToWithExprs( + getClassMethodInvocationExpr, + getClassMethodInvocationExpr.toBuilder().setExprReferenceExpr(argVarExpr).build()); + LogicalOperationExpr orLogicalExpr = + LogicalOperationExpr.logicalOrWithExprs(oNotEqualsNullExpr, getClassEqualsExpr); + + // Create second if statement's body assignment expression. + Variable thatVariable = Variable.builder().setName("that").setType(thisClassType).build(); + VariableExpr thatVariableExpr = + VariableExpr.builder().setIsDecl(false).setVariable(thatVariable).build(); + CastExpr oCastExpr = CastExpr.builder().setExpr(argVarExpr).setType(thisClassType).build(); + AssignmentExpr thatAssignmentExpr = + AssignmentExpr.builder() + .setVariableExpr(thatVariableExpr.toBuilder().setIsDecl(true).build()) + .setValueExpr(oCastExpr) + .build(); + + // Create return expression in the second if statement's body. + Set tokenSet = getTokenSet(tokenHierarchies); + Iterator itToken = tokenSet.iterator(); + Expr curTokenExpr = + createObjectsEqualsForTokenMethodEpxr( + thisValueExpr, + thatVariableExpr, + Variable.builder() + .setType(TypeNode.STRING) + .setName(JavaStyle.toLowerCamelCase(itToken.next())) + .build()); + while (itToken.hasNext()) { + Expr nextTokenExpr = + createObjectsEqualsForTokenMethodEpxr( + thisValueExpr, + thatVariableExpr, + Variable.builder() + .setType(TypeNode.STRING) + .setName(JavaStyle.toLowerCamelCase(itToken.next())) + .build()); + curTokenExpr = LogicalOperationExpr.logicalAndWithExprs(curTokenExpr, nextTokenExpr); + } + ReturnExpr secondIfReturnExpr = ReturnExpr.withExpr(curTokenExpr); + + // Code: if (o == this) { return true;} + IfStatement firstIfStatement = + IfStatement.builder() + .setConditionExpr(oEqualsThisExpr) + .setBody(Arrays.asList(ExprStatement.withExpr(returnTrueExpr))) + .build(); + // Code: if (o != null || getClass() == o.getClass()) { FoobarName that = ((FoobarName) o); + // return ..} + IfStatement secondIfStatement = + IfStatement.builder() + .setConditionExpr(orLogicalExpr) + .setBody( + Arrays.asList( + ExprStatement.withExpr(thatAssignmentExpr), + ExprStatement.withExpr(secondIfReturnExpr))) + .build(); + + // Create method's return expression. + ValueExpr falseValueExpr = + ValueExpr.withValue( + PrimitiveValue.builder().setType(TypeNode.BOOLEAN).setValue("false").build()); + + return MethodDefinition.builder() + .setIsOverride(true) + .setScope(ScopeNode.PUBLIC) + .setArguments(argVarExpr.toBuilder().setIsDecl(true).build()) + .setReturnType(TypeNode.BOOLEAN) + .setName("equals") + .setReturnExpr(falseValueExpr) + .setBody(Arrays.asList(firstIfStatement, secondIfStatement)) + .build(); + } + + private static MethodInvocationExpr createObjectsEqualsForTokenMethodEpxr( + Expr thisExpr, Expr thatExpr, Variable tokenVar) { + VariableExpr varThisExpr = + VariableExpr.builder().setVariable(tokenVar).setExprReferenceExpr(thisExpr).build(); + VariableExpr varThatExpr = + VariableExpr.builder().setVariable(tokenVar).setExprReferenceExpr(thatExpr).build(); + return MethodInvocationExpr.builder() + .setStaticReferenceType(STATIC_TYPES.get("Objects")) + .setMethodName("equals") + .setArguments(Arrays.asList(varThisExpr, varThatExpr)) + .setReturnType(TypeNode.BOOLEAN) + .build(); + } + private static List createNestedBuilderClasses( ResourceName resourceName, List> tokenHierarchies, diff --git a/src/test/java/com/google/api/generator/gapic/composer/goldens/FoobarName.golden b/src/test/java/com/google/api/generator/gapic/composer/goldens/FoobarName.golden index 7676c60e08..ac8d8995d2 100644 --- a/src/test/java/com/google/api/generator/gapic/composer/goldens/FoobarName.golden +++ b/src/test/java/com/google/api/generator/gapic/composer/goldens/FoobarName.golden @@ -249,6 +249,21 @@ public class FoobarName implements ResourceName { return !Objects.isNull(fixedValue) ? fixedValue : pathTemplate.instantiate(getFieldValuesMap()); } + @Override + public boolean equals(Object o) { + if (o == this) { + return true; + } + if (o != null || getClass() == o.getClass()) { + FoobarName that = ((FoobarName) o); + return Objects.equals(this.project, that.project) + && Objects.equals(this.foobar, that.foobar) + && Objects.equals(this.variant, that.variant) + && Objects.equals(this.barFoo, that.barFoo); + } + return false; + } + /** Builder for projects/{project}/foobars/{foobar}. */ public static class Builder { private String project; diff --git a/src/test/java/com/google/api/generator/gapic/composer/goldens/SessionName.golden b/src/test/java/com/google/api/generator/gapic/composer/goldens/SessionName.golden index 4dbe76e88e..58e15add60 100644 --- a/src/test/java/com/google/api/generator/gapic/composer/goldens/SessionName.golden +++ b/src/test/java/com/google/api/generator/gapic/composer/goldens/SessionName.golden @@ -101,6 +101,18 @@ public class SessionName implements ResourceName { return SESSION.instantiate("session", session); } + @Override + public boolean equals(Object o) { + if (o == this) { + return true; + } + if (o != null || getClass() == o.getClass()) { + SessionName that = ((SessionName) o); + return Objects.equals(this.session, that.session); + } + return false; + } + /** Builder for sessions/{session}. */ public static class Builder { private String session;