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      */
accept(Visitor<R, A> v, A a)36     <R, A> R accept(Visitor<R, A> v, A a);
37 
38     /**
39      * The type as mentioned in the resource file.
40      */
kindName()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 
CustomType(String typeString)55         public CustomType(String typeString) {
56             this.typeString = typeString;
57         }
58 
59         @Override
kindName()60         public String kindName() {
61             return typeString;
62         }
63 
64         @Override
accept(Visitor<R, A> v, A a)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         TREE_TAG("tree tag", "Tag", "com.sun.tools.javac.tree.JCTree"),
99         TYPE("type", "Type", "com.sun.tools.javac.code"),
100         URL("url", "URL", "java.net"),
101         SET("set", "Set", "java.util"),
102         LIST("list", "List", "java.util"),
103         OBJECT("object", "Object", null),
104         UNUSED("unused", "Void", null),
105         UNKNOWN("<unknown>", "UnknownType", null);
106 
107         /** name of the predefined type as mentioned in the resource file. */
108         public final String kindName;
109 
110         /** string-based representation of the type */
111         public final String clazz;
112 
113         /** type qualifier (might be null) */
114         public final String qualifier;
115 
SimpleType(String kindName, String clazz, String qualifier)116         SimpleType(String kindName, String clazz, String qualifier) {
117             this.kindName = kindName;
118             this.clazz = clazz;
119             this.qualifier = qualifier;
120         }
121 
122         @Override
kindName()123         public String kindName() {
124             return kindName;
125         }
126 
127         @Override
accept(Visitor<R, A> v, A a)128         public <R, A> R accept(Visitor<R, A> v, A a) {
129             return v.visitSimpleType(this, a);
130         }
131     }
132 
133     /**
134      * A compound type is a collection of some element type.
135      *
136      * Example: list of string
137      */
138     public static class CompoundType implements MessageType {
139 
140         /**
141          * Compound type kind.
142          */
143         public enum Kind {
144             COLLECTION("collection of", SimpleType.COLLECTION),
145             LIST("list of", SimpleType.LIST),
146             SET("set of", SimpleType.SET);
147 
148             public final String kindName;
149             public final SimpleType clazz;
150 
Kind(String kindName, SimpleType clazz)151             Kind(String kindName, SimpleType clazz) {
152                 this.kindName = kindName;
153                 this.clazz = clazz;
154             }
155         }
156 
157         /** The compound type kind. */
158         public final Kind kind;
159 
160         /** The element type. */
161         public final MessageType elemtype;
162 
CompoundType(Kind kind, MessageType elemtype)163         public CompoundType(Kind kind, MessageType elemtype) {
164             this.kind = kind;
165             this.elemtype = elemtype;
166         }
167 
168         @Override
kindName()169         public String kindName() {
170             return kind.kindName;
171         }
172 
173         @Override
accept(Visitor<R, A> v, A a)174         public <R, A> R accept(Visitor<R, A> v, A a) {
175             return v.visitCompoundType(this, a);
176         }
177     }
178 
179     /**
180      * A union type represents an alternative between two (or more) types. It can be useful to
181      * define the type of an argument which can assume multiple (unrelated) values; union types
182      * are only meant to be used in cases where the alternative comes up frequently enough in the
183      * resource file comments - in order to avoid cluttered comments.
184      *
185      * Example: message segment
186      */
187     public static class UnionType implements MessageType {
188 
189         /**
190          * Union type kind.
191          */
192         public enum Kind {
193             MESSAGE_SEGMENT("message segment", SimpleType.DIAGNOSTIC, SimpleType.FRAGMENT),
194             FILE_NAME("file name", SimpleType.FILE, SimpleType.FILE_OBJECT, SimpleType.PATH);
195 
196             final String kindName;
197             final SimpleType[] choices;
198 
Kind(String kindName, SimpleType... choices)199             Kind(String kindName, SimpleType... choices) {
200                 this.kindName = kindName;
201                 this.choices = choices;
202             }
203         }
204 
205         /** The union type kind. */
206         public final Kind kind;
207 
208         /** The union type alternatives. */
209         public final MessageType[] choices;
210 
UnionType(Kind kind)211         UnionType(Kind kind) {
212             this(kind, kind.choices);
213         }
214 
UnionType(Kind kind, MessageType[] choices)215         protected UnionType(Kind kind, MessageType[] choices) {
216             this.choices = choices;
217             this.kind = kind;
218         }
219 
220         @Override
kindName()221         public String kindName() {
222             return kind.kindName;
223         }
224 
225         @Override
accept(Visitor<R, A> v, A a)226         public <R, A> R accept(Visitor<R, A> v, A a) {
227             return v.visitUnionType(this, a);
228         }
229     }
230 
231     /**
232      * A subclass of union type representing 'explicit' alternatives in the resource file comments.
233      * Note: as the token 'or' is parsed with lowest priority, it is not possible, for instance,
234      * to form a compound type out of an 'or' type. In such cases a plain union type should be used
235      * instead.
236      *
237      * Examples: symbol or type
238      */
239     public static class OrType extends UnionType {
240 
241         public static final String OR_NAME = "or";
242 
243         @Override
kindName()244         public String kindName() {
245             return OR_NAME;
246         }
247 
OrType(MessageType... choices)248         public OrType(MessageType... choices) {
249             super(null, choices);
250         }
251     }
252 
253     /**
254      * Visitor class.
255      */
256     public static abstract class Visitor<R, A> {
visitCustomType(CustomType t, A a)257         public abstract R visitCustomType(CustomType t, A a);
visitSimpleType(SimpleType t, A a)258         public abstract R visitSimpleType(SimpleType t, A a);
visitCompoundType(CompoundType t, A a)259         public abstract R visitCompoundType(CompoundType t, A a);
visitUnionType(UnionType t, A a)260         public abstract R visitUnionType(UnionType t, A a);
261     }
262 }
263