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 ReferenceConstructorExpr implements Expr {
26   public enum KeywordKind {
27     THIS,
28     SUPER
29   }
30 
31   @Override
type()32   public abstract TypeNode type();
33 
keywordKind()34   public abstract KeywordKind keywordKind();
35 
arguments()36   public abstract ImmutableList<Expr> arguments();
37 
38   @Override
accept(AstNodeVisitor visitor)39   public void accept(AstNodeVisitor visitor) {
40     visitor.visit(this);
41   }
42 
thisBuilder()43   public static Builder thisBuilder() {
44     return new AutoValue_ReferenceConstructorExpr.Builder()
45         .setArguments(Collections.emptyList())
46         .setKeywordKind(KeywordKind.THIS);
47   }
48 
superBuilder()49   public static Builder superBuilder() {
50     return new AutoValue_ReferenceConstructorExpr.Builder()
51         .setArguments(Collections.emptyList())
52         .setKeywordKind(KeywordKind.SUPER);
53   }
54 
55   @AutoValue.Builder
56   public abstract static class Builder {
setType(TypeNode node)57     public abstract Builder setType(TypeNode node);
58 
setArguments(Expr... arguments)59     public Builder setArguments(Expr... arguments) {
60       return setArguments(Arrays.asList(arguments));
61     }
62 
setArguments(List<Expr> arguments)63     public abstract Builder setArguments(List<Expr> arguments);
64 
65     // private.
setKeywordKind(KeywordKind keywordKind)66     abstract Builder setKeywordKind(KeywordKind keywordKind);
67 
type()68     abstract TypeNode type();
69 
arguments()70     abstract ImmutableList<Expr> arguments();
71 
autoBuild()72     abstract ReferenceConstructorExpr autoBuild();
73 
build()74     public ReferenceConstructorExpr build() {
75       ReferenceConstructorExpr referenceConstructorExpr = autoBuild();
76       Preconditions.checkState(
77           TypeNode.isReferenceType(referenceConstructorExpr.type()),
78           "A this/super constructor must have a reference type.");
79 
80       NodeValidator.checkNoNullElements(
81           arguments(), "the \"this\" or \"super\" initialization", type().reference().name());
82 
83       return referenceConstructorExpr;
84     }
85   }
86 }
87