Add OptionDefinition layer between the @Option annotation and its fields and the options parser.
Removes any direct reads of the annotation outside of OptionDefinition. This allows for fewer manual checks for the annotation's existence, unifies error wording, and paves the way for potentially generifying the OptionsParser to accept different @Option-equivalent annotations.
Also allows for cleanup of duplicate code by giving @Option-specific operations a clear home, such as sorts and default logic. In followup changes, we can eliminate some unnecessarily complex caching by instead memoizing values in the OptionDefinition. This will have the positive side effect of making sure reads come from the cached values.
RELNOTES: None.
PiperOrigin-RevId: 166019075
diff --git a/src/main/java/com/google/devtools/build/lib/runtime/BlazeRuntime.java b/src/main/java/com/google/devtools/build/lib/runtime/BlazeRuntime.java
index e37a6ec..8d9f93c 100644
--- a/src/main/java/com/google/devtools/build/lib/runtime/BlazeRuntime.java
+++ b/src/main/java/com/google/devtools/build/lib/runtime/BlazeRuntime.java
@@ -15,7 +15,6 @@
package com.google.devtools.build.lib.runtime;
import com.google.common.annotations.VisibleForTesting;
-import com.google.common.base.Function;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Lists;
@@ -76,11 +75,12 @@
import com.google.devtools.build.lib.windows.WindowsSubprocessFactory;
import com.google.devtools.common.options.CommandNameCache;
import com.google.devtools.common.options.InvocationPolicyParser;
-import com.google.devtools.common.options.Option;
+import com.google.devtools.common.options.OptionDefinition;
import com.google.devtools.common.options.OptionPriority;
import com.google.devtools.common.options.OptionsBase;
import com.google.devtools.common.options.OptionsClassProvider;
import com.google.devtools.common.options.OptionsParser;
+import com.google.devtools.common.options.OptionsParser.ConstructionException;
import com.google.devtools.common.options.OptionsParsingException;
import com.google.devtools.common.options.OptionsProvider;
import com.google.devtools.common.options.TriState;
@@ -101,6 +101,7 @@
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;
+import java.util.function.Function;
import java.util.logging.Handler;
import java.util.logging.Level;
import java.util.logging.LogRecord;
@@ -652,11 +653,16 @@
}
for (Field field : startupFields) {
- if (field.isAnnotationPresent(Option.class)) {
- prefixes.add("--" + field.getAnnotation(Option.class).name());
+ try {
+ OptionDefinition optionDefinition = OptionDefinition.extractOptionDefinition(field);
+ prefixes.add("--" + optionDefinition.getOptionName());
if (field.getType() == boolean.class || field.getType() == TriState.class) {
- prefixes.add("--no" + field.getAnnotation(Option.class).name());
+ prefixes.add("--no" + optionDefinition.getOptionName());
}
+ } catch (ConstructionException e) {
+ // Do nothing, just ignore fields that are not actually options. OptionsBases technically
+ // shouldn't have fields that are not @Options, but this is a requirement that isn't yet
+ // being enforced, so this should not cause a failure here.
}
}