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 import com.google.common.collect.ImmutableList;
20 import java.util.Arrays;
21 import java.util.Collections;
22 import java.util.List;
23 
24 @AutoValue
25 public abstract class NewObjectExpr implements Expr {
26   @Override
type()27   public abstract TypeNode type();
28 
arguments()29   public abstract ImmutableList<Expr> arguments();
30 
isGeneric()31   public abstract boolean isGeneric();
32 
33   @Override
accept(AstNodeVisitor visitor)34   public void accept(AstNodeVisitor visitor) {
35     visitor.visit(this);
36   }
37 
withType(TypeNode type)38   public static NewObjectExpr withType(TypeNode type) {
39     return builder().setType(type).build();
40   }
41 
builder()42   public static Builder builder() {
43     return new AutoValue_NewObjectExpr.Builder()
44         .setArguments(Collections.emptyList())
45         .setIsGeneric(false);
46   }
47 
48   @AutoValue.Builder
49   public abstract static class Builder {
setType(TypeNode type)50     public abstract Builder setType(TypeNode type);
51 
setArguments(Expr... arguments)52     public Builder setArguments(Expr... arguments) {
53       return setArguments(Arrays.asList(arguments));
54     }
55 
setArguments(List<Expr> arguments)56     public abstract Builder setArguments(List<Expr> arguments);
57 
setIsGeneric(boolean isGeneric)58     public abstract Builder setIsGeneric(boolean isGeneric);
59 
60     // Private accessors.
type()61     abstract TypeNode type();
62 
isGeneric()63     abstract boolean isGeneric();
64 
arguments()65     abstract ImmutableList<Expr> arguments();
66 
autoBuild()67     abstract NewObjectExpr autoBuild();
68 
build()69     public NewObjectExpr build() {
70       Preconditions.checkState(
71           TypeNode.isReferenceType(type()), "New object expression should be reference types.");
72 
73       NodeValidator.checkNoNullElements(
74           arguments(), "the \"new\" constructor", type().reference().name());
75 
76       // Only the case where generics() is empty and isGeneric() is false, we set isGeneric() to
77       // false. Otherwise, isGeneric() should be true.
78       setIsGeneric(isGeneric() || !type().reference().generics().isEmpty());
79       return autoBuild();
80     }
81   }
82 }
83