Switch android tools' use of options parser to a more concise form for the single options-base case.

This is to prepare the options parser from making options parser creation exceptions a caught exception. Since all of these classes already have a single options class and used parseAndExitUponError, this allows us to keep behavior consistent between the malformed options-base errors and the incorrect user-input errors.

All the other uses of the options parser in //src/tools already throw sufficiently broad exceptions to not need this.

RELNOTES: None
PiperOrigin-RevId: 165702786
diff --git a/src/main/java/com/google/devtools/common/options/Options.java b/src/main/java/com/google/devtools/common/options/Options.java
index c52e395..b636c09 100644
--- a/src/main/java/com/google/devtools/common/options/Options.java
+++ b/src/main/java/com/google/devtools/common/options/Options.java
@@ -14,6 +14,7 @@
 
 package com.google.devtools.common.options;
 
+import com.google.devtools.common.options.OptionsParser.ConstructionException;
 import java.util.Arrays;
 import java.util.List;
 
@@ -56,6 +57,26 @@
   }
 
   /**
+   * A convenience function for use in main methods. Parses the command line parameters, and exits
+   * upon error. Also, prints out the usage message if "--help" appears anywhere within {@code
+   * args}.
+   */
+  public static <O extends OptionsBase> Options<O> parseAndExitUponError(
+      Class<O> optionsClass, boolean allowResidue, String... args) {
+    OptionsParser parser = null;
+    try {
+      parser = OptionsParser.newOptionsParser(optionsClass);
+      parser.setAllowResidue(allowResidue);
+    } catch (ConstructionException e) {
+      System.err.println("Error constructing the options parser: " + e.getMessage());
+      System.exit(2);
+    }
+    parser.parseAndExitUponError(args);
+    List<String> remainingArgs = parser.getResidue();
+    return new Options<>(parser.getOptions(optionsClass), remainingArgs.toArray(new String[0]));
+  }
+
+  /**
    * Returns an options object at its default values.  The returned object may
    * be freely modified by the caller, by assigning its fields.
    */
diff --git a/src/tools/android/java/com/google/devtools/build/android/AarGeneratorAction.java b/src/tools/android/java/com/google/devtools/build/android/AarGeneratorAction.java
index f074a0c..62ad8fe 100644
--- a/src/tools/android/java/com/google/devtools/build/android/AarGeneratorAction.java
+++ b/src/tools/android/java/com/google/devtools/build/android/AarGeneratorAction.java
@@ -27,8 +27,8 @@
 import com.google.devtools.common.options.Option;
 import com.google.devtools.common.options.OptionDocumentationCategory;
 import com.google.devtools.common.options.OptionEffectTag;
+import com.google.devtools.common.options.Options;
 import com.google.devtools.common.options.OptionsBase;
-import com.google.devtools.common.options.OptionsParser;
 import java.io.BufferedOutputStream;
 import java.io.File;
 import java.io.IOException;
@@ -67,7 +67,7 @@
   private static final Logger logger = Logger.getLogger(AarGeneratorAction.class.getName());
 
   /** Flag specifications for this action. */
-  public static final class Options extends OptionsBase {
+  public static final class AarGeneratorOptions extends OptionsBase {
     @Option(
       name = "mainData",
       defaultValue = "null",
@@ -137,9 +137,9 @@
 
   public static void main(String[] args) {
     Stopwatch timer = Stopwatch.createStarted();
-    OptionsParser optionsParser = OptionsParser.newOptionsParser(Options.class);
-    optionsParser.parseAndExitUponError(args);
-    Options options = optionsParser.getOptions(Options.class);
+    AarGeneratorOptions options =
+        Options.parseAndExitUponError(AarGeneratorOptions.class, /*allowResidue=*/ true, args)
+            .getOptions();
 
     checkFlags(options);
 
@@ -181,7 +181,7 @@
   }
 
   @VisibleForTesting
-  static void checkFlags(Options options) throws IllegalArgumentException {
+  static void checkFlags(AarGeneratorOptions options) {
     List<String> nullFlags = new LinkedList<>();
     if (options.manifest == null) {
       nullFlags.add("manifest");
diff --git a/src/tools/android/java/com/google/devtools/build/android/desugar/Desugar.java b/src/tools/android/java/com/google/devtools/build/android/desugar/Desugar.java
index 5ba7699..63ca5e7 100644
--- a/src/tools/android/java/com/google/devtools/build/android/desugar/Desugar.java
+++ b/src/tools/android/java/com/google/devtools/build/android/desugar/Desugar.java
@@ -33,8 +33,8 @@
 import com.google.devtools.common.options.Option;
 import com.google.devtools.common.options.OptionDocumentationCategory;
 import com.google.devtools.common.options.OptionEffectTag;
+import com.google.devtools.common.options.Options;
 import com.google.devtools.common.options.OptionsBase;
-import com.google.devtools.common.options.OptionsParser;
 import com.google.errorprone.annotations.MustBeClosed;
 import java.io.IOError;
 import java.io.IOException;
@@ -65,7 +65,7 @@
 class Desugar {
 
   /** Commandline options for {@link Desugar}. */
-  public static class Options extends OptionsBase {
+  public static class DesugarOptions extends OptionsBase {
     @Option(
       name = "input",
       allowMultiple = true,
@@ -231,7 +231,7 @@
     public boolean coreLibrary;
   }
 
-  private final Options options;
+  private final DesugarOptions options;
   private final CoreLibraryRewriter rewriter;
   private final LambdaClassMaker lambdas;
   private final GeneratedClassStore store;
@@ -247,7 +247,7 @@
   /** An instance of Desugar is expected to be used ONLY ONCE */
   private boolean used;
 
-  private Desugar(Options options, Path dumpDirectory) {
+  private Desugar(DesugarOptions options, Path dumpDirectory) {
     this.options = options;
     this.rewriter = new CoreLibraryRewriter(options.coreLibrary ? "__desugar__/" : "");
     this.lambdas = new LambdaClassMaker(dumpDirectory);
@@ -590,7 +590,7 @@
     Path dumpDirectory = createAndRegisterLambdaDumpDirectory();
     verifyLambdaDumpDirectoryRegistered(dumpDirectory);
 
-    Options options = parseCommandLineOptions(args);
+    DesugarOptions options = parseCommandLineOptions(args);
     if (options.verbose) {
       System.out.printf("Lambda classes will be written under %s%n", dumpDirectory);
     }
@@ -646,16 +646,13 @@
     return dumpDirectory;
   }
 
-  private static Options parseCommandLineOptions(String[] args) throws IOException {
+  private static DesugarOptions parseCommandLineOptions(String[] args) throws IOException {
     if (args.length == 1 && args[0].startsWith("@")) {
       args = Files.readAllLines(Paths.get(args[0].substring(1)), ISO_8859_1).toArray(new String[0]);
     }
-
-    OptionsParser optionsParser = OptionsParser.newOptionsParser(Options.class);
-    optionsParser.setAllowResidue(false);
-    optionsParser.parseAndExitUponError(args);
-
-    Options options = optionsParser.getOptions(Options.class);
+    DesugarOptions options =
+        Options.parseAndExitUponError(DesugarOptions.class, /*allowResidue=*/ false, args)
+            .getOptions();
 
     checkArgument(!options.inputJars.isEmpty(), "--input is required");
     checkArgument(
@@ -672,7 +669,7 @@
     return options;
   }
 
-  private static ImmutableList<InputOutputPair> toInputOutputPairs(Options options) {
+  private static ImmutableList<InputOutputPair> toInputOutputPairs(DesugarOptions options) {
     final ImmutableList.Builder<InputOutputPair> ioPairListbuilder = ImmutableList.builder();
     for (Iterator<Path> inputIt = options.inputJars.iterator(),
             outputIt = options.outputJars.iterator();
diff --git a/src/tools/android/java/com/google/devtools/build/android/idlclass/IdlClass.java b/src/tools/android/java/com/google/devtools/build/android/idlclass/IdlClass.java
index fabf09a..3bce5c1 100644
--- a/src/tools/android/java/com/google/devtools/build/android/idlclass/IdlClass.java
+++ b/src/tools/android/java/com/google/devtools/build/android/idlclass/IdlClass.java
@@ -22,7 +22,7 @@
 import com.google.devtools.build.buildjar.jarhelper.JarCreator;
 import com.google.devtools.build.buildjar.proto.JavaCompilation.CompilationUnit;
 import com.google.devtools.build.buildjar.proto.JavaCompilation.Manifest;
-import com.google.devtools.common.options.OptionsParser;
+import com.google.devtools.common.options.Options;
 import java.io.IOException;
 import java.io.InputStream;
 import java.nio.file.Files;
@@ -42,23 +42,24 @@
 public class IdlClass {
 
   public static void main(String[] args) throws IOException {
-    OptionsParser optionsParser = OptionsParser.newOptionsParser(IdlClassOptions.class);
-    optionsParser.parseAndExitUponError(args);
-    IdlClassOptions options = optionsParser.getOptions(IdlClassOptions.class);
-    Preconditions.checkNotNull(options.manifestProto);
-    Preconditions.checkNotNull(options.classJar);
-    Preconditions.checkNotNull(options.outputClassJar);
-    Preconditions.checkNotNull(options.outputSourceJar);
-    Preconditions.checkNotNull(options.tempDir);
+    Options<IdlClassOptions> options =
+        Options.parseAndExitUponError(IdlClassOptions.class, /*allowResidue=*/ true, args);
+
+    IdlClassOptions idlClassOptions = options.getOptions();
+    Preconditions.checkNotNull(idlClassOptions.manifestProto);
+    Preconditions.checkNotNull(idlClassOptions.classJar);
+    Preconditions.checkNotNull(idlClassOptions.outputClassJar);
+    Preconditions.checkNotNull(idlClassOptions.outputSourceJar);
+    Preconditions.checkNotNull(idlClassOptions.tempDir);
 
     List<Path> idlSources = Lists.newArrayList();
-    for (String idlSource : optionsParser.getResidue()) {
+    for (String idlSource : options.getRemainingArgs()) {
       idlSources.add(Paths.get(idlSource));
     }
 
-    Manifest manifest = readManifest(options.manifestProto);
-    writeClassJar(options, idlSources, manifest);
-    writeSourceJar(options, idlSources, manifest);
+    Manifest manifest = readManifest(idlClassOptions.manifestProto);
+    writeClassJar(idlClassOptions, idlSources, manifest);
+    writeSourceJar(idlClassOptions, idlSources, manifest);
   }
 
   private static void writeClassJar(IdlClassOptions options,
diff --git a/src/tools/android/java/com/google/devtools/build/android/ziputils/BUILD b/src/tools/android/java/com/google/devtools/build/android/ziputils/BUILD
index 4f88bf7..81fc56c 100644
--- a/src/tools/android/java/com/google/devtools/build/android/ziputils/BUILD
+++ b/src/tools/android/java/com/google/devtools/build/android/ziputils/BUILD
@@ -75,6 +75,7 @@
     deps = [
         ":ziputils_lib",
         "//src/main/java/com/google/devtools/common/options",
+        "//third_party:guava",
     ],
 )
 
diff --git a/src/tools/android/java/com/google/devtools/build/android/ziputils/DexMapper.java b/src/tools/android/java/com/google/devtools/build/android/ziputils/DexMapper.java
index e26db4f..9318791 100644
--- a/src/tools/android/java/com/google/devtools/build/android/ziputils/DexMapper.java
+++ b/src/tools/android/java/com/google/devtools/build/android/ziputils/DexMapper.java
@@ -19,8 +19,8 @@
 import com.google.devtools.common.options.Option;
 import com.google.devtools.common.options.OptionDocumentationCategory;
 import com.google.devtools.common.options.OptionEffectTag;
+import com.google.devtools.common.options.Options;
 import com.google.devtools.common.options.OptionsBase;
-import com.google.devtools.common.options.OptionsParser;
 import java.util.List;
 
 /**
@@ -36,9 +36,9 @@
    * @param args the command line arguments
    */
   public static void main(String[] args) {
-    OptionsParser optionsParser = OptionsParser.newOptionsParser(Options.class);
-    optionsParser.parseAndExitUponError(args);
-    Options options = optionsParser.getOptions(Options.class);
+    DexMapperOptions options =
+        Options.parseAndExitUponError(DexMapperOptions.class, /*allowResidue=*/ true, args)
+            .getOptions();
     List<String> inputs = options.inputJars;
     List<String> outputs = options.outputJars;
     String filterFile = options.mainDexFilter;
@@ -67,10 +67,8 @@
     }
   }
 
-  /**
-   * Commandline options.
-   */
-  public static class Options extends OptionsBase {
+  /** Commandline options. */
+  public static class DexMapperOptions extends OptionsBase {
     @Option(
       name = "input_jar",
       defaultValue = "null",
diff --git a/src/tools/android/java/com/google/devtools/build/android/ziputils/DexReducer.java b/src/tools/android/java/com/google/devtools/build/android/ziputils/DexReducer.java
index 2ba1d9d..91f1a56 100644
--- a/src/tools/android/java/com/google/devtools/build/android/ziputils/DexReducer.java
+++ b/src/tools/android/java/com/google/devtools/build/android/ziputils/DexReducer.java
@@ -27,8 +27,8 @@
 import com.google.devtools.common.options.Option;
 import com.google.devtools.common.options.OptionDocumentationCategory;
 import com.google.devtools.common.options.OptionEffectTag;
+import com.google.devtools.common.options.Options;
 import com.google.devtools.common.options.OptionsBase;
-import com.google.devtools.common.options.OptionsParser;
 import java.io.FileInputStream;
 import java.io.FileOutputStream;
 import java.io.IOException;
@@ -73,9 +73,9 @@
   }
 
   private void parseArguments(String[] args) {
-    OptionsParser optionsParser = OptionsParser.newOptionsParser(Options.class);
-    optionsParser.parseAndExitUponError(args);
-    Options options = optionsParser.getOptions(Options.class);
+    DexReducerOptions options =
+        Options.parseAndExitUponError(DexReducerOptions.class, /*allowResidue=*/ true, args)
+            .getOptions();
     paths = options.inputZips;
     outFile = options.outputZip;
   }
@@ -112,10 +112,8 @@
     }
   }
 
-  /**
-   * Commandline options.
-   */
-  public static class Options extends OptionsBase {
+  /** Commandline options. */
+  public static class DexReducerOptions extends OptionsBase {
     @Option(
       name = "input_zip",
       defaultValue = "null",