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