langtools/make/tools/propertiesparser/gen/ClassGenerator.java
author jlahoda
Mon, 02 Feb 2015 21:53:36 +0100
changeset 28801 2f1c998c3fcc
parent 28588 16eda7aedf89
permissions -rw-r--r--
8072054: Cannot build langtools if checked-out in a directory ending with \"com\" Summary: Making sure a proper package name is used when generating Properties classes Reviewed-by: mcimadamore
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
28588
16eda7aedf89 8069229: new .java file with no copyright notice
mcimadamore
parents: 28334
diff changeset
     1
/*
16eda7aedf89 8069229: new .java file with no copyright notice
mcimadamore
parents: 28334
diff changeset
     2
 * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
16eda7aedf89 8069229: new .java file with no copyright notice
mcimadamore
parents: 28334
diff changeset
     3
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
16eda7aedf89 8069229: new .java file with no copyright notice
mcimadamore
parents: 28334
diff changeset
     4
 *
16eda7aedf89 8069229: new .java file with no copyright notice
mcimadamore
parents: 28334
diff changeset
     5
 * This code is free software; you can redistribute it and/or modify it
16eda7aedf89 8069229: new .java file with no copyright notice
mcimadamore
parents: 28334
diff changeset
     6
 * under the terms of the GNU General Public License version 2 only, as
16eda7aedf89 8069229: new .java file with no copyright notice
mcimadamore
parents: 28334
diff changeset
     7
 * published by the Free Software Foundation.
16eda7aedf89 8069229: new .java file with no copyright notice
mcimadamore
parents: 28334
diff changeset
     8
 *
16eda7aedf89 8069229: new .java file with no copyright notice
mcimadamore
parents: 28334
diff changeset
     9
 * This code is distributed in the hope that it will be useful, but WITHOUT
16eda7aedf89 8069229: new .java file with no copyright notice
mcimadamore
parents: 28334
diff changeset
    10
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
16eda7aedf89 8069229: new .java file with no copyright notice
mcimadamore
parents: 28334
diff changeset
    11
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
16eda7aedf89 8069229: new .java file with no copyright notice
mcimadamore
parents: 28334
diff changeset
    12
 * version 2 for more details (a copy is included in the LICENSE file that
16eda7aedf89 8069229: new .java file with no copyright notice
mcimadamore
parents: 28334
diff changeset
    13
 * accompanied this code).
16eda7aedf89 8069229: new .java file with no copyright notice
mcimadamore
parents: 28334
diff changeset
    14
 *
16eda7aedf89 8069229: new .java file with no copyright notice
mcimadamore
parents: 28334
diff changeset
    15
 * You should have received a copy of the GNU General Public License version
16eda7aedf89 8069229: new .java file with no copyright notice
mcimadamore
parents: 28334
diff changeset
    16
 * 2 along with this work; if not, write to the Free Software Foundation,
16eda7aedf89 8069229: new .java file with no copyright notice
mcimadamore
parents: 28334
diff changeset
    17
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
16eda7aedf89 8069229: new .java file with no copyright notice
mcimadamore
parents: 28334
diff changeset
    18
 *
16eda7aedf89 8069229: new .java file with no copyright notice
mcimadamore
parents: 28334
diff changeset
    19
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
16eda7aedf89 8069229: new .java file with no copyright notice
mcimadamore
parents: 28334
diff changeset
    20
 * or visit www.oracle.com if you need additional information or have any
16eda7aedf89 8069229: new .java file with no copyright notice
mcimadamore
parents: 28334
diff changeset
    21
 * questions.
16eda7aedf89 8069229: new .java file with no copyright notice
mcimadamore
parents: 28334
diff changeset
    22
 */
16eda7aedf89 8069229: new .java file with no copyright notice
mcimadamore
parents: 28334
diff changeset
    23
28334
1633de6070ae 8058542: Devise scheme for better diagnostic creation
mcimadamore
parents:
diff changeset
    24
package propertiesparser.gen;
1633de6070ae 8058542: Devise scheme for better diagnostic creation
mcimadamore
parents:
diff changeset
    25
1633de6070ae 8058542: Devise scheme for better diagnostic creation
mcimadamore
parents:
diff changeset
    26
import propertiesparser.parser.Message;
1633de6070ae 8058542: Devise scheme for better diagnostic creation
mcimadamore
parents:
diff changeset
    27
import propertiesparser.parser.MessageFile;
1633de6070ae 8058542: Devise scheme for better diagnostic creation
mcimadamore
parents:
diff changeset
    28
import propertiesparser.parser.MessageInfo;
1633de6070ae 8058542: Devise scheme for better diagnostic creation
mcimadamore
parents:
diff changeset
    29
import propertiesparser.parser.MessageLine;
1633de6070ae 8058542: Devise scheme for better diagnostic creation
mcimadamore
parents:
diff changeset
    30
import propertiesparser.parser.MessageType;
1633de6070ae 8058542: Devise scheme for better diagnostic creation
mcimadamore
parents:
diff changeset
    31
import propertiesparser.parser.MessageType.CompoundType;
1633de6070ae 8058542: Devise scheme for better diagnostic creation
mcimadamore
parents:
diff changeset
    32
import propertiesparser.parser.MessageType.CustomType;
1633de6070ae 8058542: Devise scheme for better diagnostic creation
mcimadamore
parents:
diff changeset
    33
import propertiesparser.parser.MessageType.SimpleType;
1633de6070ae 8058542: Devise scheme for better diagnostic creation
mcimadamore
parents:
diff changeset
    34
import propertiesparser.parser.MessageType.UnionType;
1633de6070ae 8058542: Devise scheme for better diagnostic creation
mcimadamore
parents:
diff changeset
    35
import propertiesparser.parser.MessageType.Visitor;
1633de6070ae 8058542: Devise scheme for better diagnostic creation
mcimadamore
parents:
diff changeset
    36
1633de6070ae 8058542: Devise scheme for better diagnostic creation
mcimadamore
parents:
diff changeset
    37
import java.io.File;
1633de6070ae 8058542: Devise scheme for better diagnostic creation
mcimadamore
parents:
diff changeset
    38
import java.io.FileWriter;
1633de6070ae 8058542: Devise scheme for better diagnostic creation
mcimadamore
parents:
diff changeset
    39
import java.io.IOException;
1633de6070ae 8058542: Devise scheme for better diagnostic creation
mcimadamore
parents:
diff changeset
    40
import java.io.InputStream;
1633de6070ae 8058542: Devise scheme for better diagnostic creation
mcimadamore
parents:
diff changeset
    41
import java.text.MessageFormat;
1633de6070ae 8058542: Devise scheme for better diagnostic creation
mcimadamore
parents:
diff changeset
    42
import java.util.ArrayList;
1633de6070ae 8058542: Devise scheme for better diagnostic creation
mcimadamore
parents:
diff changeset
    43
import java.util.Arrays;
1633de6070ae 8058542: Devise scheme for better diagnostic creation
mcimadamore
parents:
diff changeset
    44
import java.util.Collections;
1633de6070ae 8058542: Devise scheme for better diagnostic creation
mcimadamore
parents:
diff changeset
    45
import java.util.TreeSet;
1633de6070ae 8058542: Devise scheme for better diagnostic creation
mcimadamore
parents:
diff changeset
    46
import java.util.List;
1633de6070ae 8058542: Devise scheme for better diagnostic creation
mcimadamore
parents:
diff changeset
    47
import java.util.Map;
1633de6070ae 8058542: Devise scheme for better diagnostic creation
mcimadamore
parents:
diff changeset
    48
import java.util.Set;
1633de6070ae 8058542: Devise scheme for better diagnostic creation
mcimadamore
parents:
diff changeset
    49
import java.util.Properties;
1633de6070ae 8058542: Devise scheme for better diagnostic creation
mcimadamore
parents:
diff changeset
    50
import java.util.stream.Collectors;
1633de6070ae 8058542: Devise scheme for better diagnostic creation
mcimadamore
parents:
diff changeset
    51
import java.util.stream.Stream;
1633de6070ae 8058542: Devise scheme for better diagnostic creation
mcimadamore
parents:
diff changeset
    52
1633de6070ae 8058542: Devise scheme for better diagnostic creation
mcimadamore
parents:
diff changeset
    53
public class ClassGenerator {
1633de6070ae 8058542: Devise scheme for better diagnostic creation
mcimadamore
parents:
diff changeset
    54
1633de6070ae 8058542: Devise scheme for better diagnostic creation
mcimadamore
parents:
diff changeset
    55
    /** Empty string - used to generate indentation padding. */
1633de6070ae 8058542: Devise scheme for better diagnostic creation
mcimadamore
parents:
diff changeset
    56
    private final static String INDENT_STRING = "                                                                   ";
1633de6070ae 8058542: Devise scheme for better diagnostic creation
mcimadamore
parents:
diff changeset
    57
1633de6070ae 8058542: Devise scheme for better diagnostic creation
mcimadamore
parents:
diff changeset
    58
    /** Default indentation step. */
1633de6070ae 8058542: Devise scheme for better diagnostic creation
mcimadamore
parents:
diff changeset
    59
    private final static int INDENT_WIDTH = 4;
1633de6070ae 8058542: Devise scheme for better diagnostic creation
mcimadamore
parents:
diff changeset
    60
1633de6070ae 8058542: Devise scheme for better diagnostic creation
mcimadamore
parents:
diff changeset
    61
    /** File-backed property file containing basic code stubs. */
1633de6070ae 8058542: Devise scheme for better diagnostic creation
mcimadamore
parents:
diff changeset
    62
    static Properties stubs;
1633de6070ae 8058542: Devise scheme for better diagnostic creation
mcimadamore
parents:
diff changeset
    63
1633de6070ae 8058542: Devise scheme for better diagnostic creation
mcimadamore
parents:
diff changeset
    64
    static {
1633de6070ae 8058542: Devise scheme for better diagnostic creation
mcimadamore
parents:
diff changeset
    65
        //init properties from file
1633de6070ae 8058542: Devise scheme for better diagnostic creation
mcimadamore
parents:
diff changeset
    66
        stubs = new Properties();
1633de6070ae 8058542: Devise scheme for better diagnostic creation
mcimadamore
parents:
diff changeset
    67
        String resourcePath = "/propertiesparser/resources/templates.properties";
1633de6070ae 8058542: Devise scheme for better diagnostic creation
mcimadamore
parents:
diff changeset
    68
        try (InputStream in = ClassGenerator.class.getResourceAsStream(resourcePath)) {
1633de6070ae 8058542: Devise scheme for better diagnostic creation
mcimadamore
parents:
diff changeset
    69
            stubs.load(in);
1633de6070ae 8058542: Devise scheme for better diagnostic creation
mcimadamore
parents:
diff changeset
    70
        } catch (IOException ex) {
1633de6070ae 8058542: Devise scheme for better diagnostic creation
mcimadamore
parents:
diff changeset
    71
            throw new AssertionError(ex);
1633de6070ae 8058542: Devise scheme for better diagnostic creation
mcimadamore
parents:
diff changeset
    72
        }
1633de6070ae 8058542: Devise scheme for better diagnostic creation
mcimadamore
parents:
diff changeset
    73
    }
1633de6070ae 8058542: Devise scheme for better diagnostic creation
mcimadamore
parents:
diff changeset
    74
1633de6070ae 8058542: Devise scheme for better diagnostic creation
mcimadamore
parents:
diff changeset
    75
    /**
1633de6070ae 8058542: Devise scheme for better diagnostic creation
mcimadamore
parents:
diff changeset
    76
     * Supported stubs in the property file.
1633de6070ae 8058542: Devise scheme for better diagnostic creation
mcimadamore
parents:
diff changeset
    77
     */
1633de6070ae 8058542: Devise scheme for better diagnostic creation
mcimadamore
parents:
diff changeset
    78
    enum StubKind {
1633de6070ae 8058542: Devise scheme for better diagnostic creation
mcimadamore
parents:
diff changeset
    79
        TOPLEVEL("toplevel.decl"),
1633de6070ae 8058542: Devise scheme for better diagnostic creation
mcimadamore
parents:
diff changeset
    80
        FACTORY_CLASS("nested.decl"),
1633de6070ae 8058542: Devise scheme for better diagnostic creation
mcimadamore
parents:
diff changeset
    81
        IMPORT("import.decl"),
1633de6070ae 8058542: Devise scheme for better diagnostic creation
mcimadamore
parents:
diff changeset
    82
        FACTORY_METHOD_DECL("factory.decl.method"),
1633de6070ae 8058542: Devise scheme for better diagnostic creation
mcimadamore
parents:
diff changeset
    83
        FACTORY_METHOD_ARG("factory.decl.method.arg"),
1633de6070ae 8058542: Devise scheme for better diagnostic creation
mcimadamore
parents:
diff changeset
    84
        FACTORY_METHOD_BODY("factory.decl.method.body"),
1633de6070ae 8058542: Devise scheme for better diagnostic creation
mcimadamore
parents:
diff changeset
    85
        FACTORY_FIELD("factory.decl.field"),
1633de6070ae 8058542: Devise scheme for better diagnostic creation
mcimadamore
parents:
diff changeset
    86
        WILDCARDS_EXTENDS("wildcards.extends"),
1633de6070ae 8058542: Devise scheme for better diagnostic creation
mcimadamore
parents:
diff changeset
    87
        SUPPRESS_WARNINGS("suppress.warnings");
1633de6070ae 8058542: Devise scheme for better diagnostic creation
mcimadamore
parents:
diff changeset
    88
1633de6070ae 8058542: Devise scheme for better diagnostic creation
mcimadamore
parents:
diff changeset
    89
        /** stub key (as it appears in the property file) */
1633de6070ae 8058542: Devise scheme for better diagnostic creation
mcimadamore
parents:
diff changeset
    90
        String key;
1633de6070ae 8058542: Devise scheme for better diagnostic creation
mcimadamore
parents:
diff changeset
    91
1633de6070ae 8058542: Devise scheme for better diagnostic creation
mcimadamore
parents:
diff changeset
    92
        StubKind(String key) {
1633de6070ae 8058542: Devise scheme for better diagnostic creation
mcimadamore
parents:
diff changeset
    93
            this.key = key;
1633de6070ae 8058542: Devise scheme for better diagnostic creation
mcimadamore
parents:
diff changeset
    94
        }
1633de6070ae 8058542: Devise scheme for better diagnostic creation
mcimadamore
parents:
diff changeset
    95
1633de6070ae 8058542: Devise scheme for better diagnostic creation
mcimadamore
parents:
diff changeset
    96
        /**
1633de6070ae 8058542: Devise scheme for better diagnostic creation
mcimadamore
parents:
diff changeset
    97
         * Subst a list of arguments into a given stub.
1633de6070ae 8058542: Devise scheme for better diagnostic creation
mcimadamore
parents:
diff changeset
    98
         */
1633de6070ae 8058542: Devise scheme for better diagnostic creation
mcimadamore
parents:
diff changeset
    99
        String format(Object... args) {
1633de6070ae 8058542: Devise scheme for better diagnostic creation
mcimadamore
parents:
diff changeset
   100
            return MessageFormat.format((String)stubs.get(key), args);
1633de6070ae 8058542: Devise scheme for better diagnostic creation
mcimadamore
parents:
diff changeset
   101
        }
1633de6070ae 8058542: Devise scheme for better diagnostic creation
mcimadamore
parents:
diff changeset
   102
    }
1633de6070ae 8058542: Devise scheme for better diagnostic creation
mcimadamore
parents:
diff changeset
   103
1633de6070ae 8058542: Devise scheme for better diagnostic creation
mcimadamore
parents:
diff changeset
   104
    /**
1633de6070ae 8058542: Devise scheme for better diagnostic creation
mcimadamore
parents:
diff changeset
   105
     * Nested factory class kind. There are multiple sub-factories, one for each kind of commonly used
1633de6070ae 8058542: Devise scheme for better diagnostic creation
mcimadamore
parents:
diff changeset
   106
     * diagnostics (i.e. error, warnings, note, fragment). An additional category is defined for
1633de6070ae 8058542: Devise scheme for better diagnostic creation
mcimadamore
parents:
diff changeset
   107
     * those resource keys whose prefix doesn't match any predefined category.
1633de6070ae 8058542: Devise scheme for better diagnostic creation
mcimadamore
parents:
diff changeset
   108
     */
1633de6070ae 8058542: Devise scheme for better diagnostic creation
mcimadamore
parents:
diff changeset
   109
    enum FactoryKind {
1633de6070ae 8058542: Devise scheme for better diagnostic creation
mcimadamore
parents:
diff changeset
   110
        ERR("err", "Error", "Errors"),
1633de6070ae 8058542: Devise scheme for better diagnostic creation
mcimadamore
parents:
diff changeset
   111
        WARN("warn", "Warning", "Warnings"),
1633de6070ae 8058542: Devise scheme for better diagnostic creation
mcimadamore
parents:
diff changeset
   112
        NOTE("note", "Note", "Notes"),
1633de6070ae 8058542: Devise scheme for better diagnostic creation
mcimadamore
parents:
diff changeset
   113
        MISC("misc", "Fragment", "Fragments"),
1633de6070ae 8058542: Devise scheme for better diagnostic creation
mcimadamore
parents:
diff changeset
   114
        OTHER(null, null, null);
1633de6070ae 8058542: Devise scheme for better diagnostic creation
mcimadamore
parents:
diff changeset
   115
1633de6070ae 8058542: Devise scheme for better diagnostic creation
mcimadamore
parents:
diff changeset
   116
        /** The prefix for this factory kind (i.e. 'err'). */
1633de6070ae 8058542: Devise scheme for better diagnostic creation
mcimadamore
parents:
diff changeset
   117
        String prefix;
1633de6070ae 8058542: Devise scheme for better diagnostic creation
mcimadamore
parents:
diff changeset
   118
1633de6070ae 8058542: Devise scheme for better diagnostic creation
mcimadamore
parents:
diff changeset
   119
        /** The type of the factory method/fields in this class. */
1633de6070ae 8058542: Devise scheme for better diagnostic creation
mcimadamore
parents:
diff changeset
   120
        String keyClazz;
1633de6070ae 8058542: Devise scheme for better diagnostic creation
mcimadamore
parents:
diff changeset
   121
1633de6070ae 8058542: Devise scheme for better diagnostic creation
mcimadamore
parents:
diff changeset
   122
        /** The class name to be used for this factory. */
1633de6070ae 8058542: Devise scheme for better diagnostic creation
mcimadamore
parents:
diff changeset
   123
        String factoryClazz;
1633de6070ae 8058542: Devise scheme for better diagnostic creation
mcimadamore
parents:
diff changeset
   124
1633de6070ae 8058542: Devise scheme for better diagnostic creation
mcimadamore
parents:
diff changeset
   125
        FactoryKind(String prefix, String keyClazz, String factoryClazz) {
1633de6070ae 8058542: Devise scheme for better diagnostic creation
mcimadamore
parents:
diff changeset
   126
            this.prefix = prefix;
1633de6070ae 8058542: Devise scheme for better diagnostic creation
mcimadamore
parents:
diff changeset
   127
            this.keyClazz = keyClazz;
1633de6070ae 8058542: Devise scheme for better diagnostic creation
mcimadamore
parents:
diff changeset
   128
            this.factoryClazz = factoryClazz;
1633de6070ae 8058542: Devise scheme for better diagnostic creation
mcimadamore
parents:
diff changeset
   129
        }
1633de6070ae 8058542: Devise scheme for better diagnostic creation
mcimadamore
parents:
diff changeset
   130
1633de6070ae 8058542: Devise scheme for better diagnostic creation
mcimadamore
parents:
diff changeset
   131
        /**
1633de6070ae 8058542: Devise scheme for better diagnostic creation
mcimadamore
parents:
diff changeset
   132
         * Utility method for parsing a factory kind from a resource key prefix.
1633de6070ae 8058542: Devise scheme for better diagnostic creation
mcimadamore
parents:
diff changeset
   133
         */
1633de6070ae 8058542: Devise scheme for better diagnostic creation
mcimadamore
parents:
diff changeset
   134
        static FactoryKind parseFrom(String prefix) {
1633de6070ae 8058542: Devise scheme for better diagnostic creation
mcimadamore
parents:
diff changeset
   135
            for (FactoryKind k : FactoryKind.values()) {
1633de6070ae 8058542: Devise scheme for better diagnostic creation
mcimadamore
parents:
diff changeset
   136
                if (k.prefix == null || k.prefix.equals(prefix)) {
1633de6070ae 8058542: Devise scheme for better diagnostic creation
mcimadamore
parents:
diff changeset
   137
                    return k;
1633de6070ae 8058542: Devise scheme for better diagnostic creation
mcimadamore
parents:
diff changeset
   138
                }
1633de6070ae 8058542: Devise scheme for better diagnostic creation
mcimadamore
parents:
diff changeset
   139
            }
1633de6070ae 8058542: Devise scheme for better diagnostic creation
mcimadamore
parents:
diff changeset
   140
            return null;
1633de6070ae 8058542: Devise scheme for better diagnostic creation
mcimadamore
parents:
diff changeset
   141
        }
1633de6070ae 8058542: Devise scheme for better diagnostic creation
mcimadamore
parents:
diff changeset
   142
    }
1633de6070ae 8058542: Devise scheme for better diagnostic creation
mcimadamore
parents:
diff changeset
   143
1633de6070ae 8058542: Devise scheme for better diagnostic creation
mcimadamore
parents:
diff changeset
   144
    /**
1633de6070ae 8058542: Devise scheme for better diagnostic creation
mcimadamore
parents:
diff changeset
   145
     * Main entry-point: generate a Java enum-like set of nested factory classes into given output
1633de6070ae 8058542: Devise scheme for better diagnostic creation
mcimadamore
parents:
diff changeset
   146
     * folder. The factories are populated as mandated by the comments in the input resource file.
1633de6070ae 8058542: Devise scheme for better diagnostic creation
mcimadamore
parents:
diff changeset
   147
     */
1633de6070ae 8058542: Devise scheme for better diagnostic creation
mcimadamore
parents:
diff changeset
   148
    public void generateFactory(MessageFile messageFile, File outDir) {
1633de6070ae 8058542: Devise scheme for better diagnostic creation
mcimadamore
parents:
diff changeset
   149
        Map<FactoryKind, List<Map.Entry<String, Message>>> groupedEntries =
1633de6070ae 8058542: Devise scheme for better diagnostic creation
mcimadamore
parents:
diff changeset
   150
                messageFile.messages.entrySet().stream()
1633de6070ae 8058542: Devise scheme for better diagnostic creation
mcimadamore
parents:
diff changeset
   151
                        .collect(Collectors.groupingBy(e -> FactoryKind.parseFrom(e.getKey().split("\\.")[1])));
1633de6070ae 8058542: Devise scheme for better diagnostic creation
mcimadamore
parents:
diff changeset
   152
        //generate nested classes
1633de6070ae 8058542: Devise scheme for better diagnostic creation
mcimadamore
parents:
diff changeset
   153
        List<String> nestedDecls = new ArrayList<>();
1633de6070ae 8058542: Devise scheme for better diagnostic creation
mcimadamore
parents:
diff changeset
   154
        Set<String> importedTypes = new TreeSet<>();
1633de6070ae 8058542: Devise scheme for better diagnostic creation
mcimadamore
parents:
diff changeset
   155
        for (Map.Entry<FactoryKind, List<Map.Entry<String, Message>>> entry : groupedEntries.entrySet()) {
1633de6070ae 8058542: Devise scheme for better diagnostic creation
mcimadamore
parents:
diff changeset
   156
            if (entry.getKey() == FactoryKind.OTHER) continue;
1633de6070ae 8058542: Devise scheme for better diagnostic creation
mcimadamore
parents:
diff changeset
   157
            //emit members
1633de6070ae 8058542: Devise scheme for better diagnostic creation
mcimadamore
parents:
diff changeset
   158
            String members = entry.getValue().stream()
1633de6070ae 8058542: Devise scheme for better diagnostic creation
mcimadamore
parents:
diff changeset
   159
                    .flatMap(e -> generateFactoryMethodsAndFields(e.getKey(), e.getValue()).stream())
1633de6070ae 8058542: Devise scheme for better diagnostic creation
mcimadamore
parents:
diff changeset
   160
                    .collect(Collectors.joining("\n\n"));
1633de6070ae 8058542: Devise scheme for better diagnostic creation
mcimadamore
parents:
diff changeset
   161
            //emit nested class
1633de6070ae 8058542: Devise scheme for better diagnostic creation
mcimadamore
parents:
diff changeset
   162
            String factoryDecl =
1633de6070ae 8058542: Devise scheme for better diagnostic creation
mcimadamore
parents:
diff changeset
   163
                    StubKind.FACTORY_CLASS.format(entry.getKey().factoryClazz, indent(members, 1));
1633de6070ae 8058542: Devise scheme for better diagnostic creation
mcimadamore
parents:
diff changeset
   164
            nestedDecls.add(indent(factoryDecl, 1));
1633de6070ae 8058542: Devise scheme for better diagnostic creation
mcimadamore
parents:
diff changeset
   165
            //add imports
1633de6070ae 8058542: Devise scheme for better diagnostic creation
mcimadamore
parents:
diff changeset
   166
            entry.getValue().stream().forEach(e ->
1633de6070ae 8058542: Devise scheme for better diagnostic creation
mcimadamore
parents:
diff changeset
   167
                    importedTypes.addAll(importedTypes(e.getValue().getMessageInfo().getTypes())));
1633de6070ae 8058542: Devise scheme for better diagnostic creation
mcimadamore
parents:
diff changeset
   168
        }
1633de6070ae 8058542: Devise scheme for better diagnostic creation
mcimadamore
parents:
diff changeset
   169
        String clazz = StubKind.TOPLEVEL.format(
1633de6070ae 8058542: Devise scheme for better diagnostic creation
mcimadamore
parents:
diff changeset
   170
                packageName(messageFile.file),
1633de6070ae 8058542: Devise scheme for better diagnostic creation
mcimadamore
parents:
diff changeset
   171
                String.join("\n", generateImports(importedTypes)),
1633de6070ae 8058542: Devise scheme for better diagnostic creation
mcimadamore
parents:
diff changeset
   172
                toplevelName(messageFile.file),
1633de6070ae 8058542: Devise scheme for better diagnostic creation
mcimadamore
parents:
diff changeset
   173
                String.join("\n", nestedDecls));
1633de6070ae 8058542: Devise scheme for better diagnostic creation
mcimadamore
parents:
diff changeset
   174
        try (FileWriter fw = new FileWriter(new File(outDir, toplevelName(messageFile.file) + ".java"))) {
1633de6070ae 8058542: Devise scheme for better diagnostic creation
mcimadamore
parents:
diff changeset
   175
            fw.append(clazz);
1633de6070ae 8058542: Devise scheme for better diagnostic creation
mcimadamore
parents:
diff changeset
   176
        } catch (Throwable ex) {
1633de6070ae 8058542: Devise scheme for better diagnostic creation
mcimadamore
parents:
diff changeset
   177
            throw new AssertionError(ex);
1633de6070ae 8058542: Devise scheme for better diagnostic creation
mcimadamore
parents:
diff changeset
   178
        }
1633de6070ae 8058542: Devise scheme for better diagnostic creation
mcimadamore
parents:
diff changeset
   179
    }
1633de6070ae 8058542: Devise scheme for better diagnostic creation
mcimadamore
parents:
diff changeset
   180
1633de6070ae 8058542: Devise scheme for better diagnostic creation
mcimadamore
parents:
diff changeset
   181
    /**
1633de6070ae 8058542: Devise scheme for better diagnostic creation
mcimadamore
parents:
diff changeset
   182
     * Indent a string to a given level.
1633de6070ae 8058542: Devise scheme for better diagnostic creation
mcimadamore
parents:
diff changeset
   183
     */
1633de6070ae 8058542: Devise scheme for better diagnostic creation
mcimadamore
parents:
diff changeset
   184
    String indent(String s, int level) {
1633de6070ae 8058542: Devise scheme for better diagnostic creation
mcimadamore
parents:
diff changeset
   185
        return Stream.of(s.split("\n"))
1633de6070ae 8058542: Devise scheme for better diagnostic creation
mcimadamore
parents:
diff changeset
   186
                .map(sub -> INDENT_STRING.substring(0, level * INDENT_WIDTH) + sub)
1633de6070ae 8058542: Devise scheme for better diagnostic creation
mcimadamore
parents:
diff changeset
   187
                .collect(Collectors.joining("\n"));
1633de6070ae 8058542: Devise scheme for better diagnostic creation
mcimadamore
parents:
diff changeset
   188
    }
1633de6070ae 8058542: Devise scheme for better diagnostic creation
mcimadamore
parents:
diff changeset
   189
1633de6070ae 8058542: Devise scheme for better diagnostic creation
mcimadamore
parents:
diff changeset
   190
    /**
1633de6070ae 8058542: Devise scheme for better diagnostic creation
mcimadamore
parents:
diff changeset
   191
     * Retrieve package part of given file object.
1633de6070ae 8058542: Devise scheme for better diagnostic creation
mcimadamore
parents:
diff changeset
   192
     */
1633de6070ae 8058542: Devise scheme for better diagnostic creation
mcimadamore
parents:
diff changeset
   193
    String packageName(File file) {
1633de6070ae 8058542: Devise scheme for better diagnostic creation
mcimadamore
parents:
diff changeset
   194
        String path = file.getAbsolutePath();
28801
2f1c998c3fcc 8072054: Cannot build langtools if checked-out in a directory ending with \"com\"
jlahoda
parents: 28588
diff changeset
   195
        int begin = path.lastIndexOf(File.separatorChar + "com" + File.separatorChar);
2f1c998c3fcc 8072054: Cannot build langtools if checked-out in a directory ending with \"com\"
jlahoda
parents: 28588
diff changeset
   196
        String packagePath = path.substring(begin + 1, path.lastIndexOf(File.separatorChar));
28334
1633de6070ae 8058542: Devise scheme for better diagnostic creation
mcimadamore
parents:
diff changeset
   197
        String packageName =  packagePath.replace(File.separatorChar, '.');
1633de6070ae 8058542: Devise scheme for better diagnostic creation
mcimadamore
parents:
diff changeset
   198
        return packageName;
1633de6070ae 8058542: Devise scheme for better diagnostic creation
mcimadamore
parents:
diff changeset
   199
    }
1633de6070ae 8058542: Devise scheme for better diagnostic creation
mcimadamore
parents:
diff changeset
   200
1633de6070ae 8058542: Devise scheme for better diagnostic creation
mcimadamore
parents:
diff changeset
   201
    /**
1633de6070ae 8058542: Devise scheme for better diagnostic creation
mcimadamore
parents:
diff changeset
   202
     * Form the name of the toplevel factory class.
1633de6070ae 8058542: Devise scheme for better diagnostic creation
mcimadamore
parents:
diff changeset
   203
     */
1633de6070ae 8058542: Devise scheme for better diagnostic creation
mcimadamore
parents:
diff changeset
   204
    public static String toplevelName(File file) {
1633de6070ae 8058542: Devise scheme for better diagnostic creation
mcimadamore
parents:
diff changeset
   205
        return Stream.of(file.getName().split("\\."))
1633de6070ae 8058542: Devise scheme for better diagnostic creation
mcimadamore
parents:
diff changeset
   206
                .map(s -> Character.toUpperCase(s.charAt(0)) + s.substring(1))
1633de6070ae 8058542: Devise scheme for better diagnostic creation
mcimadamore
parents:
diff changeset
   207
                .collect(Collectors.joining(""));
1633de6070ae 8058542: Devise scheme for better diagnostic creation
mcimadamore
parents:
diff changeset
   208
    }
1633de6070ae 8058542: Devise scheme for better diagnostic creation
mcimadamore
parents:
diff changeset
   209
1633de6070ae 8058542: Devise scheme for better diagnostic creation
mcimadamore
parents:
diff changeset
   210
    /**
1633de6070ae 8058542: Devise scheme for better diagnostic creation
mcimadamore
parents:
diff changeset
   211
     * Generate a list of import declarations given a set of imported types.
1633de6070ae 8058542: Devise scheme for better diagnostic creation
mcimadamore
parents:
diff changeset
   212
     */
1633de6070ae 8058542: Devise scheme for better diagnostic creation
mcimadamore
parents:
diff changeset
   213
    List<String> generateImports(Set<String> importedTypes) {
1633de6070ae 8058542: Devise scheme for better diagnostic creation
mcimadamore
parents:
diff changeset
   214
        List<String> importDecls = new ArrayList<>();
1633de6070ae 8058542: Devise scheme for better diagnostic creation
mcimadamore
parents:
diff changeset
   215
        for (String it : importedTypes) {
1633de6070ae 8058542: Devise scheme for better diagnostic creation
mcimadamore
parents:
diff changeset
   216
            importDecls.add(StubKind.IMPORT.format(it));
1633de6070ae 8058542: Devise scheme for better diagnostic creation
mcimadamore
parents:
diff changeset
   217
        }
1633de6070ae 8058542: Devise scheme for better diagnostic creation
mcimadamore
parents:
diff changeset
   218
        return importDecls;
1633de6070ae 8058542: Devise scheme for better diagnostic creation
mcimadamore
parents:
diff changeset
   219
    }
1633de6070ae 8058542: Devise scheme for better diagnostic creation
mcimadamore
parents:
diff changeset
   220
1633de6070ae 8058542: Devise scheme for better diagnostic creation
mcimadamore
parents:
diff changeset
   221
    /**
1633de6070ae 8058542: Devise scheme for better diagnostic creation
mcimadamore
parents:
diff changeset
   222
     * Generate a list of factory methods/fields to be added to a given factory nested class.
1633de6070ae 8058542: Devise scheme for better diagnostic creation
mcimadamore
parents:
diff changeset
   223
     */
1633de6070ae 8058542: Devise scheme for better diagnostic creation
mcimadamore
parents:
diff changeset
   224
    List<String> generateFactoryMethodsAndFields(String key, Message msg) {
1633de6070ae 8058542: Devise scheme for better diagnostic creation
mcimadamore
parents:
diff changeset
   225
        MessageInfo msgInfo = msg.getMessageInfo();
1633de6070ae 8058542: Devise scheme for better diagnostic creation
mcimadamore
parents:
diff changeset
   226
        List<MessageLine> lines = msg.getLines(false);
1633de6070ae 8058542: Devise scheme for better diagnostic creation
mcimadamore
parents:
diff changeset
   227
        String javadoc = lines.stream()
1633de6070ae 8058542: Devise scheme for better diagnostic creation
mcimadamore
parents:
diff changeset
   228
                .filter(ml -> !ml.isInfo() && !ml.isEmptyOrComment())
1633de6070ae 8058542: Devise scheme for better diagnostic creation
mcimadamore
parents:
diff changeset
   229
                .map(ml -> ml.text)
1633de6070ae 8058542: Devise scheme for better diagnostic creation
mcimadamore
parents:
diff changeset
   230
                .collect(Collectors.joining("\n *"));
1633de6070ae 8058542: Devise scheme for better diagnostic creation
mcimadamore
parents:
diff changeset
   231
        String[] keyParts = key.split("\\.");
1633de6070ae 8058542: Devise scheme for better diagnostic creation
mcimadamore
parents:
diff changeset
   232
        FactoryKind k = FactoryKind.parseFrom(keyParts[1]);
1633de6070ae 8058542: Devise scheme for better diagnostic creation
mcimadamore
parents:
diff changeset
   233
        String factoryName = factoryName(key);
1633de6070ae 8058542: Devise scheme for better diagnostic creation
mcimadamore
parents:
diff changeset
   234
        if (msgInfo.getTypes().isEmpty()) {
1633de6070ae 8058542: Devise scheme for better diagnostic creation
mcimadamore
parents:
diff changeset
   235
            //generate field
1633de6070ae 8058542: Devise scheme for better diagnostic creation
mcimadamore
parents:
diff changeset
   236
            String factoryField = StubKind.FACTORY_FIELD.format(k.keyClazz, factoryName,
1633de6070ae 8058542: Devise scheme for better diagnostic creation
mcimadamore
parents:
diff changeset
   237
                    "\"" + keyParts[0] + "\"",
1633de6070ae 8058542: Devise scheme for better diagnostic creation
mcimadamore
parents:
diff changeset
   238
                    "\"" + Stream.of(keyParts).skip(2).collect(Collectors.joining(".")) + "\"",
1633de6070ae 8058542: Devise scheme for better diagnostic creation
mcimadamore
parents:
diff changeset
   239
                    javadoc);
1633de6070ae 8058542: Devise scheme for better diagnostic creation
mcimadamore
parents:
diff changeset
   240
            return Collections.singletonList(factoryField);
1633de6070ae 8058542: Devise scheme for better diagnostic creation
mcimadamore
parents:
diff changeset
   241
        } else {
1633de6070ae 8058542: Devise scheme for better diagnostic creation
mcimadamore
parents:
diff changeset
   242
            //generate method
1633de6070ae 8058542: Devise scheme for better diagnostic creation
mcimadamore
parents:
diff changeset
   243
            List<String> factoryMethods = new ArrayList<>();
1633de6070ae 8058542: Devise scheme for better diagnostic creation
mcimadamore
parents:
diff changeset
   244
            for (List<MessageType> msgTypes : normalizeTypes(0, msgInfo.getTypes())) {
1633de6070ae 8058542: Devise scheme for better diagnostic creation
mcimadamore
parents:
diff changeset
   245
                List<String> types = generateTypes(msgTypes);
1633de6070ae 8058542: Devise scheme for better diagnostic creation
mcimadamore
parents:
diff changeset
   246
                List<String> argNames = argNames(types.size());
1633de6070ae 8058542: Devise scheme for better diagnostic creation
mcimadamore
parents:
diff changeset
   247
                String suppressionString = needsSuppressWarnings(msgTypes) ?
1633de6070ae 8058542: Devise scheme for better diagnostic creation
mcimadamore
parents:
diff changeset
   248
                        StubKind.SUPPRESS_WARNINGS.format() : "";
1633de6070ae 8058542: Devise scheme for better diagnostic creation
mcimadamore
parents:
diff changeset
   249
                String factoryMethod = StubKind.FACTORY_METHOD_DECL.format(suppressionString, k.keyClazz,
1633de6070ae 8058542: Devise scheme for better diagnostic creation
mcimadamore
parents:
diff changeset
   250
                        factoryName, argDecls(types, argNames).stream().collect(Collectors.joining(", ")),
1633de6070ae 8058542: Devise scheme for better diagnostic creation
mcimadamore
parents:
diff changeset
   251
                        indent(StubKind.FACTORY_METHOD_BODY.format(k.keyClazz,
1633de6070ae 8058542: Devise scheme for better diagnostic creation
mcimadamore
parents:
diff changeset
   252
                                "\"" + keyParts[0] + "\"",
1633de6070ae 8058542: Devise scheme for better diagnostic creation
mcimadamore
parents:
diff changeset
   253
                                "\"" + Stream.of(keyParts).skip(2).collect(Collectors.joining(".")) + "\"",
1633de6070ae 8058542: Devise scheme for better diagnostic creation
mcimadamore
parents:
diff changeset
   254
                                argNames.stream().collect(Collectors.joining(", "))), 1),
1633de6070ae 8058542: Devise scheme for better diagnostic creation
mcimadamore
parents:
diff changeset
   255
                        javadoc);
1633de6070ae 8058542: Devise scheme for better diagnostic creation
mcimadamore
parents:
diff changeset
   256
                factoryMethods.add(factoryMethod);
1633de6070ae 8058542: Devise scheme for better diagnostic creation
mcimadamore
parents:
diff changeset
   257
            }
1633de6070ae 8058542: Devise scheme for better diagnostic creation
mcimadamore
parents:
diff changeset
   258
            return factoryMethods;
1633de6070ae 8058542: Devise scheme for better diagnostic creation
mcimadamore
parents:
diff changeset
   259
        }
1633de6070ae 8058542: Devise scheme for better diagnostic creation
mcimadamore
parents:
diff changeset
   260
    }
1633de6070ae 8058542: Devise scheme for better diagnostic creation
mcimadamore
parents:
diff changeset
   261
1633de6070ae 8058542: Devise scheme for better diagnostic creation
mcimadamore
parents:
diff changeset
   262
    /**
1633de6070ae 8058542: Devise scheme for better diagnostic creation
mcimadamore
parents:
diff changeset
   263
     * Form the name of a factory method/field given a resource key.
1633de6070ae 8058542: Devise scheme for better diagnostic creation
mcimadamore
parents:
diff changeset
   264
     */
1633de6070ae 8058542: Devise scheme for better diagnostic creation
mcimadamore
parents:
diff changeset
   265
    String factoryName(String key) {
1633de6070ae 8058542: Devise scheme for better diagnostic creation
mcimadamore
parents:
diff changeset
   266
        return Stream.of(key.split("[\\.-]"))
1633de6070ae 8058542: Devise scheme for better diagnostic creation
mcimadamore
parents:
diff changeset
   267
                .skip(2)
1633de6070ae 8058542: Devise scheme for better diagnostic creation
mcimadamore
parents:
diff changeset
   268
                .map(s -> Character.toUpperCase(s.charAt(0)) + s.substring(1))
1633de6070ae 8058542: Devise scheme for better diagnostic creation
mcimadamore
parents:
diff changeset
   269
                .collect(Collectors.joining(""));
1633de6070ae 8058542: Devise scheme for better diagnostic creation
mcimadamore
parents:
diff changeset
   270
    }
1633de6070ae 8058542: Devise scheme for better diagnostic creation
mcimadamore
parents:
diff changeset
   271
1633de6070ae 8058542: Devise scheme for better diagnostic creation
mcimadamore
parents:
diff changeset
   272
    /**
1633de6070ae 8058542: Devise scheme for better diagnostic creation
mcimadamore
parents:
diff changeset
   273
     * Generate a formal parameter list given a list of types and names.
1633de6070ae 8058542: Devise scheme for better diagnostic creation
mcimadamore
parents:
diff changeset
   274
     */
1633de6070ae 8058542: Devise scheme for better diagnostic creation
mcimadamore
parents:
diff changeset
   275
    List<String> argDecls(List<String> types, List<String> args) {
1633de6070ae 8058542: Devise scheme for better diagnostic creation
mcimadamore
parents:
diff changeset
   276
        List<String> argNames = new ArrayList<>();
1633de6070ae 8058542: Devise scheme for better diagnostic creation
mcimadamore
parents:
diff changeset
   277
        for (int i = 0 ; i < types.size() ; i++) {
1633de6070ae 8058542: Devise scheme for better diagnostic creation
mcimadamore
parents:
diff changeset
   278
            argNames.add(types.get(i) + " " + args.get(i));
1633de6070ae 8058542: Devise scheme for better diagnostic creation
mcimadamore
parents:
diff changeset
   279
        }
1633de6070ae 8058542: Devise scheme for better diagnostic creation
mcimadamore
parents:
diff changeset
   280
        return argNames;
1633de6070ae 8058542: Devise scheme for better diagnostic creation
mcimadamore
parents:
diff changeset
   281
    }
1633de6070ae 8058542: Devise scheme for better diagnostic creation
mcimadamore
parents:
diff changeset
   282
1633de6070ae 8058542: Devise scheme for better diagnostic creation
mcimadamore
parents:
diff changeset
   283
    /**
1633de6070ae 8058542: Devise scheme for better diagnostic creation
mcimadamore
parents:
diff changeset
   284
     * Generate a list of formal parameter names given a size.
1633de6070ae 8058542: Devise scheme for better diagnostic creation
mcimadamore
parents:
diff changeset
   285
     */
1633de6070ae 8058542: Devise scheme for better diagnostic creation
mcimadamore
parents:
diff changeset
   286
    List<String> argNames(int size) {
1633de6070ae 8058542: Devise scheme for better diagnostic creation
mcimadamore
parents:
diff changeset
   287
        List<String> argNames = new ArrayList<>();
1633de6070ae 8058542: Devise scheme for better diagnostic creation
mcimadamore
parents:
diff changeset
   288
        for (int i = 0 ; i < size ; i++) {
1633de6070ae 8058542: Devise scheme for better diagnostic creation
mcimadamore
parents:
diff changeset
   289
            argNames.add(StubKind.FACTORY_METHOD_ARG.format(i));
1633de6070ae 8058542: Devise scheme for better diagnostic creation
mcimadamore
parents:
diff changeset
   290
        }
1633de6070ae 8058542: Devise scheme for better diagnostic creation
mcimadamore
parents:
diff changeset
   291
        return argNames;
1633de6070ae 8058542: Devise scheme for better diagnostic creation
mcimadamore
parents:
diff changeset
   292
    }
1633de6070ae 8058542: Devise scheme for better diagnostic creation
mcimadamore
parents:
diff changeset
   293
1633de6070ae 8058542: Devise scheme for better diagnostic creation
mcimadamore
parents:
diff changeset
   294
    /**
1633de6070ae 8058542: Devise scheme for better diagnostic creation
mcimadamore
parents:
diff changeset
   295
     * Convert a (normalized) parsed type into a string-based representation of some Java type.
1633de6070ae 8058542: Devise scheme for better diagnostic creation
mcimadamore
parents:
diff changeset
   296
     */
1633de6070ae 8058542: Devise scheme for better diagnostic creation
mcimadamore
parents:
diff changeset
   297
    List<String> generateTypes(List<MessageType> msgTypes) {
1633de6070ae 8058542: Devise scheme for better diagnostic creation
mcimadamore
parents:
diff changeset
   298
        return msgTypes.stream().map(t -> t.accept(stringVisitor, null)).collect(Collectors.toList());
1633de6070ae 8058542: Devise scheme for better diagnostic creation
mcimadamore
parents:
diff changeset
   299
    }
1633de6070ae 8058542: Devise scheme for better diagnostic creation
mcimadamore
parents:
diff changeset
   300
    //where
1633de6070ae 8058542: Devise scheme for better diagnostic creation
mcimadamore
parents:
diff changeset
   301
        Visitor<String, Void> stringVisitor = new Visitor<String, Void>() {
1633de6070ae 8058542: Devise scheme for better diagnostic creation
mcimadamore
parents:
diff changeset
   302
            @Override
1633de6070ae 8058542: Devise scheme for better diagnostic creation
mcimadamore
parents:
diff changeset
   303
            public String visitCustomType(CustomType t, Void aVoid) {
1633de6070ae 8058542: Devise scheme for better diagnostic creation
mcimadamore
parents:
diff changeset
   304
                String customType = t.typeString;
1633de6070ae 8058542: Devise scheme for better diagnostic creation
mcimadamore
parents:
diff changeset
   305
                return customType.substring(customType.lastIndexOf('.') + 1);
1633de6070ae 8058542: Devise scheme for better diagnostic creation
mcimadamore
parents:
diff changeset
   306
            }
1633de6070ae 8058542: Devise scheme for better diagnostic creation
mcimadamore
parents:
diff changeset
   307
1633de6070ae 8058542: Devise scheme for better diagnostic creation
mcimadamore
parents:
diff changeset
   308
            @Override
1633de6070ae 8058542: Devise scheme for better diagnostic creation
mcimadamore
parents:
diff changeset
   309
            public String visitSimpleType(SimpleType t, Void aVoid) {
1633de6070ae 8058542: Devise scheme for better diagnostic creation
mcimadamore
parents:
diff changeset
   310
                return t.clazz;
1633de6070ae 8058542: Devise scheme for better diagnostic creation
mcimadamore
parents:
diff changeset
   311
            }
1633de6070ae 8058542: Devise scheme for better diagnostic creation
mcimadamore
parents:
diff changeset
   312
1633de6070ae 8058542: Devise scheme for better diagnostic creation
mcimadamore
parents:
diff changeset
   313
            @Override
1633de6070ae 8058542: Devise scheme for better diagnostic creation
mcimadamore
parents:
diff changeset
   314
            public String visitCompoundType(CompoundType t, Void aVoid) {
1633de6070ae 8058542: Devise scheme for better diagnostic creation
mcimadamore
parents:
diff changeset
   315
                return StubKind.WILDCARDS_EXTENDS.format(t.kind.clazz.clazz,
1633de6070ae 8058542: Devise scheme for better diagnostic creation
mcimadamore
parents:
diff changeset
   316
                        t.elemtype.accept(this, null));
1633de6070ae 8058542: Devise scheme for better diagnostic creation
mcimadamore
parents:
diff changeset
   317
            }
1633de6070ae 8058542: Devise scheme for better diagnostic creation
mcimadamore
parents:
diff changeset
   318
1633de6070ae 8058542: Devise scheme for better diagnostic creation
mcimadamore
parents:
diff changeset
   319
            @Override
1633de6070ae 8058542: Devise scheme for better diagnostic creation
mcimadamore
parents:
diff changeset
   320
            public String visitUnionType(UnionType t, Void aVoid) {
1633de6070ae 8058542: Devise scheme for better diagnostic creation
mcimadamore
parents:
diff changeset
   321
                throw new AssertionError("Union types should have been denormalized!");
1633de6070ae 8058542: Devise scheme for better diagnostic creation
mcimadamore
parents:
diff changeset
   322
            }
1633de6070ae 8058542: Devise scheme for better diagnostic creation
mcimadamore
parents:
diff changeset
   323
        };
1633de6070ae 8058542: Devise scheme for better diagnostic creation
mcimadamore
parents:
diff changeset
   324
1633de6070ae 8058542: Devise scheme for better diagnostic creation
mcimadamore
parents:
diff changeset
   325
    /**
1633de6070ae 8058542: Devise scheme for better diagnostic creation
mcimadamore
parents:
diff changeset
   326
     * See if any of the parsed types in the given list needs warning suppression.
1633de6070ae 8058542: Devise scheme for better diagnostic creation
mcimadamore
parents:
diff changeset
   327
     */
1633de6070ae 8058542: Devise scheme for better diagnostic creation
mcimadamore
parents:
diff changeset
   328
    boolean needsSuppressWarnings(List<MessageType> msgTypes) {
1633de6070ae 8058542: Devise scheme for better diagnostic creation
mcimadamore
parents:
diff changeset
   329
        return msgTypes.stream().anyMatch(t -> t.accept(suppressWarningsVisitor, null));
1633de6070ae 8058542: Devise scheme for better diagnostic creation
mcimadamore
parents:
diff changeset
   330
    }
1633de6070ae 8058542: Devise scheme for better diagnostic creation
mcimadamore
parents:
diff changeset
   331
    //where
1633de6070ae 8058542: Devise scheme for better diagnostic creation
mcimadamore
parents:
diff changeset
   332
    Visitor<Boolean, Void> suppressWarningsVisitor = new Visitor<Boolean, Void>() {
1633de6070ae 8058542: Devise scheme for better diagnostic creation
mcimadamore
parents:
diff changeset
   333
        @Override
1633de6070ae 8058542: Devise scheme for better diagnostic creation
mcimadamore
parents:
diff changeset
   334
        public Boolean visitCustomType(CustomType t, Void aVoid) {
1633de6070ae 8058542: Devise scheme for better diagnostic creation
mcimadamore
parents:
diff changeset
   335
            //play safe
1633de6070ae 8058542: Devise scheme for better diagnostic creation
mcimadamore
parents:
diff changeset
   336
            return true;
1633de6070ae 8058542: Devise scheme for better diagnostic creation
mcimadamore
parents:
diff changeset
   337
        }
1633de6070ae 8058542: Devise scheme for better diagnostic creation
mcimadamore
parents:
diff changeset
   338
        @Override
1633de6070ae 8058542: Devise scheme for better diagnostic creation
mcimadamore
parents:
diff changeset
   339
        public Boolean visitSimpleType(SimpleType t, Void aVoid) {
1633de6070ae 8058542: Devise scheme for better diagnostic creation
mcimadamore
parents:
diff changeset
   340
            switch (t) {
1633de6070ae 8058542: Devise scheme for better diagnostic creation
mcimadamore
parents:
diff changeset
   341
                case LIST:
1633de6070ae 8058542: Devise scheme for better diagnostic creation
mcimadamore
parents:
diff changeset
   342
                case SET:
1633de6070ae 8058542: Devise scheme for better diagnostic creation
mcimadamore
parents:
diff changeset
   343
                    return true;
1633de6070ae 8058542: Devise scheme for better diagnostic creation
mcimadamore
parents:
diff changeset
   344
                default:
1633de6070ae 8058542: Devise scheme for better diagnostic creation
mcimadamore
parents:
diff changeset
   345
                    return false;
1633de6070ae 8058542: Devise scheme for better diagnostic creation
mcimadamore
parents:
diff changeset
   346
            }
1633de6070ae 8058542: Devise scheme for better diagnostic creation
mcimadamore
parents:
diff changeset
   347
        }
1633de6070ae 8058542: Devise scheme for better diagnostic creation
mcimadamore
parents:
diff changeset
   348
1633de6070ae 8058542: Devise scheme for better diagnostic creation
mcimadamore
parents:
diff changeset
   349
        @Override
1633de6070ae 8058542: Devise scheme for better diagnostic creation
mcimadamore
parents:
diff changeset
   350
        public Boolean visitCompoundType(CompoundType t, Void aVoid) {
1633de6070ae 8058542: Devise scheme for better diagnostic creation
mcimadamore
parents:
diff changeset
   351
            return t.elemtype.accept(this, null);
1633de6070ae 8058542: Devise scheme for better diagnostic creation
mcimadamore
parents:
diff changeset
   352
        }
1633de6070ae 8058542: Devise scheme for better diagnostic creation
mcimadamore
parents:
diff changeset
   353
1633de6070ae 8058542: Devise scheme for better diagnostic creation
mcimadamore
parents:
diff changeset
   354
        @Override
1633de6070ae 8058542: Devise scheme for better diagnostic creation
mcimadamore
parents:
diff changeset
   355
        public Boolean visitUnionType(UnionType t, Void aVoid) {
1633de6070ae 8058542: Devise scheme for better diagnostic creation
mcimadamore
parents:
diff changeset
   356
            return needsSuppressWarnings(Arrays.asList(t.choices));
1633de6070ae 8058542: Devise scheme for better diagnostic creation
mcimadamore
parents:
diff changeset
   357
        }
1633de6070ae 8058542: Devise scheme for better diagnostic creation
mcimadamore
parents:
diff changeset
   358
    };
1633de6070ae 8058542: Devise scheme for better diagnostic creation
mcimadamore
parents:
diff changeset
   359
1633de6070ae 8058542: Devise scheme for better diagnostic creation
mcimadamore
parents:
diff changeset
   360
    /**
1633de6070ae 8058542: Devise scheme for better diagnostic creation
mcimadamore
parents:
diff changeset
   361
     * Retrieve a list of types that need to be imported, so that the factory body can refer
1633de6070ae 8058542: Devise scheme for better diagnostic creation
mcimadamore
parents:
diff changeset
   362
     * to the types in the given list using simple names.
1633de6070ae 8058542: Devise scheme for better diagnostic creation
mcimadamore
parents:
diff changeset
   363
     */
1633de6070ae 8058542: Devise scheme for better diagnostic creation
mcimadamore
parents:
diff changeset
   364
    Set<String> importedTypes(List<MessageType> msgTypes) {
1633de6070ae 8058542: Devise scheme for better diagnostic creation
mcimadamore
parents:
diff changeset
   365
        Set<String> imports = new TreeSet<>();
1633de6070ae 8058542: Devise scheme for better diagnostic creation
mcimadamore
parents:
diff changeset
   366
        msgTypes.forEach(t -> t.accept(importVisitor, imports));
1633de6070ae 8058542: Devise scheme for better diagnostic creation
mcimadamore
parents:
diff changeset
   367
        return imports;
1633de6070ae 8058542: Devise scheme for better diagnostic creation
mcimadamore
parents:
diff changeset
   368
    }
1633de6070ae 8058542: Devise scheme for better diagnostic creation
mcimadamore
parents:
diff changeset
   369
    //where
1633de6070ae 8058542: Devise scheme for better diagnostic creation
mcimadamore
parents:
diff changeset
   370
    Visitor<Void, Set<String>> importVisitor = new Visitor<Void, Set<String>>() {
1633de6070ae 8058542: Devise scheme for better diagnostic creation
mcimadamore
parents:
diff changeset
   371
        @Override
1633de6070ae 8058542: Devise scheme for better diagnostic creation
mcimadamore
parents:
diff changeset
   372
        public Void visitCustomType(CustomType t, Set<String> imports) {
1633de6070ae 8058542: Devise scheme for better diagnostic creation
mcimadamore
parents:
diff changeset
   373
            imports.add(t.typeString);
1633de6070ae 8058542: Devise scheme for better diagnostic creation
mcimadamore
parents:
diff changeset
   374
            return null;
1633de6070ae 8058542: Devise scheme for better diagnostic creation
mcimadamore
parents:
diff changeset
   375
        }
1633de6070ae 8058542: Devise scheme for better diagnostic creation
mcimadamore
parents:
diff changeset
   376
1633de6070ae 8058542: Devise scheme for better diagnostic creation
mcimadamore
parents:
diff changeset
   377
        @Override
1633de6070ae 8058542: Devise scheme for better diagnostic creation
mcimadamore
parents:
diff changeset
   378
        public Void visitSimpleType(SimpleType t, Set<String> imports) {
1633de6070ae 8058542: Devise scheme for better diagnostic creation
mcimadamore
parents:
diff changeset
   379
            if (t.qualifier != null) {
1633de6070ae 8058542: Devise scheme for better diagnostic creation
mcimadamore
parents:
diff changeset
   380
                imports.add(t.qualifier + "." + t.clazz);
1633de6070ae 8058542: Devise scheme for better diagnostic creation
mcimadamore
parents:
diff changeset
   381
            }
1633de6070ae 8058542: Devise scheme for better diagnostic creation
mcimadamore
parents:
diff changeset
   382
            return null;
1633de6070ae 8058542: Devise scheme for better diagnostic creation
mcimadamore
parents:
diff changeset
   383
        }
1633de6070ae 8058542: Devise scheme for better diagnostic creation
mcimadamore
parents:
diff changeset
   384
1633de6070ae 8058542: Devise scheme for better diagnostic creation
mcimadamore
parents:
diff changeset
   385
        @Override
1633de6070ae 8058542: Devise scheme for better diagnostic creation
mcimadamore
parents:
diff changeset
   386
        public Void visitCompoundType(CompoundType t, Set<String> imports) {
1633de6070ae 8058542: Devise scheme for better diagnostic creation
mcimadamore
parents:
diff changeset
   387
            visitSimpleType(t.kind.clazz, imports);
1633de6070ae 8058542: Devise scheme for better diagnostic creation
mcimadamore
parents:
diff changeset
   388
            t.elemtype.accept(this, imports);
1633de6070ae 8058542: Devise scheme for better diagnostic creation
mcimadamore
parents:
diff changeset
   389
            return null;
1633de6070ae 8058542: Devise scheme for better diagnostic creation
mcimadamore
parents:
diff changeset
   390
        }
1633de6070ae 8058542: Devise scheme for better diagnostic creation
mcimadamore
parents:
diff changeset
   391
1633de6070ae 8058542: Devise scheme for better diagnostic creation
mcimadamore
parents:
diff changeset
   392
        @Override
1633de6070ae 8058542: Devise scheme for better diagnostic creation
mcimadamore
parents:
diff changeset
   393
        public Void visitUnionType(UnionType t, Set<String> imports) {
1633de6070ae 8058542: Devise scheme for better diagnostic creation
mcimadamore
parents:
diff changeset
   394
            Stream.of(t.choices).forEach(c -> c.accept(this, imports));
1633de6070ae 8058542: Devise scheme for better diagnostic creation
mcimadamore
parents:
diff changeset
   395
            return null;
1633de6070ae 8058542: Devise scheme for better diagnostic creation
mcimadamore
parents:
diff changeset
   396
        }
1633de6070ae 8058542: Devise scheme for better diagnostic creation
mcimadamore
parents:
diff changeset
   397
    };
1633de6070ae 8058542: Devise scheme for better diagnostic creation
mcimadamore
parents:
diff changeset
   398
1633de6070ae 8058542: Devise scheme for better diagnostic creation
mcimadamore
parents:
diff changeset
   399
    /**
1633de6070ae 8058542: Devise scheme for better diagnostic creation
mcimadamore
parents:
diff changeset
   400
     * Normalize parsed types in a comment line. If one or more types in the line contains alternatives,
1633de6070ae 8058542: Devise scheme for better diagnostic creation
mcimadamore
parents:
diff changeset
   401
     * this routine generate a list of 'overloaded' normalized signatures.
1633de6070ae 8058542: Devise scheme for better diagnostic creation
mcimadamore
parents:
diff changeset
   402
     */
1633de6070ae 8058542: Devise scheme for better diagnostic creation
mcimadamore
parents:
diff changeset
   403
    List<List<MessageType>> normalizeTypes(int idx, List<MessageType> msgTypes) {
1633de6070ae 8058542: Devise scheme for better diagnostic creation
mcimadamore
parents:
diff changeset
   404
        if (msgTypes.size() == idx) return Collections.singletonList(Collections.emptyList());
1633de6070ae 8058542: Devise scheme for better diagnostic creation
mcimadamore
parents:
diff changeset
   405
        MessageType head = msgTypes.get(idx);
1633de6070ae 8058542: Devise scheme for better diagnostic creation
mcimadamore
parents:
diff changeset
   406
        List<List<MessageType>> buf = new ArrayList<>();
1633de6070ae 8058542: Devise scheme for better diagnostic creation
mcimadamore
parents:
diff changeset
   407
        for (MessageType alternative : head.accept(normalizeVisitor, null)) {
1633de6070ae 8058542: Devise scheme for better diagnostic creation
mcimadamore
parents:
diff changeset
   408
            for (List<MessageType> rest : normalizeTypes(idx + 1, msgTypes)) {
1633de6070ae 8058542: Devise scheme for better diagnostic creation
mcimadamore
parents:
diff changeset
   409
                List<MessageType> temp = new ArrayList<>(rest);
1633de6070ae 8058542: Devise scheme for better diagnostic creation
mcimadamore
parents:
diff changeset
   410
                temp.add(0, alternative);
1633de6070ae 8058542: Devise scheme for better diagnostic creation
mcimadamore
parents:
diff changeset
   411
                buf.add(temp);
1633de6070ae 8058542: Devise scheme for better diagnostic creation
mcimadamore
parents:
diff changeset
   412
            }
1633de6070ae 8058542: Devise scheme for better diagnostic creation
mcimadamore
parents:
diff changeset
   413
        }
1633de6070ae 8058542: Devise scheme for better diagnostic creation
mcimadamore
parents:
diff changeset
   414
        return buf;
1633de6070ae 8058542: Devise scheme for better diagnostic creation
mcimadamore
parents:
diff changeset
   415
    }
1633de6070ae 8058542: Devise scheme for better diagnostic creation
mcimadamore
parents:
diff changeset
   416
    //where
1633de6070ae 8058542: Devise scheme for better diagnostic creation
mcimadamore
parents:
diff changeset
   417
    Visitor<List<MessageType>, Void> normalizeVisitor = new Visitor<List<MessageType>, Void>() {
1633de6070ae 8058542: Devise scheme for better diagnostic creation
mcimadamore
parents:
diff changeset
   418
        @Override
1633de6070ae 8058542: Devise scheme for better diagnostic creation
mcimadamore
parents:
diff changeset
   419
        public List<MessageType> visitCustomType(CustomType t, Void aVoid) {
1633de6070ae 8058542: Devise scheme for better diagnostic creation
mcimadamore
parents:
diff changeset
   420
            return Collections.singletonList(t);
1633de6070ae 8058542: Devise scheme for better diagnostic creation
mcimadamore
parents:
diff changeset
   421
        }
1633de6070ae 8058542: Devise scheme for better diagnostic creation
mcimadamore
parents:
diff changeset
   422
1633de6070ae 8058542: Devise scheme for better diagnostic creation
mcimadamore
parents:
diff changeset
   423
        @Override
1633de6070ae 8058542: Devise scheme for better diagnostic creation
mcimadamore
parents:
diff changeset
   424
        public List<MessageType> visitSimpleType(SimpleType t, Void aVoid) {
1633de6070ae 8058542: Devise scheme for better diagnostic creation
mcimadamore
parents:
diff changeset
   425
            return Collections.singletonList(t);
1633de6070ae 8058542: Devise scheme for better diagnostic creation
mcimadamore
parents:
diff changeset
   426
        }
1633de6070ae 8058542: Devise scheme for better diagnostic creation
mcimadamore
parents:
diff changeset
   427
1633de6070ae 8058542: Devise scheme for better diagnostic creation
mcimadamore
parents:
diff changeset
   428
        @Override
1633de6070ae 8058542: Devise scheme for better diagnostic creation
mcimadamore
parents:
diff changeset
   429
        public List<MessageType> visitCompoundType(CompoundType t, Void aVoid) {
1633de6070ae 8058542: Devise scheme for better diagnostic creation
mcimadamore
parents:
diff changeset
   430
            return t.elemtype.accept(this, null).stream()
1633de6070ae 8058542: Devise scheme for better diagnostic creation
mcimadamore
parents:
diff changeset
   431
                    .map(nt -> new CompoundType(t.kind, nt))
1633de6070ae 8058542: Devise scheme for better diagnostic creation
mcimadamore
parents:
diff changeset
   432
                    .collect(Collectors.toList());
1633de6070ae 8058542: Devise scheme for better diagnostic creation
mcimadamore
parents:
diff changeset
   433
        }
1633de6070ae 8058542: Devise scheme for better diagnostic creation
mcimadamore
parents:
diff changeset
   434
1633de6070ae 8058542: Devise scheme for better diagnostic creation
mcimadamore
parents:
diff changeset
   435
        @Override
1633de6070ae 8058542: Devise scheme for better diagnostic creation
mcimadamore
parents:
diff changeset
   436
        public List<MessageType> visitUnionType(UnionType t, Void aVoid) {
1633de6070ae 8058542: Devise scheme for better diagnostic creation
mcimadamore
parents:
diff changeset
   437
            return Stream.of(t.choices)
1633de6070ae 8058542: Devise scheme for better diagnostic creation
mcimadamore
parents:
diff changeset
   438
                    .flatMap(t2 -> t2.accept(this, null).stream())
1633de6070ae 8058542: Devise scheme for better diagnostic creation
mcimadamore
parents:
diff changeset
   439
                    .collect(Collectors.toList());
1633de6070ae 8058542: Devise scheme for better diagnostic creation
mcimadamore
parents:
diff changeset
   440
        }
1633de6070ae 8058542: Devise scheme for better diagnostic creation
mcimadamore
parents:
diff changeset
   441
    };
1633de6070ae 8058542: Devise scheme for better diagnostic creation
mcimadamore
parents:
diff changeset
   442
}