diff options
author | 2017-09-12 19:57:36 +0200 | |
---|---|---|
committer | 2017-09-13 19:05:52 +0200 | |
commit | 7da54b5e2942bdb444abbf68ac3c7f34a453b4d9 (patch) | |
tree | 3ecc7406b36b9de0e964eb39ee08d395f65012c6 /src/main | |
parent | bdc0aef8cd3f064f5b16a5547f9d543c81d57c8f (diff) |
Move option value tracking classes to their own file.
These classes are mostly used during the options parsing process itself, and are barely a part of the options parser interface, so they really don't belong in OptionsParser.java. They are also about to change significantly, so taking this opportunity to split them out.
RELNOTES: None.
PiperOrigin-RevId: 168400162
Diffstat (limited to 'src/main')
7 files changed, 308 insertions, 274 deletions
diff --git a/src/main/java/com/google/devtools/build/lib/util/OptionsUtils.java b/src/main/java/com/google/devtools/build/lib/util/OptionsUtils.java index 3013f3e23e..ab4872aa08 100644 --- a/src/main/java/com/google/devtools/build/lib/util/OptionsUtils.java +++ b/src/main/java/com/google/devtools/build/lib/util/OptionsUtils.java @@ -18,9 +18,9 @@ import com.google.common.collect.ImmutableList; import com.google.devtools.build.lib.vfs.PathFragment; import com.google.devtools.common.options.Converter; import com.google.devtools.common.options.Converters; -import com.google.devtools.common.options.OptionsParser.UnparsedOptionValueDescription; import com.google.devtools.common.options.OptionsParsingException; import com.google.devtools.common.options.OptionsProvider; +import com.google.devtools.common.options.UnparsedOptionValueDescription; import java.util.ArrayList; import java.util.Collections; import java.util.List; diff --git a/src/main/java/com/google/devtools/common/options/InvocationPolicyEnforcer.java b/src/main/java/com/google/devtools/common/options/InvocationPolicyEnforcer.java index 73c6c5e2bd..e8a84f032a 100644 --- a/src/main/java/com/google/devtools/common/options/InvocationPolicyEnforcer.java +++ b/src/main/java/com/google/devtools/common/options/InvocationPolicyEnforcer.java @@ -28,7 +28,6 @@ import com.google.devtools.build.lib.runtime.proto.InvocationPolicyOuterClass.In import com.google.devtools.build.lib.runtime.proto.InvocationPolicyOuterClass.SetValue; import com.google.devtools.build.lib.runtime.proto.InvocationPolicyOuterClass.UseDefault; import com.google.devtools.common.options.OptionsParser.OptionDescription; -import com.google.devtools.common.options.OptionsParser.OptionValueDescription; import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; diff --git a/src/main/java/com/google/devtools/common/options/OptionValueDescription.java b/src/main/java/com/google/devtools/common/options/OptionValueDescription.java new file mode 100644 index 0000000000..8e16287ccc --- /dev/null +++ b/src/main/java/com/google/devtools/common/options/OptionValueDescription.java @@ -0,0 +1,191 @@ +// Copyright 2017 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 com.google.common.base.Preconditions; +import com.google.common.collect.ListMultimap; +import java.util.ArrayList; +import java.util.List; +import javax.annotation.Nullable; + +/** + * The name and value of an option with additional metadata describing its priority, source, whether + * it was set via an implicit dependency, and if so, by which other option. + */ +public class OptionValueDescription { + private final OptionDefinition optionDefinition; + private final boolean isDefaultValue; + @Nullable private final String originalValueString; + @Nullable private final Object value; + @Nullable private final OptionPriority priority; + @Nullable private final String source; + @Nullable private final OptionDefinition implicitDependant; + @Nullable private final OptionDefinition expandedFrom; + + private OptionValueDescription( + OptionDefinition optionDefinition, + boolean isDefaultValue, + @Nullable String originalValueString, + @Nullable Object value, + @Nullable OptionPriority priority, + @Nullable String source, + @Nullable OptionDefinition implicitDependant, + @Nullable OptionDefinition expandedFrom) { + this.optionDefinition = optionDefinition; + this.isDefaultValue = isDefaultValue; + this.originalValueString = originalValueString; + this.value = value; + this.priority = priority; + this.source = source; + this.implicitDependant = implicitDependant; + this.expandedFrom = expandedFrom; + } + + public static OptionValueDescription newOptionValue( + OptionDefinition optionDefinition, + @Nullable String originalValueString, + @Nullable Object value, + @Nullable OptionPriority priority, + @Nullable String source, + @Nullable OptionDefinition implicitDependant, + @Nullable OptionDefinition expandedFrom) { + return new OptionValueDescription( + optionDefinition, + false, + originalValueString, + value, + priority, + source, + implicitDependant, + expandedFrom); + } + + public static OptionValueDescription newDefaultValue(OptionDefinition optionDefinition) { + return new OptionValueDescription( + optionDefinition, true, null, null, OptionPriority.DEFAULT, null, null, null); + } + + public OptionDefinition getOptionDefinition() { + return optionDefinition; + } + + public String getName() { + return optionDefinition.getOptionName(); + } + + public String getOriginalValueString() { + return originalValueString; + } + + // Need to suppress unchecked warnings, because the "multiple occurrence" + // options use unchecked ListMultimaps due to limitations of Java generics. + @SuppressWarnings({"unchecked", "rawtypes"}) + public Object getValue() { + if (isDefaultValue) { + // If no value was present, we want the default value for this option. + return optionDefinition.getDefaultValue(); + } + if (getAllowMultiple() && value != null) { + // Sort the results by option priority and return them in a new list. + // The generic type of the list is not known at runtime, so we can't + // use it here. It was already checked in the constructor, so this is + // type-safe. + List result = new ArrayList<>(); + ListMultimap realValue = (ListMultimap) value; + for (OptionPriority priority : OptionPriority.values()) { + // If there is no mapping for this key, this check avoids object creation (because + // ListMultimap has to return a new object on get) and also an unnecessary addAll call. + if (realValue.containsKey(priority)) { + result.addAll(realValue.get(priority)); + } + } + return result; + } + return value; + } + + /** + * @return the priority of the thing that set this value for this flag + */ + public OptionPriority getPriority() { + return priority; + } + + /** + * @return the thing that set this value for this flag + */ + public String getSource() { + return source; + } + + public OptionDefinition getImplicitDependant() { + return implicitDependant; + } + + public boolean isImplicitDependency() { + return implicitDependant != null; + } + + public OptionDefinition getExpansionParent() { + return expandedFrom; + } + + public boolean isExpansion() { + return expandedFrom != null; + } + + public boolean getAllowMultiple() { + return optionDefinition.allowsMultiple(); + } + + @Override + public String toString() { + StringBuilder result = new StringBuilder(); + result.append("option '").append(optionDefinition.getOptionName()).append("' "); + if (isDefaultValue) { + result + .append("set to its default value: '") + .append(optionDefinition.getUnparsedDefaultValue()) + .append("'"); + return result.toString(); + } else { + result.append("set to '").append(value).append("' "); + result.append("with priority ").append(priority); + if (source != null) { + result.append(" and source '").append(source).append("'"); + } + if (implicitDependant != null) { + result.append(" implicitly by "); + } + return result.toString(); + } + } + + // Need to suppress unchecked warnings, because the "multiple occurrence" + // options use unchecked ListMultimaps due to limitations of Java generics. + @SuppressWarnings({"unchecked", "rawtypes"}) + void addValue(OptionPriority addedPriority, Object addedValue) { + Preconditions.checkState(optionDefinition.allowsMultiple()); + Preconditions.checkState(!isDefaultValue); + ListMultimap optionValueList = (ListMultimap) value; + if (addedValue instanceof List<?>) { + optionValueList.putAll(addedPriority, (List<?>) addedValue); + } else { + optionValueList.put(addedPriority, addedValue); + } + } +} + + diff --git a/src/main/java/com/google/devtools/common/options/OptionsParser.java b/src/main/java/com/google/devtools/common/options/OptionsParser.java index 5bf1b4d4ac..1d41e3dfbf 100644 --- a/src/main/java/com/google/devtools/common/options/OptionsParser.java +++ b/src/main/java/com/google/devtools/common/options/OptionsParser.java @@ -19,7 +19,6 @@ import com.google.common.base.Preconditions; import com.google.common.base.Throwables; import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableMap; -import com.google.common.collect.ListMultimap; import com.google.common.escape.Escaper; import com.google.devtools.common.options.OptionDefinition.NotAnOptionException; import java.lang.reflect.Constructor; @@ -267,268 +266,6 @@ public class OptionsParser implements OptionsProvider { } /** - * The name and value of an option with additional metadata describing its - * priority, source, whether it was set via an implicit dependency, and if so, - * by which other option. - */ - public static class OptionValueDescription { - private final OptionDefinition optionDefinition; - private final boolean isDefaultValue; - @Nullable private final String originalValueString; - @Nullable private final Object value; - @Nullable private final OptionPriority priority; - @Nullable private final String source; - @Nullable private final OptionDefinition implicitDependant; - @Nullable private final OptionDefinition expandedFrom; - - private OptionValueDescription( - OptionDefinition optionDefinition, - boolean isDefaultValue, - @Nullable String originalValueString, - @Nullable Object value, - @Nullable OptionPriority priority, - @Nullable String source, - @Nullable OptionDefinition implicitDependant, - @Nullable OptionDefinition expandedFrom) { - this.optionDefinition = optionDefinition; - this.isDefaultValue = isDefaultValue; - this.originalValueString = originalValueString; - this.value = value; - this.priority = priority; - this.source = source; - this.implicitDependant = implicitDependant; - this.expandedFrom = expandedFrom; - } - - public static OptionValueDescription newOptionValue( - OptionDefinition optionDefinition, - @Nullable String originalValueString, - @Nullable Object value, - @Nullable OptionPriority priority, - @Nullable String source, - @Nullable OptionDefinition implicitDependant, - @Nullable OptionDefinition expandedFrom) { - return new OptionValueDescription( - optionDefinition, - false, - originalValueString, - value, - priority, - source, - implicitDependant, - expandedFrom); - } - - public static OptionValueDescription newDefaultValue(OptionDefinition optionDefinition) { - return new OptionValueDescription( - optionDefinition, true, null, null, OptionPriority.DEFAULT, null, null, null); - } - - public OptionDefinition getOptionDefinition() { - return optionDefinition; - } - - public String getName() { - return optionDefinition.getOptionName(); - } - - public String getOriginalValueString() { - return originalValueString; - } - - // Need to suppress unchecked warnings, because the "multiple occurrence" - // options use unchecked ListMultimaps due to limitations of Java generics. - @SuppressWarnings({"unchecked", "rawtypes"}) - public Object getValue() { - if (isDefaultValue) { - // If no value was present, we want the default value for this option. - return optionDefinition.getDefaultValue(); - } - if (getAllowMultiple() && value != null) { - // Sort the results by option priority and return them in a new list. - // The generic type of the list is not known at runtime, so we can't - // use it here. It was already checked in the constructor, so this is - // type-safe. - List result = new ArrayList<>(); - ListMultimap realValue = (ListMultimap) value; - for (OptionPriority priority : OptionPriority.values()) { - // If there is no mapping for this key, this check avoids object creation (because - // ListMultimap has to return a new object on get) and also an unnecessary addAll call. - if (realValue.containsKey(priority)) { - result.addAll(realValue.get(priority)); - } - } - return result; - } - return value; - } - - /** - * @return the priority of the thing that set this value for this flag - */ - public OptionPriority getPriority() { - return priority; - } - - /** - * @return the thing that set this value for this flag - */ - public String getSource() { - return source; - } - - public OptionDefinition getImplicitDependant() { - return implicitDependant; - } - - public boolean isImplicitDependency() { - return implicitDependant != null; - } - - public OptionDefinition getExpansionParent() { - return expandedFrom; - } - - public boolean isExpansion() { - return expandedFrom != null; - } - - public boolean getAllowMultiple() { - return optionDefinition.allowsMultiple(); - } - - @Override - public String toString() { - StringBuilder result = new StringBuilder(); - result.append("option '").append(optionDefinition.getOptionName()).append("' "); - if (isDefaultValue) { - result - .append("set to its default value: '") - .append(optionDefinition.getUnparsedDefaultValue()) - .append("'"); - return result.toString(); - } else { - result.append("set to '").append(value).append("' "); - result.append("with priority ").append(priority); - if (source != null) { - result.append(" and source '").append(source).append("'"); - } - if (implicitDependant != null) { - result.append(" implicitly by "); - } - return result.toString(); - } - } - - // Need to suppress unchecked warnings, because the "multiple occurrence" - // options use unchecked ListMultimaps due to limitations of Java generics. - @SuppressWarnings({"unchecked", "rawtypes"}) - void addValue(OptionPriority addedPriority, Object addedValue) { - Preconditions.checkState(optionDefinition.allowsMultiple()); - Preconditions.checkState(!isDefaultValue); - ListMultimap optionValueList = (ListMultimap) value; - if (addedValue instanceof List<?>) { - optionValueList.putAll(addedPriority, (List<?>) addedValue); - } else { - optionValueList.put(addedPriority, addedValue); - } - } - } - - /** - * The name and unparsed value of an option with additional metadata describing its - * priority, source, whether it was set via an implicit dependency, and if so, - * by which other option. - * - * <p>Note that the unparsed value and the source parameters can both be null. - */ - public static class UnparsedOptionValueDescription { - - private final OptionDefinition optionDefinition; - @Nullable private final String unparsedValue; - private final OptionPriority priority; - @Nullable private final String source; - private final boolean explicit; - - public UnparsedOptionValueDescription( - OptionDefinition optionDefinition, - @Nullable String unparsedValue, - OptionPriority priority, - @Nullable String source, - boolean explicit) { - this.optionDefinition = optionDefinition; - this.unparsedValue = unparsedValue; - this.priority = priority; - this.source = source; - this.explicit = explicit; - } - - public String getName() { - return optionDefinition.getOptionName(); - } - OptionDefinition getOptionDefinition() { - return optionDefinition; - } - - public boolean isBooleanOption() { - return optionDefinition.getType().equals(boolean.class); - } - - private OptionDocumentationCategory documentationCategory() { - return optionDefinition.getDocumentationCategory(); - } - - private ImmutableList<OptionMetadataTag> metadataTags() { - return ImmutableList.copyOf(optionDefinition.getOptionMetadataTags()); - } - - public boolean isDocumented() { - return documentationCategory() != OptionDocumentationCategory.UNDOCUMENTED && !isHidden(); - } - - public boolean isHidden() { - ImmutableList<OptionMetadataTag> tags = metadataTags(); - return tags.contains(OptionMetadataTag.HIDDEN) || tags.contains(OptionMetadataTag.INTERNAL); - } - - boolean isExpansion() { - return optionDefinition.isExpansionOption(); - } - - boolean isImplicitRequirement() { - return optionDefinition.getImplicitRequirements().length > 0; - } - - public String getUnparsedValue() { - return unparsedValue; - } - - OptionPriority getPriority() { - return priority; - } - - public String getSource() { - return source; - } - - public boolean isExplicit() { - return explicit; - } - - @Override - public String toString() { - StringBuilder result = new StringBuilder(); - result.append("option '").append(optionDefinition.getOptionName()).append("' "); - result.append("set to '").append(unparsedValue).append("' "); - result.append("with priority ").append(priority); - if (source != null) { - result.append(" and source '").append(source).append("'"); - } - return result.toString(); - } - } - - /** * The verbosity with which option help messages are displayed: short (just * the name), medium (name, type, default, abbreviation), and long (full * description). @@ -676,8 +413,8 @@ public class OptionsParser implements OptionsProvider { * Returns a description of the options values that get expanded from this option with the given * value. * - * @return The {@link ImmutableList<OptionValueDescription>} for the option, or null if there is - * no option by the given name. + * @return The {@link com.google.devtools.common.options.OptionValueDescriptionlueDescription>} + * for the option, or null if there is no option by the given name. */ ImmutableList<OptionValueDescription> getExpansionOptionValueDescriptions( OptionDefinition option, @Nullable String optionValue) throws OptionsParsingException { @@ -690,8 +427,8 @@ public class OptionsParser implements OptionsProvider { * of type {@link List}, the description will correspond to any one of the calls, but not * necessarily the last. * - * @return The {@link OptionValueDescription} for the option, or null if the value has not been - * set. + * @return The {@link com.google.devtools.common.options.OptionValueDescription} for the option, + * or null if the value has not been set. * @throws IllegalArgumentException if there is no option by the given name. */ OptionValueDescription getOptionValueDescription(String name) { diff --git a/src/main/java/com/google/devtools/common/options/OptionsParserImpl.java b/src/main/java/com/google/devtools/common/options/OptionsParserImpl.java index 7478ab8e2d..3ac891000f 100644 --- a/src/main/java/com/google/devtools/common/options/OptionsParserImpl.java +++ b/src/main/java/com/google/devtools/common/options/OptionsParserImpl.java @@ -25,8 +25,6 @@ import com.google.common.collect.Iterators; import com.google.common.collect.LinkedHashMultimap; import com.google.common.collect.Multimap; import com.google.devtools.common.options.OptionsParser.OptionDescription; -import com.google.devtools.common.options.OptionsParser.OptionValueDescription; -import com.google.devtools.common.options.OptionsParser.UnparsedOptionValueDescription; import java.lang.reflect.Constructor; import java.util.ArrayList; import java.util.Arrays; diff --git a/src/main/java/com/google/devtools/common/options/OptionsProvider.java b/src/main/java/com/google/devtools/common/options/OptionsProvider.java index 040aa055a3..ab420601eb 100644 --- a/src/main/java/com/google/devtools/common/options/OptionsProvider.java +++ b/src/main/java/com/google/devtools/common/options/OptionsProvider.java @@ -14,9 +14,6 @@ package com.google.devtools.common.options; -import com.google.devtools.common.options.OptionsParser.OptionValueDescription; -import com.google.devtools.common.options.OptionsParser.UnparsedOptionValueDescription; - import java.util.List; /** diff --git a/src/main/java/com/google/devtools/common/options/UnparsedOptionValueDescription.java b/src/main/java/com/google/devtools/common/options/UnparsedOptionValueDescription.java new file mode 100644 index 0000000000..4f63d0d2bd --- /dev/null +++ b/src/main/java/com/google/devtools/common/options/UnparsedOptionValueDescription.java @@ -0,0 +1,112 @@ +// Copyright 2017 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 com.google.common.collect.ImmutableList; +import javax.annotation.Nullable; + +/** + * The name and unparsed value of an option with additional metadata describing its priority, + * source, whether it was set via an implicit dependency, and if so, by which other option. + * + * <p>Note that the unparsed value and the source parameters can both be null. + */ +public final class UnparsedOptionValueDescription { + + private final OptionDefinition optionDefinition; + @Nullable private final String unparsedValue; + private final OptionPriority priority; + @Nullable private final String source; + private final boolean explicit; + + public UnparsedOptionValueDescription( + OptionDefinition optionDefinition, + @Nullable String unparsedValue, + OptionPriority priority, + @Nullable String source, + boolean explicit) { + this.optionDefinition = optionDefinition; + this.unparsedValue = unparsedValue; + this.priority = priority; + this.source = source; + this.explicit = explicit; + } + + public String getName() { + return optionDefinition.getOptionName(); + } + + OptionDefinition getOptionDefinition() { + return optionDefinition; + } + + public boolean isBooleanOption() { + return optionDefinition.getType().equals(boolean.class); + } + + private OptionDocumentationCategory documentationCategory() { + return optionDefinition.getDocumentationCategory(); + } + + private ImmutableList<OptionMetadataTag> metadataTags() { + return ImmutableList.copyOf(optionDefinition.getOptionMetadataTags()); + } + + public boolean isDocumented() { + return documentationCategory() != OptionDocumentationCategory.UNDOCUMENTED && !isHidden(); + } + + public boolean isHidden() { + ImmutableList<OptionMetadataTag> tags = metadataTags(); + return tags.contains(OptionMetadataTag.HIDDEN) || tags.contains(OptionMetadataTag.INTERNAL); + } + + boolean isExpansion() { + return optionDefinition.isExpansionOption(); + } + + boolean isImplicitRequirement() { + return optionDefinition.getImplicitRequirements().length > 0; + } + + public String getUnparsedValue() { + return unparsedValue; + } + + OptionPriority getPriority() { + return priority; + } + + public String getSource() { + return source; + } + + public boolean isExplicit() { + return explicit; + } + + @Override + public String toString() { + StringBuilder result = new StringBuilder(); + result.append("option '").append(optionDefinition.getOptionName()).append("' "); + result.append("set to '").append(unparsedValue).append("' "); + result.append("with priority ").append(priority); + if (source != null) { + result.append(" and source '").append(source).append("'"); + } + return result.toString(); + } +} + |