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.collect.ImmutableList;
19 import java.util.Arrays;
20 import java.util.Collections;
21 import java.util.List;
22 import java.util.Objects;
23 import javax.annotation.Nullable;
24 
25 @AutoValue
26 public abstract class VaporReference implements Reference {
27   private static final String DOT = ".";
28   private static final String LEFT_ANGLE = "<";
29   private static final String RIGHT_ANGLE = ">";
30   private static final String COMMA = ", ";
31 
32   @Override
accept(AstNodeVisitor visitor)33   public void accept(AstNodeVisitor visitor) {
34     visitor.visit(this);
35   }
36 
37   @Override
generics()38   public abstract ImmutableList<Reference> generics();
39 
40   @Override
name()41   public abstract String name();
42 
43   @Override
simpleName()44   public abstract String simpleName();
45 
46   @Override
pakkage()47   public abstract String pakkage();
48 
49   @Override
useFullName()50   public abstract boolean useFullName();
51 
52   @Nullable
53   @Override
enclosingClassNames()54   public abstract ImmutableList<String> enclosingClassNames();
55 
56   @Nullable
supertypeReference()57   public abstract Reference supertypeReference();
58 
59   @Nullable
60   @Override
wildcardUpperBound()61   public Reference wildcardUpperBound() {
62     return null;
63   }
64 
65   @Override
fullName()66   public String fullName() {
67     if (hasEnclosingClass()) {
68       return String.format(
69           "%s.%s.%s", pakkage(), String.join(DOT, enclosingClassNames()), simpleName());
70     }
71     return String.format("%s.%s", pakkage(), simpleName());
72   }
73 
74   @Override
isStaticImport()75   public abstract boolean isStaticImport();
76 
77   @Override
hasEnclosingClass()78   public boolean hasEnclosingClass() {
79     return !enclosingClassNames().isEmpty();
80   }
81 
82   @Override
isFromPackage(String pkg)83   public boolean isFromPackage(String pkg) {
84     return pakkage().equals(pkg);
85   }
86 
87   @Override
isSupertypeOrEquals(Reference other)88   public boolean isSupertypeOrEquals(Reference other) {
89     // Not handling more complex cases for VaporReference.
90     if (!(other instanceof VaporReference)) {
91       return false;
92     }
93 
94     VaporReference ref = (VaporReference) other;
95     return pakkage().equals(ref.pakkage())
96         && simpleName().equals(ref.simpleName())
97         && Objects.equals(enclosingClassNames(), ref.enclosingClassNames());
98   }
99 
100   @Override
isAssignableFrom(Reference other)101   public boolean isAssignableFrom(Reference other) {
102     // Not handling this yet for VaporReference.
103     return false;
104   }
105 
106   @Override
isWildcard()107   public boolean isWildcard() {
108     return false;
109   }
110 
111   @Override
equals(Object o)112   public boolean equals(Object o) {
113     if (!(o instanceof VaporReference)) {
114       return false;
115     }
116 
117     VaporReference ref = (VaporReference) o;
118     return pakkage().equals(ref.pakkage())
119         && name().equals(ref.name())
120         && generics().equals(ref.generics())
121         && Objects.equals(enclosingClassNames(), ref.enclosingClassNames());
122   }
123 
124   @Override
hashCode()125   public int hashCode() {
126     int hash = 17 * pakkage().hashCode() + 19 * name().hashCode() + 23 * generics().hashCode();
127     if (!enclosingClassNames().isEmpty()) {
128       hash += 29 * enclosingClassNames().hashCode();
129     }
130     return hash;
131   }
132 
133   @Override
copyAndSetGenerics(List<Reference> generics)134   public Reference copyAndSetGenerics(List<Reference> generics) {
135     return toBuilder().setGenerics(generics).build();
136   }
137 
builder()138   public static Builder builder() {
139     return new AutoValue_VaporReference.Builder()
140         .setUseFullName(false)
141         .setGenerics(ImmutableList.of())
142         .setIsStaticImport(false)
143         .setEnclosingClassNames(Collections.emptyList());
144   }
145 
146   // Private.
toBuilder()147   abstract Builder toBuilder();
148 
149   @AutoValue.Builder
150   public abstract static class Builder {
setName(String name)151     public abstract Builder setName(String name);
152 
setPakkage(String pakkage)153     public abstract Builder setPakkage(String pakkage);
154 
setUseFullName(boolean useFullName)155     public abstract Builder setUseFullName(boolean useFullName);
156 
setGenerics(Reference... references)157     public Builder setGenerics(Reference... references) {
158       return setGenerics(Arrays.asList(references));
159     }
160 
setGenerics(List<Reference> clazzes)161     public abstract Builder setGenerics(List<Reference> clazzes);
162 
setEnclosingClassNames(String... enclosingClassNames)163     public Builder setEnclosingClassNames(String... enclosingClassNames) {
164       return setEnclosingClassNames(Arrays.asList(enclosingClassNames));
165     }
166 
setEnclosingClassNames(List<String> enclosingClassNames)167     public abstract Builder setEnclosingClassNames(List<String> enclosingClassNames);
168 
setIsStaticImport(boolean isStaticImport)169     public abstract Builder setIsStaticImport(boolean isStaticImport);
170 
setSupertypeReference(Reference supertypeReference)171     public abstract Builder setSupertypeReference(Reference supertypeReference);
172 
173     // Private.
setSimpleName(String simpleName)174     abstract Builder setSimpleName(String simpleName);
175 
name()176     abstract String name();
177 
generics()178     abstract ImmutableList<Reference> generics();
179 
enclosingClassNames()180     abstract ImmutableList<String> enclosingClassNames();
181 
isStaticImport()182     abstract boolean isStaticImport();
183 
autoBuild()184     abstract VaporReference autoBuild();
185 
build()186     public VaporReference build() {
187       String contextInfo = String.format("vapor reference %s", name());
188       NodeValidator.checkNoNullElements(generics(), "generics", contextInfo);
189       NodeValidator.checkNoNullElements(enclosingClassNames(), "enclosingClassNames", contextInfo);
190 
191       // Validate the name.
192       IdentifierNode.builder().setName(name()).build();
193       // No exception thrown, so we can proceed.
194 
195       setSimpleName(name());
196 
197       setIsStaticImport(!enclosingClassNames().isEmpty() && isStaticImport());
198 
199       StringBuilder sb = new StringBuilder();
200       if (!enclosingClassNames().isEmpty() && !isStaticImport()) {
201         sb.append(String.join(DOT, enclosingClassNames()));
202         sb.append(DOT);
203       }
204 
205       sb.append(name());
206       if (!generics().isEmpty()) {
207         sb.append(LEFT_ANGLE);
208         for (int i = 0; i < generics().size(); i++) {
209           Reference r = generics().get(i);
210           sb.append(r.name());
211           if (i < generics().size() - 1) {
212             sb.append(COMMA);
213           }
214         }
215         sb.append(RIGHT_ANGLE);
216       }
217       setName(sb.toString());
218 
219       return autoBuild();
220     }
221   }
222 }
223