public void usage(PrintStream out, boolean showSecretMenu) {
    usageHeader(out);

    boolean firstSecretItem = true;
    List<OptFlag<?>> sorted = new ArrayList<>(flags);
    Collections.sort(sorted, null);
    for (OptFlag<?> flag : sorted) {
      boolean isSecret = flag.kind.compareTo(Kind.SECRET) >= 0;
      if (showSecretMenu && isSecret && firstSecretItem) {
        out.println();
        out.println("Secret menu:");
        firstSecretItem = false;
      }

      if (showSecretMenu || !isSecret) flag.printUsage(out);
    }
  }
 /**
  * Iterates over arguments parsed from the command line and applies them to this object. Any
  * source arguments are added to {@code source}.
  *
  * @param source The set of source filenames provided on the command line.
  */
 public void printCommandLine(PrintStream out) {
   Set<OptFlag<?>> seen = new LinkedHashSet<>();
   for (Arg<?> arg : arguments) {
     if (arg.flag != null) {
       seen.add(arg.flag);
     }
     out.print(" " + arg.toString());
   }
   for (OptFlag<?> flag : flags) {
     if (seen.contains(flag)) continue;
     else {
       Arg<?> arg = flag.defaultArg(arguments);
       if (arg != null) out.print(" " + arg.toString());
     }
   }
   out.println();
 }
  /**
   * Parse a command
   *
   * @return the next index to process. i.e., if calling this method processes two commands, then
   *     the return value should be index+2
   */
  protected int parseCommand(String args[], int index, Set<String> source)
      throws UsageError, Main.TerminationException {
    // Find a flag whose id matches args[index] and let it process the
    // arguments.
    for (OptFlag<?> flag : flags) {
      if (flag.ids.contains(args[index])) {
        Arg<?> arg = flag.handle(args, index + 1);
        arguments.add(arg);
        return arg.next();
      }
    }

    if (!args[index].startsWith("-")) {
      index = parseSourceArg(args, index);
    }

    return index;
  }
  /**
   * Validates the arguments parsed from the command line.
   *
   * @throws UsageError if the arguments are invalid.
   */
  protected void validateArgs() throws UsageError {
    if (arguments.size() < 1) {
      throw new UsageError("No command line arguments given");
    }

    if (!OptFlag.hasSourceArg(arguments)) {
      throw new UsageError("must specify at least one source file");
    }
  }
 public Options(ExtensionInfo extension, boolean checkFlags) {
   this.extension = extension;
   flags = new LinkedHashSet<>();
   arguments = new ArrayList<>();
   populateFlags(flags);
   if (checkFlags) {
     Set<String> ids = new LinkedHashSet<>();
     for (OptFlag<?> flag : flags) {
       for (String id : flag.ids()) {
         if (!ids.add(id)) {
           throw new InternalCompilerError(
               "Flag " + flag.ids() + " conflicts with " + OptFlag.lookupFlag(id, flags).ids());
         }
       }
     }
   }
   setDefaultValues();
 }
  /**
   * Iterates over arguments parsed from the command line and applies them to this object. Any
   * source arguments are added to {@code source}.
   *
   * @param source The set of source filenames provided on the command line.
   */
  protected final void applyArgs(Set<String> source) throws UsageError {
    // Set up defaults first.
    for (OptFlag<?> flag : flags) {
      Arg<?> arg = flag.defaultArg(arguments);
      if (arg != null) handleArg(arg);
    }

    // Let user-specified arguments override the defaults.
    for (Arg<?> arg : arguments) {
      if (arg.flag == null) {
        handleSourceArg(arg, source);
      } else {
        try {
          handleArg(arg);
        } catch (UsageError e) {
          throw e;
        } catch (Throwable e) {
          throw new InternalCompilerError(
              "Error while handling arg " + arg + " created by " + arg.flag().getClass(), e);
        }
      }
    }
  }