1 /*
   2  * Copyright (c) 2012, 2019, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.  Oracle designates this
   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 
  26 package jdk.javadoc.internal.tool;
  27 
  28 import java.util.ArrayList;
  29 import java.util.Arrays;
  30 import java.util.LinkedHashMap;
  31 import java.util.List;
  32 import java.util.Map;
  33 import javax.lang.model.element.ElementKind;
  34 
  35 import com.sun.tools.javac.main.Option;
  36 import com.sun.tools.javac.main.Option.InvalidValueException;
  37 import com.sun.tools.javac.main.OptionHelper;
  38 import com.sun.tools.javac.util.Context;
  39 import com.sun.tools.javac.util.Options;
  40 
  41 import static jdk.javadoc.internal.tool.Main.Result.OK;
  42 import static jdk.javadoc.internal.tool.ToolOptions.ToolOption.Kind.*;
  43 
  44 /**
  45  * Storage and support for javadoc tool options, as distinct from
  46  * the options supported by any doclet that may be in use.
  47  * The tool options includes those options which are delegated
  48  * to javac and/or the file manager, such as options to set
  49  * the source level, and path options to locate the files to be
  50  * documented.
  51  *
  52  *  <p><b>This is NOT part of any supported API.
  53  *  If you write code that depends on this, you do so at your own risk.
  54  *  This code and its internal interfaces are subject to change or
  55  *  deletion without notice.</b>
  56  */
  57 public class ToolOptions {
  58     // The following are the names of options handled in the first pass of option decoding,
  59     // in Start.preprocess.
  60     static final String DOCLET = "-doclet";
  61     static final String DOCLET_PATH = "-docletpath";
  62     static final String DUMP_ON_ERROR = "--dump-on-error";
  63     static final String J = "-J";
  64     static final String LOCALE = "-locale";
  65 
  66     /**
  67      * Argument for command-line option {@code -breakiterator}.
  68      */
  69     private boolean breakIterator = false;
  70 
  71     /**
  72      * Argument for command-line option {@code -locale}.
  73      */
  74     private String docLocale = "";
  75 
  76     /**
  77      * Argument for command-line option {@code --dump-on-error}.
  78      * Dump stack traces for debugging etc.
  79      * Similar to javac {@code -doe}.
  80      */
  81     private boolean dumpOnError = false;
  82 
  83     /**
  84      * Argument for command-line option {@code -exclude}.
  85      */
  86     private List<String> excludes = new ArrayList<>();
  87 
  88     /**
  89      * Argument for command-line option {@code --expand-requires}.
  90      */
  91     private AccessKind expandRequires;
  92 
  93     /**
  94      * Argument for command-line option {@code --ignore-source-errors}.
  95      */
  96     private boolean ignoreSourceErrors;
  97 
  98     /**
  99      * Argument for command-line option {@code --module}.
 100      */
 101     private List<String> modules = new ArrayList<>();
 102 
 103     /**
 104      * Argument for command-line option {@code -Xwerror}.
 105      * Set by -Xwerror.
 106      */
 107     private boolean rejectWarnings = false;
 108 
 109     /**
 110      * Argument for command-line option {@code --show-members}.
 111      */
 112     private AccessKind showMembersAccess;
 113 
 114     /**
 115      * Argument for command-line option {@code --show-types}.
 116      */
 117     private AccessKind showTypesAccess;
 118 
 119     /**
 120      * Argument for command-line option {@code --show-packages}.
 121      */
 122     private AccessKind showPackagesAccess;
 123 
 124     /**
 125      * Argument for command-line option {@code --show-module-contents}.
 126      */
 127     private AccessKind showModuleContents;
 128 
 129     /**
 130      * Argument for command-line option {@code -quiet}.
 131      */
 132     private boolean quiet;
 133 
 134     /**
 135      * Argument for command-line option {@code -subpackages}.
 136      */
 137     private List<String> subpackages = new ArrayList<>();
 138 
 139     /**
 140      * Argument for command-line option {@code -verbose}.
 141      */
 142     private boolean verbose;
 143 
 144     /**
 145      * Argument for command-line option {@code -xclasses}.
 146      * If true, names on the command line that would normally be
 147      * treated as package names are treated as class names instead.
 148      */
 149     private boolean xclasses = false;
 150 
 151     /**
 152      * Options to be given to the file manager, such as path options
 153      * indicating where to find files to be documented.
 154      */
 155     private final Map<Option, String> fileManagerOpts;
 156 
 157     /**
 158      * Options to be given to the underlying compiler front-end,
 159      * such as options to indicate the source level to be used.
 160      */
 161     private final Options compOpts;
 162 
 163     /**
 164      * The "helper" to be used when processing compiler options.
 165      */
 166     private final OptionHelper compilerOptionHelper;
 167 
 168     /**
 169      * The messager to be used to report diagnostics..
 170      */
 171     private final Messager messager;
 172 
 173     /**
 174      * The helper for help and version options
 175      */
 176     private final ShowHelper showHelper;
 177 
 178     /**
 179      * Creates an object to handle tool options.
 180      *
 181      * @param context the context used to find other tool-related components
 182      * @param messager the messager to be used to report diagnostics
 183      */
 184     ToolOptions(Context context, Messager messager, ShowHelper showHelper) {
 185         this.messager = messager;
 186         this.showHelper = showHelper;
 187         compOpts = Options.instance(context);
 188         fileManagerOpts = new LinkedHashMap<>();
 189         compilerOptionHelper = getOptionHelper();
 190         setAccessDefault();
 191     }
 192 
 193     /**
 194      * Creates a minimal object, just sufficient to check the names of the
 195      * supported options.
 196      */
 197     private ToolOptions() {
 198         compOpts = null;
 199         compilerOptionHelper = null;
 200         fileManagerOpts = null;
 201         messager = null;
 202         showHelper = null;
 203     }
 204 
 205     /**
 206      * Returns the set of options supported by the tool, excluding any options
 207      * that are managed by the doclet that may be in use.
 208      *
 209      * @return the set of options
 210      */
 211     public List<ToolOption> getSupportedOptions() {
 212         return supportedOptions;
 213     }
 214 
 215     /**
 216      * Determines if the given option is supported and if so, the
 217      * number of arguments the option takes.
 218      *
 219      * @param option an option
 220      * @return the number of arguments the given option takes or -1 if
 221      * the option is not supported
 222      * @see javax.tools.DocumentationTool#isSupportedOption(String)
 223      */
 224     public static int isSupportedOption(String option) {
 225         ToolOptions t = new ToolOptions();
 226         for (ToolOption o : t.supportedOptions) {
 227             for (String name : o.names) {
 228                 if (name.equals(option))
 229                     return o.hasArg ? 1 : 0;
 230             }
 231         }
 232         return -1;
 233     }
 234 
 235     /**
 236      * Returns the option to be used to process an argument such as may be found on
 237      * the command line.
 238      *
 239      * @param arg the argument
 240      * @return the option
 241      */
 242     ToolOption getOption(String arg) {
 243         String name = arg;
 244         if (arg.startsWith("--") && arg.contains("=")) {
 245             name = arg.substring(0, arg.indexOf('='));
 246         }
 247         for (ToolOption o : supportedOptions) {
 248             for (String n : o.names) {
 249                 if (name.equals(n)) {
 250                     return o;
 251                 }
 252             }
 253         }
 254         return null;
 255     }
 256 
 257     private List<ToolOption> supportedOptions = List.of(
 258             // ----- options for underlying compiler -----
 259 
 260             new ToolOption("-bootclasspath", STANDARD, true) {
 261                 @Override
 262                 public void process(String arg) throws InvalidValueException {
 263                     processCompilerOption(Option.BOOT_CLASS_PATH, primaryName, arg);
 264                 }
 265             },
 266 
 267             new ToolOption("--class-path -classpath -cp", STANDARD, true) {
 268                 @Override
 269                 public void process(String arg) throws InvalidValueException {
 270                     processCompilerOption(Option.CLASS_PATH, primaryName, arg);
 271                 }
 272             },
 273 
 274             new ToolOption("-extdirs", STANDARD, true) {
 275                 @Override
 276                 public void process(String arg) throws InvalidValueException {
 277                     processCompilerOption(Option.EXTDIRS, primaryName, arg);
 278                 }
 279             },
 280 
 281             new ToolOption("--source-path -sourcepath", STANDARD, true) {
 282                 @Override
 283                 public void process(String arg) throws InvalidValueException {
 284                     processCompilerOption(Option.SOURCE_PATH, primaryName, arg);
 285                 }
 286             },
 287 
 288             new ToolOption("--module-source-path", STANDARD, true) {
 289                 @Override
 290                 public void process(String arg) throws InvalidValueException {
 291                     processCompilerOption(Option.MODULE_SOURCE_PATH, primaryName, arg);
 292                 }
 293             },
 294 
 295             new ToolOption("--upgrade-module-path", STANDARD, true) {
 296                 @Override
 297                 public void process(String arg) throws InvalidValueException {
 298                     processCompilerOption(Option.UPGRADE_MODULE_PATH, primaryName, arg);
 299                 }
 300             },
 301 
 302             new ToolOption("--system", STANDARD, true) {
 303                 @Override
 304                 public void process(String arg) throws InvalidValueException {
 305                     processCompilerOption(Option.SYSTEM, primaryName, arg);
 306                 }
 307             },
 308 
 309             new ToolOption("--module-path -p", STANDARD, true) {
 310                 @Override
 311                 public void process(String arg) throws InvalidValueException {
 312                     processCompilerOption(Option.MODULE_PATH, primaryName, arg);
 313                 }
 314             },
 315 
 316             new ToolOption("--add-modules", STANDARD, true) {
 317                 @Override
 318                 public void process(String arg) throws InvalidValueException {
 319                     processCompilerOption(Option.ADD_MODULES, primaryName, arg);
 320                 }
 321             },
 322 
 323             new ToolOption("--limit-modules", STANDARD, true) {
 324                 @Override
 325                 public void process(String arg) throws InvalidValueException {
 326                     processCompilerOption(Option.LIMIT_MODULES, primaryName, arg);
 327                 }
 328             },
 329 
 330             new ToolOption("--module", STANDARD, true) {
 331                 @Override
 332                 public void process(String arg) {
 333                     modules.addAll(List.of(arg.split(",")));
 334                 }
 335             },
 336 
 337             new ToolOption("-encoding", STANDARD, true) {
 338                 @Override
 339                 public void process(String arg) throws InvalidValueException {
 340                     processCompilerOption(Option.ENCODING, primaryName, arg);
 341                 }
 342             },
 343 
 344             new ToolOption("--release", STANDARD, true) {
 345                 @Override
 346                 public void process(String arg) throws InvalidValueException {
 347                     processCompilerOption(Option.RELEASE, primaryName, arg);
 348                 }
 349             },
 350 
 351             new ToolOption("--source -source", STANDARD, true) {
 352                 @Override
 353                 public void process(String arg) throws InvalidValueException {
 354                     processCompilerOption(Option.SOURCE, primaryName, arg);
 355                     processCompilerOption(Option.TARGET, Option.TARGET.primaryName, arg);
 356                 }
 357             },
 358 
 359             new ToolOption("-Xmaxerrs", EXTENDED, true) {
 360                 @Override
 361                 public void process(String arg) throws InvalidValueException {
 362                     processCompilerOption(Option.XMAXERRS, primaryName, arg);
 363                 }
 364             },
 365 
 366             new ToolOption("-Xmaxwarns", EXTENDED, true) {
 367                 @Override
 368                 public void process(String arg) throws InvalidValueException {
 369                     processCompilerOption(Option.XMAXWARNS, primaryName, arg);
 370                 }
 371             },
 372 
 373             new ToolOption("--add-reads", EXTENDED, true) {
 374                 @Override
 375                 public void process(String arg) throws InvalidValueException {
 376                     processCompilerOption(Option.ADD_READS, primaryName, arg);
 377                 }
 378             },
 379 
 380             new ToolOption("--add-exports", EXTENDED, true) {
 381                 @Override
 382                 public void process(String arg) throws InvalidValueException {
 383                     processCompilerOption(Option.ADD_EXPORTS, primaryName, arg);
 384                 }
 385             },
 386 
 387             new ToolOption("--patch-module", EXTENDED, true) {
 388                 @Override
 389                 public void process(String arg) throws InvalidValueException {
 390                     processCompilerOption(Option.PATCH_MODULE, primaryName, arg);
 391                 }
 392             },
 393 
 394             new ToolOption("--add-opens", HIDDEN, true) {
 395                 @Override
 396                 public void process(String arg) throws InvalidValueException {
 397                     processCompilerOption(Option.ADD_OPENS, primaryName, arg);
 398                 }
 399             },
 400 
 401             new ToolOption("--enable-preview", STANDARD) {
 402                 @Override
 403                 public void process() throws InvalidValueException {
 404                     processCompilerOption(Option.PREVIEW, primaryName);
 405                 }
 406             },
 407 
 408             // ----- doclet options -----
 409 
 410             new ToolOption(DOCLET, STANDARD, true), // handled in setDocletInvoker
 411 
 412             new ToolOption(DOCLET_PATH, STANDARD, true), // handled in setDocletInvoker
 413 
 414             // ----- selection options -----
 415 
 416             new ToolOption("-subpackages", STANDARD, true) {
 417                 @Override
 418                 public void process(String arg) {
 419                     subpackages.addAll(List.of(arg.split(":")));
 420                 }
 421             },
 422 
 423             new ToolOption("-exclude", STANDARD, true) {
 424                 @Override
 425                 public void process(String arg) {
 426                     excludes.addAll(List.of(arg.split(":")));
 427                 }
 428             },
 429 
 430             // ----- filtering options -----
 431 
 432             new ToolOption("-package", STANDARD) {
 433                 @Override
 434                 public void process() throws OptionException {
 435                     setSimpleFilter("package");
 436                 }
 437             },
 438 
 439             new ToolOption("-private", STANDARD) {
 440                 @Override
 441                 public void process() throws OptionException {
 442                     setSimpleFilter("private");
 443                 }
 444             },
 445 
 446             new ToolOption("-protected", STANDARD) {
 447                 @Override
 448                 public void process() throws OptionException {
 449                     setSimpleFilter("protected");
 450                 }
 451             },
 452 
 453             new ToolOption("-public", STANDARD) {
 454                 @Override
 455                 public void process() throws OptionException {
 456                     setSimpleFilter("public");
 457                 }
 458             },
 459 
 460             new ToolOption("--show-members", STANDARD, true) {
 461                 @Override
 462                 public void process(String arg) throws OptionException {
 463                     setShowMembersAccess(arg);
 464                 }
 465             },
 466 
 467             new ToolOption("--show-types", STANDARD, true) {
 468                 @Override
 469                 public void process(String arg) throws OptionException {
 470                     setShowTypesAccess(arg);
 471                 }
 472             },
 473 
 474             new ToolOption("--show-packages", STANDARD, true) {
 475                 @Override
 476                 public void process(String arg) throws OptionException {
 477                     setShowPackageAccess(arg);
 478                 }
 479             },
 480 
 481             new ToolOption("--show-module-contents", STANDARD, true) {
 482                 @Override
 483                 public void process(String arg) throws OptionException {
 484                     setShowModuleContents(arg);
 485                 }
 486             },
 487 
 488             new ToolOption("--expand-requires", STANDARD, true) {
 489                 @Override
 490                 public void process(String arg) throws OptionException {
 491                     setExpandRequires(arg);
 492                 }
 493             },
 494 
 495             // ----- output control options -----
 496 
 497             new ToolOption("-quiet", STANDARD) {
 498                 @Override
 499                 public void process() {
 500                     quiet = true;
 501                 }
 502             },
 503 
 504             new ToolOption("-verbose", STANDARD) {
 505                 @Override
 506                 public void process() {
 507                     setVerbose();
 508                 }
 509             },
 510 
 511             new ToolOption("-Xwerror", HIDDEN) {
 512                 @Override
 513                 public void process() {
 514                     rejectWarnings = true;
 515                 }
 516             },
 517 
 518             // ----- other options -----
 519 
 520             new ToolOption("-breakiterator", STANDARD) {
 521                 @Override
 522                 public void process() {
 523                     breakIterator = true;
 524                 }
 525             },
 526 
 527             new ToolOption(LOCALE, STANDARD, true) {
 528                 @Override
 529                 public void process(String arg) {
 530                     docLocale = arg;
 531                 }
 532             },
 533 
 534             new ToolOption("-Xclasses", HIDDEN) {
 535                 @Override
 536                 public void process() {
 537                     xclasses = true;
 538                 }
 539             },
 540 
 541             new ToolOption(DUMP_ON_ERROR, HIDDEN) {
 542                 @Override
 543                 public void process() {
 544                     dumpOnError = true;
 545                 }
 546             },
 547 
 548             new ToolOption("--ignore-source-errors", HIDDEN) {
 549                 @Override
 550                 public void process() {
 551                     ignoreSourceErrors = true;
 552                 }
 553             },
 554 
 555             // ----- help options -----
 556 
 557             new ToolOption("--help -help -? -h", STANDARD) {
 558                 @Override
 559                 public void process() throws OptionException {
 560                     throw new OptionException(OK, showHelper::usage);
 561                 }
 562             },
 563 
 564             new ToolOption("--help-extra -X", STANDARD) {
 565                 @Override
 566                 public void process() throws OptionException {
 567                     throw new OptionException(OK, showHelper::Xusage);
 568                 }
 569             },
 570 
 571             // This option exists only for the purpose of documenting itself.
 572             // It's actually implemented by the launcher.
 573             new ToolOption(J, STANDARD, true) {
 574                 @Override
 575                 public void process() {
 576                     throw new AssertionError("the -J flag should be caught by the launcher.");
 577                 }
 578             },
 579 
 580             new ToolOption("--version", STANDARD) {
 581                 @Override
 582                 public void process() throws OptionException {
 583                     throw new OptionException(OK, showHelper::version);
 584                 }
 585             },
 586 
 587             new ToolOption("--full-version", HIDDEN) {
 588                 @Override
 589                 public void process() throws OptionException {
 590                     throw new OptionException(OK, showHelper::fullVersion);
 591                 }
 592             });
 593 
 594     /**
 595      * Base class for all supported tool options.
 596      */
 597     static class ToolOption {
 598         enum Kind { STANDARD, EXTENDED, HIDDEN }
 599 
 600         final String primaryName;
 601         final List<String> names;
 602         final Kind kind;
 603         final boolean hasArg;
 604         final boolean hasSuffix; // ex: foo:bar or -foo=bar
 605 
 606         ToolOption(String opt, Kind kind) {
 607             this(opt, kind, false);
 608         }
 609 
 610         ToolOption(String names, Kind kind, boolean hasArg) {
 611             this.names = Arrays.asList(names.split("\\s+"));
 612             this.primaryName = this.names.get(0);
 613             this.kind = kind;
 614             this.hasArg = hasArg;
 615             char lastChar = names.charAt(names.length() - 1);
 616             this.hasSuffix = lastChar == ':' || lastChar == '=';
 617         }
 618 
 619         void process(String arg) throws OptionException, Option.InvalidValueException { }
 620 
 621         void process() throws OptionException, Option.InvalidValueException { }
 622 
 623         List<String> getNames() {
 624             return names;
 625         }
 626 
 627         String getParameters(Messager messager) {
 628             return (hasArg || primaryName.endsWith(":"))
 629                     ? messager.getText(getKey(primaryName, ".arg"))
 630                     : null;
 631         }
 632 
 633         String getDescription(Messager messager) {
 634             return messager.getText(getKey(primaryName, ".desc"));
 635         }
 636 
 637         private String getKey(String optionName, String suffix) {
 638             return "main.opt."
 639                     + optionName
 640                         .replaceAll("^-*", "")              // remove leading '-'
 641                         .replaceAll("[^A-Za-z0-9]+$", "")   // remove trailing non-alphanumeric
 642                         .replaceAll("[^A-Za-z0-9]", ".")    // replace internal non-alphanumeric
 643                     + suffix;
 644         }
 645     }
 646 
 647     interface ShowHelper {
 648         /**
 649          * Show command-line help for the standard options, as requested by
 650          * the {@code --help} option and its aliases.
 651          */
 652         void usage();
 653 
 654         /**
 655          * Show command-line help for the extended options, as requested by
 656          * the {@code --help-extended} option and its aliases.
 657          */
 658         void Xusage();
 659 
 660         /**
 661          * Show the basic version information, as requested by the {@code --version} option.
 662          */
 663         void version();
 664 
 665         /**
 666          * Show the full version information, as requested by the {@code --full-version} option.
 667          */
 668         void fullVersion();
 669     }
 670 
 671     //<editor-fold desc="accessor methods">
 672     /**
 673      * Argument for command-line option {@code -breakiterator}.
 674      */
 675     boolean breakIterator() {
 676         return breakIterator;
 677     }
 678 
 679     /**
 680      * Argument for command-line option {@code -locale}.
 681      */
 682     String locale() {
 683         return docLocale;
 684     }
 685 
 686     /**
 687      * Argument for command-line option {@code --dump-on-error}.
 688      * Dump stack traces for debugging etc.
 689      * Similar to javac {@code -doe}.
 690      */
 691     boolean dumpOnError() {
 692         return dumpOnError;
 693     }
 694 
 695     void setDumpOnError(boolean v) {
 696         dumpOnError = true;
 697     }
 698 
 699     /**
 700      * Argument for command-line option {@code -exclude}.
 701      */
 702     List<String> excludes() {
 703         return excludes;
 704     }
 705 
 706     /**
 707      * Argument for command-line option {@code --expand-requires}.
 708      */
 709     AccessKind expandRequires() {
 710         return expandRequires;
 711     }
 712 
 713     /**
 714      * Argument for command-line option {@code --ignore-source-errors}.
 715      */
 716     boolean ignoreSourceErrors() {
 717         return ignoreSourceErrors;
 718     }
 719 
 720     /**
 721      * Argument for command-line option {@code --module}.
 722      */
 723     List<String> modules() {
 724         return modules;
 725     }
 726 
 727     /**
 728      * Argument for command-line option {@code -Xwerror}.
 729      * Set by -Xwerror.
 730      */
 731     boolean rejectWarnings() {
 732         return rejectWarnings;
 733     }
 734 
 735     /**
 736      * Argument for command-line option {@code --show-members}.
 737      */
 738     AccessKind showMembersAccess() {
 739         return showMembersAccess;
 740     }
 741 
 742     /**
 743      * Argument for command-line option {@code --show-types}.
 744      */
 745     AccessKind showTypesAccess() {
 746         return showTypesAccess;
 747     }
 748 
 749     /**
 750      * Argument for command-line option {@code --show-packages}.
 751      */
 752     AccessKind showPackagesAccess() {
 753         return showPackagesAccess;
 754     }
 755 
 756     /**
 757      * Argument for command-line option {@code --show-module-contents}.
 758      */
 759     AccessKind showModuleContents() {
 760         return showModuleContents;
 761     }
 762 
 763     /**
 764      * Argument for command-line option {@code -quiet}.
 765      */
 766     boolean quiet() {
 767         return quiet;
 768     }
 769 
 770     /**
 771      * Argument for command-line option {@code -subpackages}.
 772      */
 773     List<String> subpackages() {
 774         return subpackages;
 775     }
 776 
 777     /**
 778      * Argument for command-line option {@code -verbose}.
 779      */
 780     boolean verbose() {
 781         return verbose;
 782     }
 783 
 784     /**
 785      * Argument for command-line option {@code -xclasses}.
 786      * If true, names on the command line that would normally be
 787      * treated as package names are treated as class names instead.
 788      */
 789     boolean xclasses() {
 790         return xclasses;
 791     }
 792 
 793     /**
 794      * Returns the set of options to be used for the instance of the
 795      * underlying compiler front-end.
 796      *
 797      * @return the options
 798      */
 799     Options compilerOptions() {
 800         return compOpts;
 801     }
 802 
 803     /**
 804      * Returns the set of options to be used for the file manager.
 805      *
 806      * @return the options
 807      */
 808     Map<Option, String> fileManagerOptions() {
 809         return fileManagerOpts;
 810     }
 811     //</editor-fold>
 812 
 813     /**
 814      * Returns an {@code IllegalOptionValue} exception.
 815      *
 816      * @param arg the arghument to include in the detail message
 817      * @return the exception
 818      */
 819     private IllegalOptionValue illegalOptionValue(String arg) {
 820         return new IllegalOptionValue(showHelper::usage, messager.getText("main.illegal_option_value", arg));
 821     }
 822 
 823     /**
 824      * Process a compiler option.
 825      *
 826      * @param option the option object to process the command-line option
 827      * @param opt    the command-line option
 828      * @throws Option.InvalidValueException if the command-line option is invalid
 829      */
 830     void processCompilerOption(Option option, String opt) throws Option.InvalidValueException {
 831         option.process(compilerOptionHelper, opt);
 832     }
 833 
 834     /**
 835      * Process a compiler option.
 836      *
 837      * @param option the option object to process the command-line option
 838      * @param opt    the command-line option
 839      * @param arg    the argument for the command-line option
 840      * @throws Option.InvalidValueException if the command-line option is invalid
 841      */
 842     private void processCompilerOption(Option option, String opt, String arg) throws Option.InvalidValueException {
 843         option.process(compilerOptionHelper, opt, arg);
 844     }
 845 
 846     /**
 847      * Returns a "helper" to be used when processing compiler options.
 848      * @return the helper
 849      */
 850     private OptionHelper getOptionHelper() {
 851         return new OptionHelper.GrumpyHelper(messager) {
 852             @Override
 853             public String get(com.sun.tools.javac.main.Option option) {
 854                 return compOpts.get(option);
 855             }
 856 
 857             @Override
 858             public void put(String name, String value) {
 859                 compOpts.put(name, value);
 860             }
 861 
 862             @Override
 863             public void remove(String name) {
 864                 compOpts.remove(name);
 865             }
 866 
 867             @Override
 868             public boolean handleFileManagerOption(com.sun.tools.javac.main.Option option, String value) {
 869                 fileManagerOpts.put(option, value);
 870                 return true;
 871             }
 872         };
 873     }
 874 
 875     private void setExpandRequires(String arg) throws OptionException {
 876         switch (arg) {
 877             case "transitive":
 878                 expandRequires = AccessKind.PUBLIC;
 879                 break;
 880             case "all":
 881                 expandRequires = AccessKind.PRIVATE;
 882                 break;
 883             default:
 884                 throw illegalOptionValue(arg);
 885         }
 886     }
 887 
 888     private void setShowModuleContents(String arg) throws OptionException {
 889         switch (arg) {
 890             case "api":
 891                 showModuleContents = AccessKind.PUBLIC;
 892                 break;
 893             case "all":
 894                 showModuleContents = AccessKind.PRIVATE;
 895                 break;
 896             default:
 897                 throw illegalOptionValue(arg);
 898         }
 899     }
 900 
 901     private void setShowPackageAccess(String arg) throws OptionException {
 902         switch (arg) {
 903             case "exported":
 904                 showPackagesAccess = AccessKind.PUBLIC;
 905                 break;
 906             case "all":
 907                 showPackagesAccess = AccessKind.PRIVATE;
 908                 break;
 909             default:
 910                 throw illegalOptionValue(arg);
 911         }
 912     }
 913 
 914     private void setShowTypesAccess(String arg) throws OptionException {
 915         showTypesAccess = getAccessValue(arg);
 916     }
 917 
 918     private void setShowMembersAccess(String arg) throws OptionException {
 919         showMembersAccess = getAccessValue(arg);
 920     }
 921 
 922     private void setSimpleFilter(String arg) throws OptionException {
 923         setSimpleAccessOption(arg);
 924     }
 925 
 926     private void setVerbose() {
 927         compOpts.put("-verbose", "");
 928         verbose = true;
 929     }
 930 
 931     private void setSimpleAccessOption(String arg) throws OptionException {
 932         setAccess(getAccessValue(arg));
 933     }
 934 
 935     /*
 936      * This method handles both the simple options -package,
 937      * -private, so on, in addition to the new ones such as
 938      * --show-types:public and so on.
 939      */
 940     private AccessKind getAccessValue(String arg) throws OptionException {
 941         int colon = arg.indexOf(':');
 942         String value = (colon > 0)
 943                 ? arg.substring(colon + 1)
 944                 : arg;
 945         switch (value) {
 946             case "public":
 947                 return AccessKind.PUBLIC;
 948             case "protected":
 949                 return AccessKind.PROTECTED;
 950             case "package":
 951                 return AccessKind.PACKAGE;
 952             case "private":
 953                 return AccessKind.PRIVATE;
 954             default:
 955                 throw illegalOptionValue(value);
 956         }
 957     }
 958 
 959     /*
 960      * Sets all access members to PROTECTED; this is the default.
 961      */
 962     private void setAccessDefault() {
 963         setAccess(AccessKind.PROTECTED);
 964     }
 965 
 966     /*
 967      * This sets access to all the allowed kinds in the
 968      * access members.
 969      */
 970     private void setAccess(AccessKind accessValue) {
 971         for (ElementKind kind : ElementsTable.ModifierFilter.ALLOWED_KINDS) {
 972             switch (kind) {
 973                 case METHOD:
 974                     showMembersAccess = accessValue;
 975                     break;
 976                 case CLASS:
 977                     showTypesAccess = accessValue;
 978                     break;
 979                 case PACKAGE:
 980                     showPackagesAccess = accessValue;
 981                     break;
 982                 case MODULE:
 983                     showModuleContents = accessValue;
 984                     break;
 985                 default:
 986                     throw new AssertionError("unknown element kind:" + kind);
 987             }
 988         }
 989     }
 990 }