1 /*
   2  * Copyright (c) 2013, 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.
   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  */
  23 
  24 
  25 package org.graalvm.compiler.options;
  26 
  27 import java.util.Arrays;
  28 import java.util.Collections;
  29 import java.util.List;
  30 
  31 /**
  32  * Describes the attributes of a static field {@linkplain Option option} and provides access to its
  33  * {@linkplain OptionKey value}.
  34  */
  35 public final class OptionDescriptor {
  36 
  37     private final String name;
  38     private final OptionType optionType;
  39     private final Class<?> optionValueType;
  40     private final String help;
  41     private final List<String> extraHelp;
  42     private final OptionKey<?> optionKey;
  43     private final Class<?> declaringClass;
  44     private final String fieldName;
  45 
  46     private static final String[] NO_EXTRA_HELP = {};
  47 
  48     public static OptionDescriptor create(String name, OptionType optionType, Class<?> optionValueType, String help, Class<?> declaringClass, String fieldName, OptionKey<?> option) {
  49         return create(name, optionType, optionValueType, help, NO_EXTRA_HELP, declaringClass, fieldName, option);
  50     }
  51 
  52     public static OptionDescriptor create(String name, OptionType optionType, Class<?> optionValueType, String help, String[] extraHelp, Class<?> declaringClass, String fieldName,
  53                     OptionKey<?> option) {
  54         assert option != null : declaringClass + "." + fieldName;
  55         OptionDescriptor result = option.getDescriptor();
  56         if (result == null) {
  57             List<String> extraHelpList = extraHelp == null || extraHelp.length == 0 ? Collections.emptyList() : Collections.unmodifiableList(Arrays.asList(extraHelp));
  58             result = new OptionDescriptor(name, optionType, optionValueType, help, extraHelpList, declaringClass, fieldName, option);
  59             option.setDescriptor(result);
  60         }
  61         assert result.name.equals(name) && result.optionValueType == optionValueType && result.declaringClass == declaringClass && result.fieldName.equals(fieldName) && result.optionKey == option;
  62         return result;
  63     }
  64 
  65     private OptionDescriptor(String name, OptionType optionType, Class<?> optionValueType, String help, List<String> extraHelp, Class<?> declaringClass, String fieldName, OptionKey<?> optionKey) {
  66         this.name = name;
  67         this.optionType = optionType;
  68         this.optionValueType = optionValueType;
  69         this.help = help;
  70         this.extraHelp = extraHelp;
  71         this.optionKey = optionKey;
  72         this.declaringClass = declaringClass;
  73         this.fieldName = fieldName;
  74         assert !optionValueType.isPrimitive() : "must used boxed optionValueType instead of " + optionValueType;
  75     }
  76 
  77     /**
  78      * Gets the type of values stored in the option. This will be the boxed type for a primitive
  79      * option.
  80      */
  81     public Class<?> getOptionValueType() {
  82         return optionValueType;
  83     }
  84 
  85     /**
  86      * Gets a descriptive help message for the option. This message should be self contained without
  87      * relying on {@link #getExtraHelp() extra help lines}.
  88      *
  89      * @see Option#help()
  90      */
  91     public String getHelp() {
  92         return help;
  93     }
  94 
  95     /**
  96      * Gets extra lines of help text. These lines should not be subject to any line wrapping or
  97      * formatting apart from indentation.
  98      */
  99     public List<String> getExtraHelp() {
 100         return extraHelp;
 101     }
 102 
 103     /**
 104      * Gets the name of the option. It's up to the client of this object how to use the name to get
 105      * a user specified value for the option from the environment.
 106      */
 107     public String getName() {
 108         return name;
 109     }
 110 
 111     /**
 112      * Gets the type of the option.
 113      */
 114     public OptionType getOptionType() {
 115         return optionType;
 116     }
 117 
 118     /**
 119      * Gets the boxed option value.
 120      */
 121     public OptionKey<?> getOptionKey() {
 122         return optionKey;
 123     }
 124 
 125     public Class<?> getDeclaringClass() {
 126         return declaringClass;
 127     }
 128 
 129     public String getFieldName() {
 130         return fieldName;
 131     }
 132 
 133     /**
 134      * Gets a description of the location where this option is stored.
 135      */
 136     public String getLocation() {
 137         return getDeclaringClass().getName() + "." + getFieldName();
 138     }
 139 }