1 // Copyright 2020 Google LLC
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 //      http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 
15 package com.google.api.generator.engine.ast;
16 
17 import com.google.auto.value.AutoValue;
18 import com.google.common.base.Preconditions;
19 
20 @AutoValue
21 public abstract class LogicalOperationExpr implements OperationExpr {
22 
lhsExpr()23   public abstract Expr lhsExpr();
24 
rhsExpr()25   public abstract Expr rhsExpr();
26 
27   @Override
operatorKind()28   public abstract OperatorKind operatorKind();
29 
30   @Override
type()31   public TypeNode type() {
32     return TypeNode.BOOLEAN;
33   }
34 
35   @Override
accept(AstNodeVisitor visitor)36   public void accept(AstNodeVisitor visitor) {
37     visitor.visit(this);
38   }
39 
40   // Convenience wrapper.
logicalAndWithExprs(Expr lhsExpr, Expr rhsExpr)41   public static LogicalOperationExpr logicalAndWithExprs(Expr lhsExpr, Expr rhsExpr) {
42     return builder()
43         .setLhsExpr(lhsExpr)
44         .setRhsExpr(rhsExpr)
45         .setOperatorKind(OperatorKind.LOGICAL_AND)
46         .build();
47   }
48 
49   // Convenience wrapper.
logicalOrWithExprs(Expr lhsExpr, Expr rhsExpr)50   public static LogicalOperationExpr logicalOrWithExprs(Expr lhsExpr, Expr rhsExpr) {
51     return builder()
52         .setLhsExpr(lhsExpr)
53         .setRhsExpr(rhsExpr)
54         .setOperatorKind(OperatorKind.LOGICAL_OR)
55         .build();
56   }
57 
builder()58   private static Builder builder() {
59     return new AutoValue_LogicalOperationExpr.Builder();
60   }
61 
62   @AutoValue.Builder
63   abstract static class Builder {
64     // Private setter.
setLhsExpr(Expr expr)65     abstract Builder setLhsExpr(Expr expr);
66 
67     // Private setter.
setRhsExpr(Expr expr)68     abstract Builder setRhsExpr(Expr expr);
69 
70     // Private setter.
setOperatorKind(OperatorKind operator)71     abstract Builder setOperatorKind(OperatorKind operator);
72 
autoBuild()73     abstract LogicalOperationExpr autoBuild();
74 
build()75     private LogicalOperationExpr build() {
76       LogicalOperationExpr logicalOperationExpr = autoBuild();
77       TypeNode lhsExprType = logicalOperationExpr.lhsExpr().type();
78       TypeNode rhsExprType = logicalOperationExpr.rhsExpr().type();
79       OperatorKind operator = logicalOperationExpr.operatorKind();
80       final String errorMsg =
81           String.format(
82               "Logical operator %s is valid only on boolean or its boxed type, found %s, %s.",
83               operator, lhsExprType.toString(), rhsExprType.toString());
84       Preconditions.checkState(
85           lhsExprType.equals(TypeNode.BOOLEAN) && rhsExprType.equals(TypeNode.BOOLEAN), errorMsg);
86       return logicalOperationExpr;
87     }
88   }
89 }
90