001/*
002 * Copyright (C) 2022 - 2023, the original author or authors.
003 *
004 * Licensed under the Apache License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 *    http://www.apache.org/licenses/LICENSE-2.0
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 */
016package io.github.ascopes.jct.compilers;
017
018import io.github.ascopes.jct.ex.JctCompilerException;
019import io.github.ascopes.jct.filemanagers.AnnotationProcessorDiscovery;
020import io.github.ascopes.jct.filemanagers.LoggingMode;
021import io.github.ascopes.jct.utils.IterableUtils;
022import io.github.ascopes.jct.workspaces.Workspace;
023import java.io.UncheckedIOException;
024import java.nio.charset.Charset;
025import java.nio.charset.StandardCharsets;
026import java.util.Collection;
027import java.util.List;
028import java.util.Locale;
029import javax.annotation.processing.Processor;
030import javax.lang.model.SourceVersion;
031import org.apiguardian.api.API;
032import org.apiguardian.api.API.Status;
033
034/**
035 * Base definition of a compiler that can be configured to perform a compilation run against
036 * sources. This is designed to provide functionality that {@code javac} does by default, for JDK
037 * 17.
038 *
039 * @author Ashley Scopes
040 * @since 0.0.1
041 */
042@API(since = "0.0.1", status = Status.STABLE)
043public interface JctCompiler {
044
045  /**
046   * Default setting for deprecation warnings ({@code true}).
047   */
048  boolean DEFAULT_SHOW_DEPRECATION_WARNINGS = true;
049
050  /**
051   * Default setting for locale ({@link Locale#ROOT}).
052   */
053  Locale DEFAULT_LOCALE = Locale.ROOT;
054
055  /**
056   * Default setting for preview features ({@code false}).
057   */
058  boolean DEFAULT_PREVIEW_FEATURES = false;
059
060  /**
061   * Default setting for verbose logging ({@code false}).
062   */
063  boolean DEFAULT_VERBOSE = false;
064
065  /**
066   * Default setting for displaying warnings ({@code true}).
067   */
068  boolean DEFAULT_SHOW_WARNINGS = true;
069
070  /**
071   * Default setting for displaying warnings as errors ({@code false}).
072   */
073  boolean DEFAULT_FAIL_ON_WARNINGS = false;
074
075  /**
076   * Default setting for fixing modules being placed on the classpath by mistake ({@code true}).
077   */
078  boolean DEFAULT_FIX_JVM_MODULE_PATH_MISMATCH = true;
079
080  /**
081   * Default setting for inclusion of the current class path ({@code true}).
082   */
083  boolean DEFAULT_INHERIT_CLASS_PATH = true;
084
085  /**
086   * Default setting for inclusion of the current module path ({@code true}).
087   */
088  boolean DEFAULT_INHERIT_MODULE_PATH = true;
089
090  /**
091   * Default setting for inclusion of the system module path ({@code true}).
092   */
093  boolean DEFAULT_INHERIT_SYSTEM_MODULE_PATH = true;
094
095  /**
096   * Default setting for logging file manager operations ({@link LoggingMode#DISABLED}).
097   */
098  LoggingMode DEFAULT_FILE_MANAGER_LOGGING_MODE = LoggingMode.DISABLED;
099
100  /**
101   * Default setting for logging diagnostics ({@link LoggingMode#ENABLED}).
102   */
103  LoggingMode DEFAULT_DIAGNOSTIC_LOGGING_MODE = LoggingMode.ENABLED;
104
105  /**
106   * Default setting for the compilation mode to use
107   * ({@link CompilationMode#COMPILATION_AND_ANNOTATION_PROCESSING}).
108   */
109  CompilationMode DEFAULT_COMPILATION_MODE = CompilationMode.COMPILATION_AND_ANNOTATION_PROCESSING;
110
111  /**
112   * Default setting for how to apply annotation processor discovery when no processors are
113   * explicitly defined ({@link AnnotationProcessorDiscovery#INCLUDE_DEPENDENCIES}).
114   */
115  AnnotationProcessorDiscovery DEFAULT_ANNOTATION_PROCESSOR_DISCOVERY =
116      AnnotationProcessorDiscovery.INCLUDE_DEPENDENCIES;
117
118  /**
119   * Default charset to use for compiler logs ({@link StandardCharsets#UTF_8}).
120   */
121  Charset DEFAULT_LOG_CHARSET = StandardCharsets.UTF_8;
122
123  /**
124   * Invoke the compilation and return the compilation result.
125   *
126   * <p>The actual classes to compile will be dynamically discovered. If you wish to
127   * specify the specific classes to compile, see {@link #compile(Workspace, String, String...)} or
128   * {@link #compile(Workspace, Collection)}.
129   *
130   * @param workspace the workspace to compile.
131   * @return the compilation result.
132   * @throws JctCompilerException  if the compiler threw an unhandled exception. This should not
133   *                               occur for compilation failures generally.
134   * @throws IllegalStateException if no compilation units were found.
135   * @throws UncheckedIOException  if an IO error occurs.
136   * @see #compile(Workspace, String, String...)
137   * @see #compile(Workspace, Collection)
138   */
139  JctCompilation compile(Workspace workspace);
140
141  /**
142   * Invoke the compilation and return the compilation result.
143   *
144   * <p>Only classes matching the given class names will be compiled.
145   *
146   * <p>If you wish to let JCT determine which classes to compile dynamically, see
147   * {@link #compile(Workspace)} instead.
148   *
149   * @param workspace            the workspace to compile.
150   * @param firstClassName       the first class name to compile.
151   * @param additionalClassNames any additional class names to compile.
152   * @return the compilation result.
153   * @throws JctCompilerException  if the compiler threw an unhandled exception. This should not
154   *                               occur for compilation failures generally.
155   * @throws NullPointerException  if any class names are null.
156   * @throws IllegalStateException if no compilation units were found.
157   * @throws UncheckedIOException  if an IO error occurs.
158   * @see #compile(Workspace)
159   * @see #compile(Workspace, Collection)
160   */
161  default JctCompilation compile(Workspace workspace, String firstClassName,
162      String... additionalClassNames) {
163    return compile(workspace, IterableUtils.combineOneOrMore(firstClassName, additionalClassNames));
164  }
165
166  /**
167   * Invoke the compilation and return the compilation result.
168   *
169   * <p>Only classes matching the given class names will be compiled.
170   *
171   * <p>If you wish to let JCT determine which classes to compile dynamically, see
172   * {@link #compile(Workspace)} instead.
173   *
174   * @param workspace  the workspace to compile.
175   * @param classNames the class names to compile.
176   * @return the compilation result.
177   * @throws JctCompilerException     if the compiler threw an unhandled exception. This should not
178   *                                  occur for compilation failures usually.
179   * @throws NullPointerException     if the {@code classNames} collection contains any null values,
180   *                                  or if the collection itself is null.
181   * @throws IllegalArgumentException if the collection is empty.
182   * @throws IllegalStateException    if no compilation units were found.
183   * @throws UncheckedIOException     if an IO error occurs.
184   * @see #compile(Workspace)
185   * @see #compile(Workspace, String, String...)
186   */
187  JctCompilation compile(Workspace workspace, Collection<String> classNames);
188
189  /**
190   * Apply a given configurer to this compiler that can throw a checked exception.
191   *
192   * @param <E>        any exception that may be thrown.
193   * @param configurer the configurer to invoke.
194   * @return this compiler object for further call chaining.
195   * @throws E any exception that may be thrown by the configurer.
196   */
197  <E extends Exception> JctCompiler configure(JctCompilerConfigurer<E> configurer) throws E;
198
199  /**
200   * Get the friendly printable name of this compiler object.
201   *
202   * @return the name of the compiler.
203   */
204  String getName();
205
206  /**
207   * Set the friendly name of this compiler.
208   *
209   * @param name the name to set.
210   * @return this compiler object for further call chaining.
211   */
212  JctCompiler name(String name);
213
214  /**
215   * Get an <strong>immutable snapshot view</strong> of the current annotation processor options
216   * that are set.
217   *
218   * @return the current annotation processor options that are set.
219   */
220  List<String> getAnnotationProcessorOptions();
221
222  /**
223   * Add options to pass to any annotation processors.
224   *
225   * @param annotationProcessorOptions the options to pass.
226   * @return this compiler object for further call chaining.
227   */
228  JctCompiler addAnnotationProcessorOptions(Iterable<String> annotationProcessorOptions);
229
230  /**
231   * Add options to pass to any annotation processors.
232   *
233   * @param annotationProcessorOption  the first option to pass.
234   * @param annotationProcessorOptions additional options to pass.
235   * @return this compiler object for further call chaining.
236   */
237  default JctCompiler addAnnotationProcessorOptions(
238      String annotationProcessorOption,
239      String... annotationProcessorOptions
240  ) {
241    return addAnnotationProcessorOptions(
242        IterableUtils.combineOneOrMore(annotationProcessorOption, annotationProcessorOptions)
243    );
244  }
245
246  /**
247   * Get an <strong>immutable snapshot view</strong> of the current annotation processors that are
248   * explicitly set to be run, in the order that they were provided to the compiler.
249   *
250   * @return the current annotation processors that are set.
251   */
252  List<Processor> getAnnotationProcessors();
253
254  /**
255   * Add annotation processors to invoke.
256   *
257   * <p>This bypasses the discovery process of annotation processors provided in the annotation
258   * processor path.
259   *
260   * @param annotationProcessors the processors to invoke.
261   * @return this compiler object for further call chaining.
262   */
263  JctCompiler addAnnotationProcessors(Iterable<? extends Processor> annotationProcessors);
264
265  /**
266   * Add annotation processors to invoke.
267   *
268   * <p>This bypasses the discovery process of annotation processors provided in the annotation
269   * processor path.
270   *
271   * @param annotationProcessor  the first processor to invoke.
272   * @param annotationProcessors additional processors to invoke.
273   * @return this compiler object for further call chaining.
274   */
275  default JctCompiler addAnnotationProcessors(
276      Processor annotationProcessor,
277      Processor... annotationProcessors
278  ) {
279    return addAnnotationProcessors(
280        IterableUtils.combineOneOrMore(annotationProcessor, annotationProcessors));
281  }
282
283  /**
284   * Get an <strong>immutable snapshot view</strong> of the current compiler options that are set.
285   *
286   * @return the current compiler  options that are set.
287   */
288  List<String> getCompilerOptions();
289
290  /**
291   * Add command line options to pass to {@code javac}.
292   *
293   * @param compilerOptions the options to add.
294   * @return this compiler object for further call chaining.
295   */
296  JctCompiler addCompilerOptions(Iterable<String> compilerOptions);
297
298  /**
299   * Add command line options to pass to {@code javac}.
300   *
301   * @param compilerOption  the first option to add.
302   * @param compilerOptions additional options to add.
303   * @return this compiler object for further call chaining.
304   */
305  default JctCompiler addCompilerOptions(String compilerOption, String... compilerOptions) {
306    return addCompilerOptions(IterableUtils.combineOneOrMore(compilerOption, compilerOptions));
307  }
308
309  /**
310   * Determine whether verbose logging is enabled or not.
311   *
312   * <p>Unless otherwise changed or specified, implementations should default to
313   * {@link #DEFAULT_VERBOSE}.
314   *
315   * <p>Note that enabling this is compiler-specific behaviour. There is no guarantee that the
316   * output target or the format or verbosity of output will be consistent between different
317   * compiler implementations.
318   *
319   * @return whether verbose logging is enabled or not.
320   */
321  boolean isVerbose();
322
323  /**
324   * Set whether to use verbose output or not.
325   *
326   * <p>Unless otherwise changed or specified, implementations should default to
327   * {@link #DEFAULT_VERBOSE}.
328   *
329   * <p>Note that enabling this is compiler-specific behaviour. There is no guarantee that the
330   * output target or the format or verbosity of output will be consistent between different
331   * compiler implementations.
332   *
333   * @param enabled {@code true} for verbose output, {@code false} for normal output.
334   * @return this compiler for further call chaining.
335   */
336  JctCompiler verbose(boolean enabled);
337
338  /**
339   * Determine whether preview features are enabled or not.
340   *
341   * <p>Unless otherwise changed or specified, implementations should default to
342   * {@link #DEFAULT_PREVIEW_FEATURES}.
343   *
344   * @return whether preview features are enabled or not.
345   */
346  boolean isPreviewFeatures();
347
348  /**
349   * Set whether to enable preview features or not.
350   *
351   * <p>Unless otherwise changed or specified, implementations should default to
352   * {@link #DEFAULT_PREVIEW_FEATURES}.
353   *
354   * @param enabled {@code true} to enable preview features, or {@code false} to disable them.
355   * @return this compiler object for further call chaining.
356   */
357  JctCompiler previewFeatures(boolean enabled);
358
359  /**
360   * Determine whether warnings are enabled or not.
361   *
362   * <p>Unless otherwise changed or specified, implementations should default to
363   * {@link #DEFAULT_SHOW_WARNINGS}.
364   *
365   * @return whether warnings are enabled or not.
366   */
367  boolean isShowWarnings();
368
369  /**
370   * Set whether to enable displaying warnings or not.
371   *
372   * <p>Unless otherwise changed or specified, implementations should default to
373   * {@link #DEFAULT_SHOW_WARNINGS}.
374   *
375   * @param enabled {@code true} to enable warnings. {@code false} to disable them.
376   * @return this compiler object for further call chaining.
377   */
378  JctCompiler showWarnings(boolean enabled);
379
380  /**
381   * Determine whether deprecation warnings are enabled or not.
382   *
383   * <p>Unless otherwise changed or specified, implementations should default to
384   * {@link #DEFAULT_SHOW_DEPRECATION_WARNINGS}.
385   *
386   * @return whether deprecation warnings are enabled or not.
387   */
388  boolean isShowDeprecationWarnings();
389
390  /**
391   * Set whether to enable deprecation warnings or not.
392   *
393   * <p>This is ignored if {@link #showWarnings(boolean)} is disabled.
394   *
395   * <p>Unless otherwise changed or specified, implementations should default to
396   * {@link #DEFAULT_SHOW_DEPRECATION_WARNINGS}.
397   *
398   * @param enabled {@code true} to enable deprecation warnings. {@code false} to disable them.
399   * @return this compiler object for further call chaining.
400   */
401  JctCompiler showDeprecationWarnings(boolean enabled);
402
403  /**
404   * Determine whether warnings are being treated as errors or not.
405   *
406   * <p>Unless otherwise changed or specified, implementations should default to
407   * {@link #DEFAULT_FAIL_ON_WARNINGS}.
408   *
409   * @return whether warnings are being treated as errors or not.
410   */
411  boolean isFailOnWarnings();
412
413  /**
414   * Set whether to enable treating warnings as errors or not.
415   *
416   * <p>This is ignored if {@link #showWarnings(boolean)} is disabled.
417   *
418   * <p>Unless otherwise changed or specified, implementations should default to
419   * {@link #DEFAULT_FAIL_ON_WARNINGS}.
420   *
421   * @param enabled {@code true} to enable treating warnings as errors. {@code false} to disable
422   *                them.
423   * @return this compiler object for further call chaining.
424   */
425  JctCompiler failOnWarnings(boolean enabled);
426
427  /**
428   * Get the compilation mode that is in use.
429   *
430   * <p>Unless otherwise changed or specified, implementations should default to
431   * {@link #DEFAULT_COMPILATION_MODE}.
432   *
433   * @return the compilation mode.
434   */
435  CompilationMode getCompilationMode();
436
437  /**
438   * Set the compilation mode to use for this compiler.
439   *
440   * <p>Unless otherwise changed or specified, implementations should default to
441   * {@link #DEFAULT_COMPILATION_MODE}.
442   *
443   * @param compilationMode the compilation mode to use.
444   * @return this compiler object for further call chaining.
445   */
446  JctCompiler compilationMode(CompilationMode compilationMode);
447
448  /**
449   * Get the default release to use if no release or target version is specified.
450   *
451   * <p>This can <strong>not</strong> be configured.
452   *
453   * @return the default release version to use.
454   */
455  String getDefaultRelease();
456
457  /**
458   * Get the effective release to use for the actual compilation.
459   *
460   * <p>This may be determined from the {@link #getSource() source},
461   * {@link #getTarget() target}, {@link #getRelease() release}, and
462   * {@link #getDefaultRelease() default release.}
463   *
464   * @return the effective release.
465   */
466  String getEffectiveRelease();
467
468  /**
469   * Get the current release version that is set, or {@code null} if left to the compiler to decide.
470   * default.
471   *
472   * <p>Unless explicitly defined, the default setting is expected to be a sane compiler-specific
473   * default.
474   *
475   * @return the release version string, if set.
476   */
477  String getRelease();
478
479  /**
480   * Set the release version.
481   *
482   * <p>This will clear any source and target version that is set.
483   *
484   * <p>Unless explicitly defined, the default setting is expected to be a sane compiler-specific
485   * default.
486   *
487   * @param release the version to set.
488   * @return this compiler object for further call chaining.
489   */
490  JctCompiler release(String release);
491
492  /**
493   * Set the release version.
494   *
495   * <p>This will clear any source and target version that is set.
496   *
497   * <p>Unless explicitly defined, the default setting is expected to be a sane compiler-specific
498   * default.
499   *
500   * @param release the version to set.
501   * @return this compiler object for further call chaining.
502   */
503  default JctCompiler release(int release) {
504    if (release < 0) {
505      throw new IllegalArgumentException("Cannot provide a release version less than 0");
506    }
507
508    return release(Integer.toString(release));
509  }
510
511  /**
512   * Set the release version.
513   *
514   * <p>This will clear any source and target version that is set.
515   *
516   * <p>Unless explicitly defined, the default setting is expected to be a sane compiler-specific
517   * default.
518   *
519   * @param release the version to set.
520   * @return this compiler object for further call chaining.
521   */
522  default JctCompiler release(SourceVersion release) {
523    return release(Integer.toString(release.ordinal()));
524  }
525
526  /**
527   * Request that the compiler uses a language version that corresponds to the
528   * runtime language version in use on the JVM running tests.
529   *
530   * <p>For example, running this on JRE 19 would set the release to "19".
531   *
532   * <p>This calls {@link #release(int) internally}.
533   *
534   * @return this compiler object for further call chaining.
535   */
536  @API(since = "1.1.0", status = Status.STABLE)
537  default JctCompiler useRuntimeRelease() {
538    return release(Runtime.version().feature());
539  }
540
541  /**
542   * Get the current source version that is set, or {@code null} if left to the compiler to decide.
543   * default.
544   *
545   * <p>Unless explicitly defined, the default setting is expected to be a sane compiler-specific
546   * default.
547   *
548   * @return the source version string, if set.
549   */
550  String getSource();
551
552  /**
553   * Set the source version.
554   *
555   * <p>This will clear any release version that is set.
556   *
557   * <p>Unless explicitly defined, the default setting is expected to be a sane compiler-specific
558   * default.
559   *
560   * @param source the version to set.
561   * @return this compiler object for further call chaining.
562   */
563  JctCompiler source(String source);
564
565  /**
566   * Set the source version.
567   *
568   * <p>This will clear any release version that is set.
569   *
570   * <p>Unless explicitly defined, the default setting is expected to be a sane compiler-specific
571   * default.
572   *
573   * @param source the version to set.
574   * @return this compiler object for further call chaining.
575   */
576  default JctCompiler source(int source) {
577    if (source < 0) {
578      throw new IllegalArgumentException("Cannot provide a source version less than 0");
579    }
580
581    return source(Integer.toString(source));
582  }
583
584  /**
585   * Set the source version.
586   *
587   * <p>This will clear any release version that is set.
588   *
589   * <p>Unless explicitly defined, the default setting is expected to be a sane compiler-specific
590   * default.
591   *
592   * @param source the version to set.
593   * @return this compiler object for further call chaining.
594   */
595  default JctCompiler source(SourceVersion source) {
596    return source(Integer.toString(source.ordinal()));
597  }
598
599  /**
600   * Get the current target version that is set, or {@code null} if left to the compiler default.
601   *
602   * <p>Unless explicitly defined, the default setting is expected to be a sane compiler-specific
603   * default.
604   *
605   * @return the target version string, if set.
606   */
607  String getTarget();
608
609  /**
610   * Set the target version.
611   *
612   * <p>This will clear any release version that is set.
613   *
614   * <p>Unless explicitly defined, the default setting is expected to be a sane compiler-specific
615   * default.
616   *
617   * @param target the version to set.
618   * @return this compiler object for further call chaining.
619   */
620  JctCompiler target(String target);
621
622  /**
623   * Set the target version.
624   *
625   * <p>This will clear any release version that is set.
626   *
627   * <p>Unless explicitly defined, the default setting is expected to be a sane compiler-specific
628   * default.
629   *
630   * @param target the version to set.
631   * @return this compiler object for further call chaining.
632   */
633  default JctCompiler target(int target) {
634    if (target < 0) {
635      throw new IllegalArgumentException("Cannot provide a target version less than 0");
636    }
637
638    return target(Integer.toString(target));
639  }
640
641  /**
642   * Set the target version.
643   *
644   * <p>This will clear any release version that is set.
645   *
646   * <p>Unless explicitly defined, the default setting is expected to be a sane compiler-specific
647   * default.
648   *
649   * @param target the version to set.
650   * @return this compiler object for further call chaining.
651   */
652  default JctCompiler target(SourceVersion target) {
653    return target(Integer.toString(target.ordinal()));
654  }
655
656  /**
657   * Get whether we will attempt to fix modules appearing on the classpath, or non-modules appearing
658   * on the module path.
659   *
660   * <p>This enables correct classpath and module path detection when the test pack is a module but
661   * the code being compiled in the test is not, and vice versa. We need this because many build
662   * systems decide whether to populate the {@code --module-path} flat or the {@code --classpath}
663   * with JPMS-enabled dependencies based on whether the project under compilation is a JPMS module
664   * itself.
665   *
666   * <p>This only applies if {@link #isInheritModulePath()} or {@link #isInheritClassPath()} is
667   * enabled, and only applies to the current JVM classpath and module path.
668   *
669   * <p>Unless otherwise changed or specified, implementations should default to
670   * {@link #DEFAULT_FIX_JVM_MODULE_PATH_MISMATCH}.
671   *
672   * @return {@code true} if enabled, or {@code false} if disabled.
673   */
674  boolean isFixJvmModulePathMismatch();
675
676  /**
677   * Get whether we will attempt to fix modules appearing on the classpath, or non-modules appearing
678   * on the module path.
679   *
680   * <p>Unless otherwise changed or specified, implementations should default to
681   * {@link #DEFAULT_FIX_JVM_MODULE_PATH_MISMATCH}.
682   *
683   * @param fixJvmModulePathMismatch whether to enable the mismatch fixing or not.
684   * @return this compiler object for further call chaining.
685   */
686  JctCompiler fixJvmModulePathMismatch(boolean fixJvmModulePathMismatch);
687
688  /**
689   * Get whether the class path is inherited from the caller JVM or not.
690   *
691   * <p>Unless otherwise changed or specified, implementations should default to
692   * {@link #DEFAULT_INHERIT_CLASS_PATH}.
693   *
694   * @return whether the current class path is being inherited or not.
695   */
696  boolean isInheritClassPath();
697
698  /**
699   * Set whether the class path is inherited from the caller JVM or not.
700   *
701   * <p>Unless otherwise changed or specified, implementations should default to
702   * {@link #DEFAULT_INHERIT_CLASS_PATH}.
703   *
704   * @param inheritClassPath {@code true} to include it, or {@code false} to exclude it.
705   * @return this compiler object for further call chaining.
706   */
707  JctCompiler inheritClassPath(boolean inheritClassPath);
708
709  /**
710   * Get whether the module path is inherited from the caller JVM or not.
711   *
712   * <p>Unless otherwise changed or specified, implementations should default to
713   * {@link #DEFAULT_INHERIT_MODULE_PATH}.
714   *
715   * @return whether the module path is being inherited or not.
716   */
717  boolean isInheritModulePath();
718
719  /**
720   * Set whether the module path is inherited from the caller JVM or not.
721   *
722   * <p>Unless otherwise changed or specified, implementations should default to
723   * {@link #DEFAULT_INHERIT_MODULE_PATH}.
724   *
725   * @param inheritModulePath {@code true} to include it, or {@code false} to exclude it.
726   * @return this compiler object for further call chaining.
727   */
728  JctCompiler inheritModulePath(boolean inheritModulePath);
729
730  /**
731   * Get whether the system module path is inherited from the caller JVM or not.
732   *
733   * <p>Unless otherwise changed or specified, implementations should default to
734   * {@link #DEFAULT_INHERIT_SYSTEM_MODULE_PATH}.
735   *
736   * @return whether the system module path is being inherited or not.
737   */
738  boolean isInheritSystemModulePath();
739
740  /**
741   * Set whether the system module path is inherited from the caller JVM or not.
742   *
743   * <p>Unless otherwise changed or specified, implementations should default to
744   * {@link #DEFAULT_INHERIT_SYSTEM_MODULE_PATH}.
745   *
746   * @param inheritSystemModulePath {@code true} to include it, or {@code false} to exclude it.
747   * @return this compiler object for further call chaining.
748   */
749  JctCompiler inheritSystemModulePath(boolean inheritSystemModulePath);
750
751  /**
752   * Get the output locale.
753   *
754   * <p>Unless otherwise changed or specified, implementations should default to
755   * {@link #DEFAULT_LOCALE}.
756   *
757   * @return the output locale to use.
758   */
759  Locale getLocale();
760
761  /**
762   * Set the output locale.
763   *
764   * <p>Unless otherwise changed or specified, implementations should default to
765   * {@link #DEFAULT_LOCALE}.
766   *
767   * @param locale the locale to use.
768   * @return this compiler for further call chaining.
769   */
770  JctCompiler locale(Locale locale);
771
772  /**
773   * Get the charset being used to write compiler logs with.
774   *
775   * <p>Unless otherwise changed or specified, implementations should default to
776   * {@link #DEFAULT_LOG_CHARSET}.
777   *
778   * @return the charset.
779   */
780  Charset getLogCharset();
781
782  /**
783   * Set the charset being used to write compiler logs with.
784   *
785   * <p>Unless otherwise changed or specified, implementations should default to
786   * {@link #DEFAULT_LOG_CHARSET}.
787   *
788   * @param logCharset the charset to use.
789   * @return this compiler for further call chaining.
790   */
791  JctCompiler logCharset(Charset logCharset);
792
793  /**
794   * Get the current file manager logging mode.
795   *
796   * <p>Unless otherwise changed or specified, implementations should default to
797   * {@link #DEFAULT_FILE_MANAGER_LOGGING_MODE}.
798   *
799   * @return the current file manager logging mode.
800   */
801  LoggingMode getFileManagerLoggingMode();
802
803  /**
804   * Set how to handle logging calls to underlying file managers.
805   *
806   * <p>Unless otherwise changed or specified, implementations should default to
807   * {@link #DEFAULT_FILE_MANAGER_LOGGING_MODE}.
808   *
809   * @param fileManagerLoggingMode the mode to use for file manager logging.
810   * @return this compiler for further call chaining.
811   */
812  JctCompiler fileManagerLoggingMode(LoggingMode fileManagerLoggingMode);
813
814  /**
815   * Get the current diagnostic logging mode.
816   *
817   * <p>Unless otherwise changed or specified, implementations should default to
818   * {@link #DEFAULT_DIAGNOSTIC_LOGGING_MODE}.
819   *
820   * @return the current diagnostic logging mode.
821   */
822  LoggingMode getDiagnosticLoggingMode();
823
824  /**
825   * Set how to handle diagnostic capture.
826   *
827   * <p>Unless otherwise changed or specified, implementations should default to
828   * {@link #DEFAULT_DIAGNOSTIC_LOGGING_MODE}.
829   *
830   * @param diagnosticLoggingMode the mode to use for diagnostic capture.
831   * @return this compiler for further call chaining.
832   */
833  JctCompiler diagnosticLoggingMode(LoggingMode diagnosticLoggingMode);
834
835  /**
836   * Get how to perform annotation processor discovery.
837   *
838   * <p>Unless otherwise changed or specified, implementations should default to
839   * {@link #DEFAULT_ANNOTATION_PROCESSOR_DISCOVERY}.
840   *
841   * <p>Specifying any annotation processors explicitly with
842   * {@link #addAnnotationProcessors(Iterable)} or
843   * {@link #addAnnotationProcessors(Processor, Processor...)} will bypass this setting, treating it
844   * as being disabled.
845   *
846   * @return the processor discovery mode to use.
847   */
848  AnnotationProcessorDiscovery getAnnotationProcessorDiscovery();
849
850  /**
851   * Set how to perform annotation processor discovery.
852   *
853   * <p>Unless otherwise changed or specified, implementations should default to
854   * {@link #DEFAULT_ANNOTATION_PROCESSOR_DISCOVERY}.
855   *
856   * <p>Specifying any annotation processors explicitly with
857   * {@link #addAnnotationProcessors(Iterable)} or
858   * {@link #addAnnotationProcessors(Processor, Processor...)} will bypass this setting, treating it
859   * as being disabled.
860   *
861   * @param annotationProcessorDiscovery the processor discovery mode to use.
862   * @return this compiler for further call chaining.
863   */
864  JctCompiler annotationProcessorDiscovery(
865      AnnotationProcessorDiscovery annotationProcessorDiscovery);
866}