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 }