1 /* 2 * Copyright (c) 2014, 2018, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26 package propertiesparser.parser; 27 28 /** 29 * Common interface to all kinds of diagnostic argument types. 30 */ 31 public interface MessageType { 32 33 /** 34 * Visitor method. 35 */ 36 <R, A> R accept(Visitor<R, A> v, A a); 37 38 /** 39 * The type as mentioned in the resource file. 40 */ 41 String kindName(); 42 43 /** 44 * A custom type is a type for which a predefined alternative does not exist. As such, it is an 45 * handy option when prototyping - but usages of custom types should be avoided in product-quality 46 * resource file comments. 47 * 48 * Example: 'com.sun.tools.javac.code.Flags.Flag' 49 */ 50 public static class CustomType implements MessageType { 51 52 /** The string-based representation of this type. */ 53 public String typeString; 54 55 public CustomType(String typeString) { 56 this.typeString = typeString; 57 } 58 59 @Override 60 public String kindName() { 61 return typeString; 62 } 63 64 @Override 65 public <R, A> R accept(Visitor<R, A> v, A a) { 66 return v.visitCustomType(this, a); 67 } 68 } 69 70 /** 71 * A predefined type. All common types mentioned in the resource file comments are meant to 72 * be included here. 73 */ 74 public enum SimpleType implements MessageType { 75 76 ANNOTATION("annotation", "Compound", "com.sun.tools.javac.code.Attribute"), 77 BOOLEAN("boolean", "boolean", null), 78 COLLECTION("collection", "Collection", "java.util"), 79 FLAG("flag", "Flag", "com.sun.tools.javac.code.Flags"), 80 FRAGMENT("fragment", "Fragment", null), 81 DIAGNOSTIC("diagnostic", "JCDiagnostic", "com.sun.tools.javac.util"), 82 MODIFIER("modifier", "Modifier", "javax.lang.model.element"), 83 FILE("file", "File", "java.io"), 84 FILE_OBJECT("file object", "JavaFileObject", "javax.tools"), 85 PATH("path", "Path", "java.nio.file"), 86 NAME("name", "Name", "com.sun.tools.javac.util"), 87 NUMBER("number", "int", null), 88 OPTION_NAME("option name", "Option", "com.sun.tools.javac.main"), 89 PROFILE("profile", "Profile", "com.sun.tools.javac.jvm"), 90 SOURCE("source", "Source", "com.sun.tools.javac.code"), 91 SOURCE_VERSION("source version", "SourceVersion", "javax.lang.model"), 92 STRING("string", "String", null), 93 SYMBOL("symbol", "Symbol", "com.sun.tools.javac.code"), 94 SYMBOL_KIND("symbol kind", "Kind", "com.sun.tools.javac.code.Kinds"), 95 KIND_NAME("kind name", "KindName", "com.sun.tools.javac.code.Kinds"), 96 TARGET("target", "Target", "com.sun.tools.javac.jvm"), 97 TOKEN("token", "TokenKind", "com.sun.tools.javac.parser.Tokens"), 98 TYPE("type", "Type", "com.sun.tools.javac.code"), 99 URL("url", "URL", "java.net"), 100 SET("set", "Set", "java.util"), 101 LIST("list", "List", "java.util"), 102 OBJECT("object", "Object", null), 103 UNUSED("unused", "Void", null), 104 UNKNOWN("<unknown>", "UnknownType", null); 105 106 /** name of the predefined type as mentioned in the resource file. */ 107 public final String kindName; 108 109 /** string-based representation of the type */ 110 public final String clazz; 111 112 /** type qualifier (might be null) */ 113 public final String qualifier; 114 115 SimpleType(String kindName, String clazz, String qualifier) { 116 this.kindName = kindName; 117 this.clazz = clazz; 118 this.qualifier = qualifier; 119 } 120 121 @Override 122 public String kindName() { 123 return kindName; 124 } 125 126 @Override 127 public <R, A> R accept(Visitor<R, A> v, A a) { 128 return v.visitSimpleType(this, a); 129 } 130 } 131 132 /** 133 * A compound type is a collection of some element type. 134 * 135 * Example: list of string 136 */ 137 public static class CompoundType implements MessageType { 138 139 /** 140 * Compound type kind. 141 */ 142 public enum Kind { 143 COLLECTION("collection of", SimpleType.COLLECTION), 144 LIST("list of", SimpleType.LIST), 145 SET("set of", SimpleType.SET); 146 147 public final String kindName; 148 public final SimpleType clazz; 149 150 Kind(String kindName, SimpleType clazz) { 151 this.kindName = kindName; 152 this.clazz = clazz; 153 } 154 } 155 156 /** The compound type kind. */ 157 public final Kind kind; 158 159 /** The element type. */ 160 public final MessageType elemtype; 161 162 public CompoundType(Kind kind, MessageType elemtype) { 163 this.kind = kind; 164 this.elemtype = elemtype; 165 } 166 167 @Override 168 public String kindName() { 169 return kind.kindName; 170 } 171 172 @Override 173 public <R, A> R accept(Visitor<R, A> v, A a) { 174 return v.visitCompoundType(this, a); 175 } 176 } 177 178 /** 179 * A union type represents an alternative between two (or more) types. It can be useful to 180 * define the type of an argument which can assume multiple (unrelated) values; union types 181 * are only meant to be used in cases where the alternative comes up frequently enough in the 182 * resource file comments - in order to avoid cluttered comments. 183 * 184 * Example: message segment 185 */ 186 public static class UnionType implements MessageType { 187 188 /** 189 * Union type kind. 190 */ 191 public enum Kind { 192 MESSAGE_SEGMENT("message segment", SimpleType.DIAGNOSTIC, SimpleType.FRAGMENT), 193 FILE_NAME("file name", SimpleType.FILE, SimpleType.FILE_OBJECT, SimpleType.PATH); 194 195 final String kindName; 196 final SimpleType[] choices; 197 198 Kind(String kindName, SimpleType... choices) { 199 this.kindName = kindName; 200 this.choices = choices; 201 } 202 } 203 204 /** The union type kind. */ 205 public final Kind kind; 206 207 /** The union type alternatives. */ 208 public final MessageType[] choices; 209 210 UnionType(Kind kind) { 211 this(kind, kind.choices); 212 } 213 214 protected UnionType(Kind kind, MessageType[] choices) { 215 this.choices = choices; 216 this.kind = kind; 217 } 218 219 @Override 220 public String kindName() { 221 return kind.kindName; 222 } 223 224 @Override 225 public <R, A> R accept(Visitor<R, A> v, A a) { 226 return v.visitUnionType(this, a); 227 } 228 } 229 230 /** 231 * A subclass of union type representing 'explicit' alternatives in the resource file comments. 232 * Note: as the token 'or' is parsed with lowest priority, it is not possible, for instance, 233 * to form a compound type out of an 'or' type. In such cases a plain union type should be used 234 * instead. 235 * 236 * Examples: symbol or type 237 */ 238 public static class OrType extends UnionType { 239 240 public static final String OR_NAME = "or"; 241 242 @Override 243 public String kindName() { 244 return OR_NAME; 245 } 246 247 public OrType(MessageType... choices) { 248 super(null, choices); 249 } 250 } 251 252 /** 253 * Visitor class. 254 */ 255 public static abstract class Visitor<R, A> { 256 public abstract R visitCustomType(CustomType t, A a); 257 public abstract R visitSimpleType(SimpleType t, A a); 258 public abstract R visitCompoundType(CompoundType t, A a); 259 public abstract R visitUnionType(UnionType t, A a); 260 } 261 }