1/*
2 * Copyright (c) 2013, 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.
8 *
9 * This code is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 */
23package org.graalvm.compiler.options;
24
25import java.util.Arrays;
26import java.util.Collections;
27import java.util.List;
28
29/**
30 * Describes the attributes of a static field {@linkplain Option option} and provides access to its
31 * {@linkplain OptionKey value}.
32 */
33public final class OptionDescriptor {
34
35    protected final String name;
36    protected final Class<?> type;
37    protected final String help;
38    protected final List<String> extraHelp;
39    protected final OptionKey<?> optionKey;
40    protected final Class<?> declaringClass;
41    protected final String fieldName;
42
43    private static final String[] NO_EXTRA_HELP = {};
44
45    public static OptionDescriptor create(String name, Class<?> type, String help, Class<?> declaringClass, String fieldName, OptionKey<?> option) {
46        return create(name, type, help, NO_EXTRA_HELP, declaringClass, fieldName, option);
47    }
48
49    public static OptionDescriptor create(String name, Class<?> type, String help, String[] extraHelp, Class<?> declaringClass, String fieldName, OptionKey<?> option) {
50        assert option != null : declaringClass + "." + fieldName;
51        OptionDescriptor result = option.getDescriptor();
52        if (result == null) {
53            List<String> extraHelpList = extraHelp == null || extraHelp.length == 0 ? Collections.emptyList() : Collections.unmodifiableList(Arrays.asList(extraHelp));
54            result = new OptionDescriptor(name, type, help, extraHelpList, declaringClass, fieldName, option);
55            option.setDescriptor(result);
56        }
57        assert result.name.equals(name) && result.type == type && result.declaringClass == declaringClass && result.fieldName.equals(fieldName) && result.optionKey == option;
58        return result;
59    }
60
61    private OptionDescriptor(String name, Class<?> type, String help, List<String> extraHelp, Class<?> declaringClass, String fieldName, OptionKey<?> optionKey) {
62        this.name = name;
63        this.type = type;
64        this.help = help;
65        this.extraHelp = extraHelp;
66        this.optionKey = optionKey;
67        this.declaringClass = declaringClass;
68        this.fieldName = fieldName;
69        assert !type.isPrimitive() : "must used boxed type instead of " + type;
70    }
71
72    /**
73     * Gets the type of values stored in the option. This will be the boxed type for a primitive
74     * option.
75     */
76    public Class<?> getType() {
77        return type;
78    }
79
80    /**
81     * Gets a descriptive help message for the option. This message should be self contained without
82     * relying on {@link #getExtraHelp() extra help lines}.
83     *
84     * @see Option#help()
85     */
86    public String getHelp() {
87        return help;
88    }
89
90    /**
91     * Gets extra lines of help text. These lines should not be subject to any line wrapping or
92     * formatting apart from indentation.
93     */
94    public List<String> getExtraHelp() {
95        return extraHelp;
96    }
97
98    /**
99     * Gets the name of the option. It's up to the client of this object how to use the name to get
100     * a user specified value for the option from the environment.
101     */
102    public String getName() {
103        return name;
104    }
105
106    /**
107     * Gets the boxed option value.
108     */
109    public OptionKey<?> getOptionKey() {
110        return optionKey;
111    }
112
113    public Class<?> getDeclaringClass() {
114        return declaringClass;
115    }
116
117    public String getFieldName() {
118        return fieldName;
119    }
120
121    /**
122     * Gets a description of the location where this option is stored.
123     */
124    public String getLocation() {
125        return getDeclaringClass().getName() + "." + getFieldName();
126    }
127}
128