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   * <p>Note that nested instance/static nested classes cannot be specified individually
150   * here. To compile them, you must also compile their outer class that they are defined
151   * within.
152   *
153   * @param workspace            the workspace to compile.
154   * @param firstClassName       the first class name to compile.
155   * @param additionalClassNames any additional class names to compile.
156   * @return the compilation result.
157   * @throws JctCompilerException  if the compiler threw an unhandled exception. This should not
158   *                               occur for compilation failures generally.
159   * @throws NullPointerException  if any class names are null.
160   * @throws IllegalStateException if no compilation units were found.
161   * @throws UncheckedIOException  if an IO error occurs.
162   * @see #compile(Workspace)
163   * @see #compile(Workspace, Collection)
164   */
165  default JctCompilation compile(Workspace workspace, String firstClassName,
166      String... additionalClassNames) {
167    return compile(workspace, IterableUtils.combineOneOrMore(firstClassName, additionalClassNames));
168  }
169
170  /**
171   * Invoke the compilation and return the compilation result.
172   *
173   * <p>Only classes matching the given class names will be compiled.
174   *
175   * <p>If you wish to let JCT determine which classes to compile dynamically, see
176   * {@link #compile(Workspace)} instead.
177   *
178   * <p>Note that nested instance/static nested classes cannot be specified individually
179   * here. To compile them, you must also compile their outer class that they are defined
180   * within.
181   *
182   * @param workspace  the workspace to compile.
183   * @param classNames the class names to compile.
184   * @return the compilation result.
185   * @throws JctCompilerException     if the compiler threw an unhandled exception. This should not
186   *                                  occur for compilation failures usually.
187   * @throws NullPointerException     if the {@code classNames} collection contains any null values,
188   *                                  or if the collection itself is null.
189   * @throws IllegalArgumentException if the collection is empty.
190   * @throws IllegalStateException    if no compilation units were found.
191   * @throws UncheckedIOException     if an IO error occurs.
192   * @see #compile(Workspace)
193   * @see #compile(Workspace, String, String...)
194   */
195  JctCompilation compile(Workspace workspace, Collection<String> classNames);
196
197  /**
198   * Apply a given configurer to this compiler that can throw a checked exception.
199   *
200   * @param <E>        any exception that may be thrown.
201   * @param configurer the configurer to invoke.
202   * @return this compiler object for further call chaining.
203   * @throws E any exception that may be thrown by the configurer.
204   */
205  <E extends Exception> JctCompiler configure(JctCompilerConfigurer<E> configurer) throws E;
206
207  /**
208   * Get the friendly printable name of this compiler object.
209   *
210   * @return the name of the compiler.
211   */
212  String getName();
213
214  /**
215   * Set the friendly name of this compiler.
216   *
217   * @param name the name to set.
218   * @return this compiler object for further call chaining.
219   */
220  JctCompiler name(String name);
221
222  /**
223   * Get an <strong>immutable snapshot view</strong> of the current annotation processor options
224   * that are set.
225   *
226   * @return the current annotation processor options that are set.
227   */
228  List<String> getAnnotationProcessorOptions();
229
230  /**
231   * Add options to pass to any annotation processors.
232   *
233   * @param annotationProcessorOptions the options to pass.
234   * @return this compiler object for further call chaining.
235   */
236  JctCompiler addAnnotationProcessorOptions(Iterable<String> annotationProcessorOptions);
237
238  /**
239   * Add options to pass to any annotation processors.
240   *
241   * @param annotationProcessorOption  the first option to pass.
242   * @param annotationProcessorOptions additional options to pass.
243   * @return this compiler object for further call chaining.
244   */
245  default JctCompiler addAnnotationProcessorOptions(
246      String annotationProcessorOption,
247      String... annotationProcessorOptions
248  ) {
249    return addAnnotationProcessorOptions(
250        IterableUtils.combineOneOrMore(annotationProcessorOption, annotationProcessorOptions)
251    );
252  }
253
254  /**
255   * Get an <strong>immutable snapshot view</strong> of the current annotation processors that are
256   * explicitly set to be run, in the order that they were provided to the compiler.
257   *
258   * @return the current annotation processors that are set.
259   */
260  List<Processor> getAnnotationProcessors();
261
262  /**
263   * Add annotation processors to invoke.
264   *
265   * <p>This bypasses the discovery process of annotation processors provided in the annotation
266   * processor path.
267   *
268   * @param annotationProcessors the processors to invoke.
269   * @return this compiler object for further call chaining.
270   */
271  JctCompiler addAnnotationProcessors(Iterable<? extends Processor> annotationProcessors);
272
273  /**
274   * Add annotation processors to invoke.
275   *
276   * <p>This bypasses the discovery process of annotation processors provided in the annotation
277   * processor path.
278   *
279   * @param annotationProcessor  the first processor to invoke.
280   * @param annotationProcessors additional processors to invoke.
281   * @return this compiler object for further call chaining.
282   */
283  default JctCompiler addAnnotationProcessors(
284      Processor annotationProcessor,
285      Processor... annotationProcessors
286  ) {
287    return addAnnotationProcessors(
288        IterableUtils.combineOneOrMore(annotationProcessor, annotationProcessors));
289  }
290
291  /**
292   * Get an <strong>immutable snapshot view</strong> of the current compiler options that are set.
293   *
294   * @return the current compiler  options that are set.
295   */
296  List<String> getCompilerOptions();
297
298  /**
299   * Add command line options to pass to {@code javac}.
300   *
301   * @param compilerOptions the options to add.
302   * @return this compiler object for further call chaining.
303   */
304  JctCompiler addCompilerOptions(Iterable<String> compilerOptions);
305
306  /**
307   * Add command line options to pass to {@code javac}.
308   *
309   * @param compilerOption  the first option to add.
310   * @param compilerOptions additional options to add.
311   * @return this compiler object for further call chaining.
312   */
313  default JctCompiler addCompilerOptions(String compilerOption, String... compilerOptions) {
314    return addCompilerOptions(IterableUtils.combineOneOrMore(compilerOption, compilerOptions));
315  }
316
317  /**
318   * Determine whether verbose logging is enabled or not.
319   *
320   * <p>Unless otherwise changed or specified, implementations should default to
321   * {@link #DEFAULT_VERBOSE}.
322   *
323   * <p>Note that enabling this is compiler-specific behaviour. There is no guarantee that the
324   * output target or the format or verbosity of output will be consistent between different
325   * compiler implementations.
326   *
327   * @return whether verbose logging is enabled or not.
328   */
329  boolean isVerbose();
330
331  /**
332   * Set whether to use verbose output or not.
333   *
334   * <p>Unless otherwise changed or specified, implementations should default to
335   * {@link #DEFAULT_VERBOSE}.
336   *
337   * <p>Note that enabling this is compiler-specific behaviour. There is no guarantee that the
338   * output target or the format or verbosity of output will be consistent between different
339   * compiler implementations.
340   *
341   * @param enabled {@code true} for verbose output, {@code false} for normal output.
342   * @return this compiler for further call chaining.
343   */
344  JctCompiler verbose(boolean enabled);
345
346  /**
347   * Determine whether preview features are enabled or not.
348   *
349   * <p>Unless otherwise changed or specified, implementations should default to
350   * {@link #DEFAULT_PREVIEW_FEATURES}.
351   *
352   * @return whether preview features are enabled or not.
353   */
354  boolean isPreviewFeatures();
355
356  /**
357   * Set whether to enable preview features or not.
358   *
359   * <p>Unless otherwise changed or specified, implementations should default to
360   * {@link #DEFAULT_PREVIEW_FEATURES}.
361   *
362   * @param enabled {@code true} to enable preview features, or {@code false} to disable them.
363   * @return this compiler object for further call chaining.
364   */
365  JctCompiler previewFeatures(boolean enabled);
366
367  /**
368   * Determine whether warnings are enabled or not.
369   *
370   * <p>Unless otherwise changed or specified, implementations should default to
371   * {@link #DEFAULT_SHOW_WARNINGS}.
372   *
373   * @return whether warnings are enabled or not.
374   */
375  boolean isShowWarnings();
376
377  /**
378   * Set whether to enable displaying warnings or not.
379   *
380   * <p>Unless otherwise changed or specified, implementations should default to
381   * {@link #DEFAULT_SHOW_WARNINGS}.
382   *
383   * @param enabled {@code true} to enable warnings. {@code false} to disable them.
384   * @return this compiler object for further call chaining.
385   */
386  JctCompiler showWarnings(boolean enabled);
387
388  /**
389   * Determine whether deprecation warnings are enabled or not.
390   *
391   * <p>Unless otherwise changed or specified, implementations should default to
392   * {@link #DEFAULT_SHOW_DEPRECATION_WARNINGS}.
393   *
394   * @return whether deprecation warnings are enabled or not.
395   */
396  boolean isShowDeprecationWarnings();
397
398  /**
399   * Set whether to enable deprecation warnings or not.
400   *
401   * <p>This is ignored if {@link #showWarnings(boolean)} is disabled.
402   *
403   * <p>Unless otherwise changed or specified, implementations should default to
404   * {@link #DEFAULT_SHOW_DEPRECATION_WARNINGS}.
405   *
406   * @param enabled {@code true} to enable deprecation warnings. {@code false} to disable them.
407   * @return this compiler object for further call chaining.
408   */
409  JctCompiler showDeprecationWarnings(boolean enabled);
410
411  /**
412   * Determine whether warnings are being treated as errors or not.
413   *
414   * <p>Unless otherwise changed or specified, implementations should default to
415   * {@link #DEFAULT_FAIL_ON_WARNINGS}.
416   *
417   * @return whether warnings are being treated as errors or not.
418   */
419  boolean isFailOnWarnings();
420
421  /**
422   * Set whether to enable treating warnings as errors or not.
423   *
424   * <p>This is ignored if {@link #showWarnings(boolean)} is disabled.
425   *
426   * <p>Unless otherwise changed or specified, implementations should default to
427   * {@link #DEFAULT_FAIL_ON_WARNINGS}.
428   *
429   * @param enabled {@code true} to enable treating warnings as errors. {@code false} to disable
430   *                them.
431   * @return this compiler object for further call chaining.
432   */
433  JctCompiler failOnWarnings(boolean enabled);
434
435  /**
436   * Get the compilation mode that is in use.
437   *
438   * <p>Unless otherwise changed or specified, implementations should default to
439   * {@link #DEFAULT_COMPILATION_MODE}.
440   *
441   * @return the compilation mode.
442   */
443  CompilationMode getCompilationMode();
444
445  /**
446   * Set the compilation mode to use for this compiler.
447   *
448   * <p>Unless otherwise changed or specified, implementations should default to
449   * {@link #DEFAULT_COMPILATION_MODE}.
450   *
451   * @param compilationMode the compilation mode to use.
452   * @return this compiler object for further call chaining.
453   */
454  JctCompiler compilationMode(CompilationMode compilationMode);
455
456  /**
457   * Get the default release to use if no release or target version is specified.
458   *
459   * <p>This can <strong>not</strong> be configured.
460   *
461   * @return the default release version to use.
462   */
463  String getDefaultRelease();
464
465  /**
466   * Get the effective release to use for the actual compilation.
467   *
468   * <p>This may be determined from the {@link #getSource() source},
469   * {@link #getTarget() target}, {@link #getRelease() release}, and
470   * {@link #getDefaultRelease() default release.}
471   *
472   * @return the effective release.
473   */
474  String getEffectiveRelease();
475
476  /**
477   * Get the current release version that is set, or {@code null} if left to the compiler to decide.
478   * default.
479   *
480   * <p>Unless explicitly defined, the default setting is expected to be a sane compiler-specific
481   * default.
482   *
483   * @return the release version string, if set.
484   */
485  String getRelease();
486
487  /**
488   * Set the release version.
489   *
490   * <p>This will clear any source and target version that is set.
491   *
492   * <p>Unless explicitly defined, the default setting is expected to be a sane compiler-specific
493   * default.
494   *
495   * @param release the version to set.
496   * @return this compiler object for further call chaining.
497   */
498  JctCompiler release(String release);
499
500  /**
501   * Set the release version.
502   *
503   * <p>This will clear any source and target version that is set.
504   *
505   * <p>Unless explicitly defined, the default setting is expected to be a sane compiler-specific
506   * default.
507   *
508   * @param release the version to set.
509   * @return this compiler object for further call chaining.
510   */
511  default JctCompiler release(int release) {
512    if (release < 0) {
513      throw new IllegalArgumentException("Cannot provide a release version less than 0");
514    }
515
516    return release(Integer.toString(release));
517  }
518
519  /**
520   * Set the release version.
521   *
522   * <p>This will clear any source and target version that is set.
523   *
524   * <p>Unless explicitly defined, the default setting is expected to be a sane compiler-specific
525   * default.
526   *
527   * @param release the version to set.
528   * @return this compiler object for further call chaining.
529   */
530  default JctCompiler release(SourceVersion release) {
531    return release(Integer.toString(release.ordinal()));
532  }
533
534  /**
535   * Request that the compiler uses a language version that corresponds to the
536   * runtime language version in use on the JVM running tests.
537   *
538   * <p>For example, running this on JRE 19 would set the release to "19".
539   *
540   * <p>This calls {@link #release(int) internally}.
541   *
542   * @return this compiler object for further call chaining.
543   */
544  @API(since = "1.1.0", status = Status.STABLE)
545  default JctCompiler useRuntimeRelease() {
546    return release(Runtime.version().feature());
547  }
548
549  /**
550   * Get the current source version that is set, or {@code null} if left to the compiler to decide.
551   * default.
552   *
553   * <p>Unless explicitly defined, the default setting is expected to be a sane compiler-specific
554   * default.
555   *
556   * @return the source version string, if set.
557   */
558  String getSource();
559
560  /**
561   * Set the source version.
562   *
563   * <p>This will clear any release version that is set.
564   *
565   * <p>Unless explicitly defined, the default setting is expected to be a sane compiler-specific
566   * default.
567   *
568   * @param source the version to set.
569   * @return this compiler object for further call chaining.
570   */
571  JctCompiler source(String source);
572
573  /**
574   * Set the source version.
575   *
576   * <p>This will clear any release version that is set.
577   *
578   * <p>Unless explicitly defined, the default setting is expected to be a sane compiler-specific
579   * default.
580   *
581   * @param source the version to set.
582   * @return this compiler object for further call chaining.
583   */
584  default JctCompiler source(int source) {
585    if (source < 0) {
586      throw new IllegalArgumentException("Cannot provide a source version less than 0");
587    }
588
589    return source(Integer.toString(source));
590  }
591
592  /**
593   * Set the source version.
594   *
595   * <p>This will clear any release version that is set.
596   *
597   * <p>Unless explicitly defined, the default setting is expected to be a sane compiler-specific
598   * default.
599   *
600   * @param source the version to set.
601   * @return this compiler object for further call chaining.
602   */
603  default JctCompiler source(SourceVersion source) {
604    return source(Integer.toString(source.ordinal()));
605  }
606
607  /**
608   * Get the current target version that is set, or {@code null} if left to the compiler default.
609   *
610   * <p>Unless explicitly defined, the default setting is expected to be a sane compiler-specific
611   * default.
612   *
613   * @return the target version string, if set.
614   */
615  String getTarget();
616
617  /**
618   * Set the target version.
619   *
620   * <p>This will clear any release version that is set.
621   *
622   * <p>Unless explicitly defined, the default setting is expected to be a sane compiler-specific
623   * default.
624   *
625   * @param target the version to set.
626   * @return this compiler object for further call chaining.
627   */
628  JctCompiler target(String target);
629
630  /**
631   * Set the target version.
632   *
633   * <p>This will clear any release version that is set.
634   *
635   * <p>Unless explicitly defined, the default setting is expected to be a sane compiler-specific
636   * default.
637   *
638   * @param target the version to set.
639   * @return this compiler object for further call chaining.
640   */
641  default JctCompiler target(int target) {
642    if (target < 0) {
643      throw new IllegalArgumentException("Cannot provide a target version less than 0");
644    }
645
646    return target(Integer.toString(target));
647  }
648
649  /**
650   * Set the target version.
651   *
652   * <p>This will clear any release version that is set.
653   *
654   * <p>Unless explicitly defined, the default setting is expected to be a sane compiler-specific
655   * default.
656   *
657   * @param target the version to set.
658   * @return this compiler object for further call chaining.
659   */
660  default JctCompiler target(SourceVersion target) {
661    return target(Integer.toString(target.ordinal()));
662  }
663
664  /**
665   * Get whether we will attempt to fix modules appearing on the classpath, or non-modules appearing
666   * on the module path.
667   *
668   * <p>This enables correct classpath and module path detection when the test pack is a module but
669   * the code being compiled in the test is not, and vice versa. We need this because many build
670   * systems decide whether to populate the {@code --module-path} flat or the {@code --classpath}
671   * with JPMS-enabled dependencies based on whether the project under compilation is a JPMS module
672   * itself.
673   *
674   * <p>This only applies if {@link #isInheritModulePath()} or {@link #isInheritClassPath()} is
675   * enabled, and only applies to the current JVM classpath and module path.
676   *
677   * <p>Unless otherwise changed or specified, implementations should default to
678   * {@link #DEFAULT_FIX_JVM_MODULE_PATH_MISMATCH}.
679   *
680   * @return {@code true} if enabled, or {@code false} if disabled.
681   */
682  boolean isFixJvmModulePathMismatch();
683
684  /**
685   * Get whether we will attempt to fix modules appearing on the classpath, or non-modules appearing
686   * on the module path.
687   *
688   * <p>Unless otherwise changed or specified, implementations should default to
689   * {@link #DEFAULT_FIX_JVM_MODULE_PATH_MISMATCH}.
690   *
691   * @param fixJvmModulePathMismatch whether to enable the mismatch fixing or not.
692   * @return this compiler object for further call chaining.
693   */
694  JctCompiler fixJvmModulePathMismatch(boolean fixJvmModulePathMismatch);
695
696  /**
697   * Get whether the class path is inherited from the caller JVM or not.
698   *
699   * <p>Unless otherwise changed or specified, implementations should default to
700   * {@link #DEFAULT_INHERIT_CLASS_PATH}.
701   *
702   * @return whether the current class path is being inherited or not.
703   */
704  boolean isInheritClassPath();
705
706  /**
707   * Set whether the class path is inherited from the caller JVM or not.
708   *
709   * <p>Unless otherwise changed or specified, implementations should default to
710   * {@link #DEFAULT_INHERIT_CLASS_PATH}.
711   *
712   * @param inheritClassPath {@code true} to include it, or {@code false} to exclude it.
713   * @return this compiler object for further call chaining.
714   */
715  JctCompiler inheritClassPath(boolean inheritClassPath);
716
717  /**
718   * Get whether the module path is inherited from the caller JVM or not.
719   *
720   * <p>Unless otherwise changed or specified, implementations should default to
721   * {@link #DEFAULT_INHERIT_MODULE_PATH}.
722   *
723   * @return whether the module path is being inherited or not.
724   */
725  boolean isInheritModulePath();
726
727  /**
728   * Set whether the module path is inherited from the caller JVM or not.
729   *
730   * <p>Unless otherwise changed or specified, implementations should default to
731   * {@link #DEFAULT_INHERIT_MODULE_PATH}.
732   *
733   * @param inheritModulePath {@code true} to include it, or {@code false} to exclude it.
734   * @return this compiler object for further call chaining.
735   */
736  JctCompiler inheritModulePath(boolean inheritModulePath);
737
738  /**
739   * Get whether the system module path is inherited from the caller JVM or not.
740   *
741   * <p>Unless otherwise changed or specified, implementations should default to
742   * {@link #DEFAULT_INHERIT_SYSTEM_MODULE_PATH}.
743   *
744   * @return whether the system module path is being inherited or not.
745   */
746  boolean isInheritSystemModulePath();
747
748  /**
749   * Set whether the system module path is inherited from the caller JVM or not.
750   *
751   * <p>Unless otherwise changed or specified, implementations should default to
752   * {@link #DEFAULT_INHERIT_SYSTEM_MODULE_PATH}.
753   *
754   * @param inheritSystemModulePath {@code true} to include it, or {@code false} to exclude it.
755   * @return this compiler object for further call chaining.
756   */
757  JctCompiler inheritSystemModulePath(boolean inheritSystemModulePath);
758
759  /**
760   * Get the output locale.
761   *
762   * <p>Unless otherwise changed or specified, implementations should default to
763   * {@link #DEFAULT_LOCALE}.
764   *
765   * @return the output locale to use.
766   */
767  Locale getLocale();
768
769  /**
770   * Set the output locale.
771   *
772   * <p>Unless otherwise changed or specified, implementations should default to
773   * {@link #DEFAULT_LOCALE}.
774   *
775   * @param locale the locale to use.
776   * @return this compiler for further call chaining.
777   */
778  JctCompiler locale(Locale locale);
779
780  /**
781   * Get the charset being used to write compiler logs with.
782   *
783   * <p>Unless otherwise changed or specified, implementations should default to
784   * {@link #DEFAULT_LOG_CHARSET}.
785   *
786   * @return the charset.
787   */
788  Charset getLogCharset();
789
790  /**
791   * Set the charset being used to write compiler logs with.
792   *
793   * <p>Unless otherwise changed or specified, implementations should default to
794   * {@link #DEFAULT_LOG_CHARSET}.
795   *
796   * @param logCharset the charset to use.
797   * @return this compiler for further call chaining.
798   */
799  JctCompiler logCharset(Charset logCharset);
800
801  /**
802   * Get the current file manager logging mode.
803   *
804   * <p>Unless otherwise changed or specified, implementations should default to
805   * {@link #DEFAULT_FILE_MANAGER_LOGGING_MODE}.
806   *
807   * @return the current file manager logging mode.
808   */
809  LoggingMode getFileManagerLoggingMode();
810
811  /**
812   * Set how to handle logging calls to underlying file managers.
813   *
814   * <p>Unless otherwise changed or specified, implementations should default to
815   * {@link #DEFAULT_FILE_MANAGER_LOGGING_MODE}.
816   *
817   * @param fileManagerLoggingMode the mode to use for file manager logging.
818   * @return this compiler for further call chaining.
819   */
820  JctCompiler fileManagerLoggingMode(LoggingMode fileManagerLoggingMode);
821
822  /**
823   * Get the current diagnostic logging mode.
824   *
825   * <p>Unless otherwise changed or specified, implementations should default to
826   * {@link #DEFAULT_DIAGNOSTIC_LOGGING_MODE}.
827   *
828   * @return the current diagnostic logging mode.
829   */
830  LoggingMode getDiagnosticLoggingMode();
831
832  /**
833   * Set how to handle diagnostic capture.
834   *
835   * <p>Unless otherwise changed or specified, implementations should default to
836   * {@link #DEFAULT_DIAGNOSTIC_LOGGING_MODE}.
837   *
838   * @param diagnosticLoggingMode the mode to use for diagnostic capture.
839   * @return this compiler for further call chaining.
840   */
841  JctCompiler diagnosticLoggingMode(LoggingMode diagnosticLoggingMode);
842
843  /**
844   * Get how to perform annotation processor discovery.
845   *
846   * <p>Unless otherwise changed or specified, implementations should default to
847   * {@link #DEFAULT_ANNOTATION_PROCESSOR_DISCOVERY}.
848   *
849   * <p>Specifying any annotation processors explicitly with
850   * {@link #addAnnotationProcessors(Iterable)} or
851   * {@link #addAnnotationProcessors(Processor, Processor...)} will bypass this setting, treating it
852   * as being disabled.
853   *
854   * @return the processor discovery mode to use.
855   */
856  AnnotationProcessorDiscovery getAnnotationProcessorDiscovery();
857
858  /**
859   * Set how to perform annotation processor discovery.
860   *
861   * <p>Unless otherwise changed or specified, implementations should default to
862   * {@link #DEFAULT_ANNOTATION_PROCESSOR_DISCOVERY}.
863   *
864   * <p>Specifying any annotation processors explicitly with
865   * {@link #addAnnotationProcessors(Iterable)} or
866   * {@link #addAnnotationProcessors(Processor, Processor...)} will bypass this setting, treating it
867   * as being disabled.
868   *
869   * @param annotationProcessorDiscovery the processor discovery mode to use.
870   * @return this compiler for further call chaining.
871   */
872  JctCompiler annotationProcessorDiscovery(
873      AnnotationProcessorDiscovery annotationProcessorDiscovery);
874}