• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 TernaryExpr implements Expr {
conditionExpr()22   public abstract Expr conditionExpr();
23 
thenExpr()24   public abstract Expr thenExpr();
25 
elseExpr()26   public abstract Expr elseExpr();
27 
28   @Override
type()29   public TypeNode type() {
30     TypeNode thenType = thenExpr().type();
31     TypeNode elseType = elseExpr().type();
32     if (thenType.isPrimitiveType() || elseType.isPrimitiveType()) {
33       // If both types are equal primitive, return either of them (elseType).
34       // If types are boxed/primitive equal, return the boxed type.
35       return thenType.isPrimitiveType() ? elseType : thenType;
36     } else {
37       // If both types are reference types, return the super type.
38       if (thenType.isSupertypeOrEquals(elseType) && !thenType.equals(TypeNode.NULL)) {
39         return thenType;
40       }
41       return elseType;
42     }
43   }
44 
45   @Override
accept(AstNodeVisitor visitor)46   public void accept(AstNodeVisitor visitor) {
47     visitor.visit(this);
48   }
49 
builder()50   public static Builder builder() {
51     return new AutoValue_TernaryExpr.Builder();
52   }
53 
54   @AutoValue.Builder
55   public abstract static class Builder {
setConditionExpr(Expr conditionExpr)56     public abstract Builder setConditionExpr(Expr conditionExpr);
57 
setThenExpr(Expr thenExpression)58     public abstract Builder setThenExpr(Expr thenExpression);
59 
setElseExpr(Expr elseExpression)60     public abstract Builder setElseExpr(Expr elseExpression);
61 
62     // Private accessors.
conditionExpr()63     abstract Expr conditionExpr();
64 
thenExpr()65     abstract Expr thenExpr();
66 
elseExpr()67     abstract Expr elseExpr();
68 
autoBuild()69     abstract TernaryExpr autoBuild();
70 
build()71     public TernaryExpr build() {
72       Preconditions.checkState(
73           conditionExpr().type().equals(TypeNode.BOOLEAN),
74           "Ternary condition must be a boolean-typed expression.");
75 
76       if (!thenExpr().type().equals(elseExpr().type())) {
77         Preconditions.checkState(
78             thenExpr().type().isSupertypeOrEquals(elseExpr().type())
79                 || elseExpr().type().isSupertypeOrEquals(thenExpr().type()),
80             "The second and third expressions must be assignable types of the other");
81       }
82       return autoBuild();
83     }
84   }
85 }
86