// Copyright 2014 The Bazel Authors. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package com.google.devtools.common.options;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* An interface for annotating fields in classes (derived from OptionsBase)
* that are options.
*/
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Option {
/**
* The name of the option ("--name").
*/
String name();
/**
* The single-character abbreviation of the option ("-abbrev").
*/
char abbrev() default '\0';
/**
* A help string for the usage information.
*/
String help() default "";
/**
* A short text string to describe the type of the expected value. E.g., regex
. This
* is ignored for boolean, tristate, boolean_or_enum, and void options.
*/
String valueHelp() default "";
/**
* The default value for the option. This method should only be invoked directly by the parser
* implementation. Any access to default values should go via the parser to allow for application
* specific defaults.
*
*
There are two reasons this is a string. Firstly, it ensures that explicitly specifying this * option at its default value (as printed in the usage message) has the same behavior as not * specifying the option at all; this would be very hard to achieve if the default value was an * instance of type T, since we'd need to ensure that {@link #toString()} and {@link #converter} * were dual to each other. The second reason is more mundane but also more restrictive: * annotation values must be compile-time constants. * *
If an option's defaultValue() is the string "null", the option's converter will not be * invoked to interpret it; a null reference will be used instead. (It would be nice if * defaultValue could simply return null, but bizarrely, the Java Language Specification does not * consider null to be a compile-time constant.) This special interpretation of the string "null" * is only applicable when computing the default value; if specified on the command-line, this * string will have its usual literal meaning. * *
The default value for flags that set allowMultiple is always the empty list and its default * value is ignored. */ String defaultValue(); /** * A string describing the category of options that this belongs to. {@link * OptionsParser#describeOptions} prints options of the same category grouped together. * *
There are three special category values: * *
If the command can occur multiple times, then the attribute value must be a list
* type {@code List The {@link #defaultValue()} field of the annotation is ignored for repeatable flags and the
* default value will be the empty list.
*/
boolean allowMultiple() default false;
/**
* If the option is actually an abbreviation for other options, this field will contain the
* strings to expand this option into. The original option is dropped and the replacement used in
* its stead. It is recommended that such an option be of type {@link Void}.
*
* An expanded option overrides previously specified options of the same name, even if it is
* explicitly specified. This is the original behavior and can be surprising if the user is not
* aware of it, which has led to several requests to change this behavior. This was discussed in
* the blaze team and it was decided that it is not a strong enough case to change the behavior.
*/
String[] expansion() default {};
/**
* A mechanism for specifying an expansion that is a function of the parser's {@link
* IsolatedOptionsData}. This can be used to create an option that expands to different strings
* depending on what other options the parser knows about.
*
* If provided (i.e. not {@link ExpansionFunction}{@code .class}), the {@code expansion} field
* must not be set. The mechanism of expansion is as if the {@code expansion} field were set to
* whatever the return value of this function is.
*/
Class extends ExpansionFunction> expansionFunction() default ExpansionFunction.class;
/**
* If the option requires that additional options be implicitly appended, this field will contain
* the additional options. Implicit dependencies are parsed at the end of each {@link
* OptionsParser#parse} invocation, and override options specified in the same call. However, they
* can be overridden by options specified in a later call or by options with a higher priority.
*
* @see OptionPriority
*/
String[] implicitRequirements() default {};
/**
* If this field is a non-empty string, the option is deprecated, and a deprecation warning is
* added to the list of warnings when such an option is used.
*/
String deprecationWarning() default "";
/**
* The old name for this option. If an option has a name "foo" and an old name "bar", --foo=baz
* and --bar=baz will be equivalent. If the old name is used, a warning will be printed indicating
* that the old name is deprecated and the new name should be used.
*/
String oldName() default "";
/**
* Indicates that this option is a wrapper for other options, and will be unwrapped when parsed.
* For example, if foo is a wrapper option, then "--foo=--bar=baz" will be parsed as the flag
* "--bar=baz" (rather than --foo taking the value "--bar=baz"). A wrapper option should have the
* type {@link Void} (if it is something other than Void, the parser will not assign a value to
* it). The {@link Option#implicitRequirements()}, {@link Option#expansion()}, {@link
* Option#converter()} attributes will not be processed. Wrapper options are implicitly repeatable
* (i.e., as though {@link Option#allowMultiple()} is true regardless of its value in the
* annotation).
*
* Wrapper options are provided only for transitioning flags which appear as values to other
* flags, to top-level flags. Wrapper options should not be used in Invocation Policy, as
* expansion flags to other flags, or as implicit requirements to other flags. Use the inner flags
* instead.
*/
boolean wrapperOption() default false;
}