// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

library;

// ignore: implementation_imports
import 'package:front_end/src/api_unstable/dart2js.dart' as fe;

import 'commandline_options.dart' show Flags;
import 'util/util.dart';

enum NullSafetyMode { unsound, sound }

enum FeatureStatus { shipped, shipping, canary }

enum CompilerPhase {
  cfe,
  closedWorld,
  globalInference,
  codegen,
  emitJs,
  dumpInfo,
}

enum CompilerStage {
  all(
    'all',
    phases: {
      CompilerPhase.cfe,
      CompilerPhase.closedWorld,
      CompilerPhase.globalInference,
      CompilerPhase.codegen,
      CompilerPhase.emitJs,
    },
  ),
  dumpInfoAll(
    'dump-info-all',
    phases: {
      CompilerPhase.cfe,
      CompilerPhase.closedWorld,
      CompilerPhase.globalInference,
      CompilerPhase.codegen,
      CompilerPhase.emitJs,
      CompilerPhase.dumpInfo,
    },
  ),
  cfe('cfe', phases: {CompilerPhase.cfe}),
  deferredLoadIds(
    'deferred-load-ids',
    dataOutputName: 'deferred_load_ids.data',
    phases: {CompilerPhase.closedWorld},
  ),
  closedWorld(
    'closed-world',
    dataOutputName: 'world.data',
    phases: {CompilerPhase.closedWorld},
  ),
  globalInference(
    'global-inference',
    dataOutputName: 'global.data',
    phases: {CompilerPhase.globalInference},
  ),
  codegenAndJsEmitter(
    'codegen-emit-js',
    phases: {CompilerPhase.codegen, CompilerPhase.emitJs},
  ),
  codegenSharded(
    'codegen',
    dataOutputName: 'codegen',
    phases: {CompilerPhase.codegen},
  ),
  jsEmitter('emit-js', phases: {CompilerPhase.emitJs}),
  dumpInfo(
    'dump-info',
    dataOutputName: 'dump.data',
    phases: {CompilerPhase.dumpInfo},
  );

  const CompilerStage(
    this._stageFlag, {
    this.dataOutputName,
    required this.phases,
  });

  final Set<CompilerPhase> phases;
  final String _stageFlag;
  final String? dataOutputName;

  bool get emitsJs => phases.contains(CompilerPhase.emitJs);
  bool get shouldOnlyComputeDill => this == CompilerStage.cfe;
  bool get canEmitDill =>
      this == CompilerStage.cfe || this == CompilerStage.closedWorld;
  bool get shouldReadPlatformBinaries => phases.contains(CompilerPhase.cfe);
  bool get emitsDumpInfo => phases.contains(CompilerPhase.dumpInfo);
  bool get emitsDeferredLoadIds => this == CompilerStage.deferredLoadIds;

  /// Global kernel transformations should be run in phase 0b, i.e. after
  /// concatenating dills, but before serializing the output of phase 0.
  // TODO(fishythefish): Add AST metadata to ensure transformations aren't rerun
  // unnecessarily.
  bool get shouldRunGlobalTransforms => phases.contains(CompilerPhase.cfe);

  bool get shouldReadClosedWorld => index > CompilerStage.closedWorld.index;
  bool get shouldReadGlobalInference =>
      index > CompilerStage.globalInference.index;
  bool get shouldReadCodegenShards =>
      index > CompilerStage.codegenSharded.index;
  bool get shouldReadDumpInfoData => this == CompilerStage.dumpInfo;
  bool get shouldWriteDumpInfoData =>
      this == CompilerStage.jsEmitter ||
      this == CompilerStage.codegenAndJsEmitter;
  bool get shouldWriteClosedWorld => this == CompilerStage.closedWorld;
  bool get shouldWriteGlobalInference => this == CompilerStage.globalInference;
  bool get shouldWriteCodegen => this == CompilerStage.codegenSharded;

  // Only use deferred reads for the linker and dump info phase as most deferred
  // entities will not be needed. In other phases we use most of this data so
  // it's not worth deferring.
  bool get shouldUseDeferredSourceReads =>
      this == CompilerStage.jsEmitter || this == CompilerStage.dumpInfo;

  String get toFlag => _stageFlag;

  static String get validFlagValuesString {
    return CompilerStage.values.map((p) => '`${p._stageFlag}`').join(', ');
  }

  static CompilerStage fromFlag(String? stageFlag) {
    if (stageFlag == null) return CompilerStage.all;
    for (final stage in CompilerStage.values) {
      if (stageFlag == stage._stageFlag) {
        return stage;
      }
    }
    throw ArgumentError(
      'Invalid stage: $stageFlag. '
      'Supported values are: $validFlagValuesString',
    );
  }
}

/// A [FeatureOption] is both a set of flags and an option. By default, creating
/// a [FeatureOption] will create two flags, `--$flag` and `--no-$flag`. The
/// default behavior for a [FeatureOption] in the [FeatureOptions.canary] set is
/// to be disabled by default unless explicity enabled or `--canary` is passed.
/// When the [FeatureOption] is moved to [FeatureOptions.shipping], the behavior
/// flips, and by default it is enabled unless explicitly disabled or
/// `--no-shipping` is passed. The [FeatureOption.isNegativeFlag] bool flips
/// things around so while in canary the [FeatureOption] is enabled unless
/// explicitly disabled, and while in [FeatureOptions.shipping] it is disabled
/// unless explicitly enabled.
///
/// Finally, mature features can be moved to [FeatureOptions.shipped], at which
/// point we ignore the flag, but throw if the value of the flag is
/// unexpected(i.e. if a positive flag is disabled, or a negative flag is
/// enabled).
class FeatureOption {
  final String flag;
  final bool isNegativeFlag;
  bool? _state;
  bool get isEnabled => _state!;
  bool get isDisabled => !isEnabled;
  set state(bool value) {
    assert(_state == null);
    _state = value;
  }

  set override(bool value) {
    assert(_state != null);
    _state = value;
  }

  FeatureOption(this.flag, {this.isNegativeFlag = false});
}

/// A class to simplify management of features which will end up being enabled
/// by default. New features should be added as properties, and then to the
/// [canary] list. Features in [canary] default to disabled unless they are
/// explicitly enabled or unless `--canary` is passed on the commandline. When
/// a feature is ready to ship, it should be moved to the [shipping] list,
/// whereupon it will immediately default to enabled but can still be disabled.
/// Once a feature is shipped, it can be deleted from this class entirely.
class FeatureOptions {
  /// Whether to restrict the generated JavaScript to features that work on the
  /// oldest supported versions of JavaScript. This currently means IE11. If
  /// `true`, the generated code runs on the legacy JavaScript platform. If
  /// `false`, the code will fail on the legacy JavaScript platform.
  FeatureOption legacyJavaScript = FeatureOption(
    'legacy-javascript',
    isNegativeFlag: true,
  );

  /// Whether to use optimized holders.
  FeatureOption newHolders = FeatureOption('new-holders');

  /// Whether to generate code compliant with Content Security Policy.
  FeatureOption useContentSecurityPolicy = FeatureOption('csp');

  /// Whether to emit JavaScript encoded as UTF-8.
  FeatureOption writeUtf8 = FeatureOption('utf8');

  /// Experimental instrumentation to add tree shaking information to
  /// dump-info's output.
  FeatureOption newDumpInfo = FeatureOption('new-dump-info');

  /// Whether to implement some simple async functions using Futures directly
  /// to reduce generated code size.
  FeatureOption simpleAsyncToFuture = FeatureOption('simple-async-to-future');

  /// Whether or not the CFE should evaluate constants.
  FeatureOption cfeConstants = FeatureOption('cfe-constants');

  /// Whether or not to intern composite values during deserialization
  /// (e.g. DartType).
  FeatureOption internValues = FeatureOption('intern-composite-values');

  /// [FeatureOption]s which are shipped and cannot be toggled.
  late final List<FeatureOption> shipped = [newHolders, legacyJavaScript];

  /// [FeatureOption]s which default to enabled.
  late final List<FeatureOption> shipping = [
    useContentSecurityPolicy,
    internValues,
  ];

  /// [FeatureOption]s which default to disabled.
  late final List<FeatureOption> canary = [
    writeUtf8,
    newDumpInfo,
    simpleAsyncToFuture,
    cfeConstants,
  ];

  /// Forces canary feature on. This must run after [Option].parse.
  void forceCanary() {
    for (var feature in canary) {
      feature.override = feature.isNegativeFlag ? false : true;
    }
  }

  /// Returns a list of enabled features as a comma separated string.
  String flavorString() {
    bool shouldPrint(FeatureOption feature) {
      return feature.isNegativeFlag ? feature.isDisabled : feature.isEnabled;
    }

    String toString(FeatureOption feature) {
      return feature.isNegativeFlag ? 'no-${feature.flag}' : feature.flag;
    }

    Iterable<String> listToString(List<FeatureOption> options) {
      return options.where(shouldPrint).map(toString);
    }

    return listToString(shipping).followedBy(listToString(canary)).join(', ');
  }

  /// Parses a [List<String>] and enables / disables features as necessary.
  void parse(List<String> options) {
    _verifyShippedFeatures(options, shipped);
    _extractFeatures(options, shipping, FeatureStatus.shipping);
    _extractFeatures(options, canary, FeatureStatus.canary);
  }
}

/// Options used for controlling diagnostic messages.
abstract class DiagnosticOptions {
  const DiagnosticOptions();

  /// If `true`, warnings cause the compilation to fail.
  bool get fatalWarnings;

  /// Emit terse diagnostics without howToFix.
  bool get terseDiagnostics;

  /// If `true`, warnings are not reported.
  bool get suppressWarnings;

  /// If `true`, hints are not reported.
  bool get suppressHints;

  /// Returns `true` if warnings and hints are shown for all packages.
  bool get showAllPackageWarnings;

  /// Returns `true` if warnings and hints are hidden for all packages.
  bool get hidePackageWarnings;

  /// Returns `true` if warnings should be should for [uri].
  bool showPackageWarningsFor(Uri uri);
}

/// Object for passing options to the compiler. Superclasses are used to select
/// subsets of these options, enabling each part of the compiler to depend on
/// as few as possible.
class CompilerOptions implements DiagnosticOptions {
  /// The entry point of the application that is being compiled.
  Uri? entryUri;

  /// The input dill to compile.
  Uri? _inputDillUri;

  Uri get _defaultInputDillUri =>
      _outputDir.resolve('${_outputPrefix}out.dill');

  Uri get inputDillUri {
    return _inputDillUri != null
        ? fe.nativeToUri(_inputDillUri.toString())
        : _defaultInputDillUri;
  }

  /// Returns the compilation target specified by these options.
  Uri get compilationTarget =>
      _inputDillUri ?? entryUri ?? _defaultInputDillUri;

  bool get shouldLoadFromDill {
    final targetPath = (_inputDillUri ?? entryUri)?.path;
    return targetPath == null || targetPath.endsWith('.dill');
  }

  /// Location of the package configuration file.
  Uri? packageConfig;

  /// List of kernel files to load.
  ///
  /// This contains all kernel files that form part of the final program. The
  /// dills passed here should contain full kernel ASTs, not just outlines.
  List<Uri>? dillDependencies;

  /// Uses a memory mapped view of files for I/O.
  bool memoryMappedFiles = false;

  /// Location from which serialized inference data is read/written.
  Uri? _globalInferenceUri;

  /// Location from which the serialized closed world is read/written.
  Uri? _closedWorldUri;

  /// Location from which codegen data is read/written.
  Uri? _codegenUri;

  // TODO(natebiggs): Delete this once Flutter is using the stage flag.
  /// Whether to run only the CFE and emit the generated kernel file in
  /// [outputUri]. Equivalent to `--stage=cfe`.
  bool _cfeOnly = false;

  /// Which stage of the compiler to run. Maps to a stage from [CompilerStage].
  String? _stageFlag;

  /// Flag only meant for dart2js developers to iterate on global inference
  /// changes.
  ///
  /// When working on large apps this flag allows to load serialized data for
  /// the app (via --read-data), reuse its closed world, and rerun the global
  /// inference stage (even though the serialized data already contains a global
  /// inference result).
  bool debugGlobalInference = false;

  /// Resolved constant "environment" values passed to the compiler via the `-D`
  /// flags.
  Map<String, String> environment = const <String, String>{};

  /// Flags enabling language experiments.
  Map<fe.ExperimentalFlag, bool> explicitExperimentalFlags = {};

  /// `true` if variance is enabled.
  bool get enableVariance => fe.isExperimentEnabled(
    fe.ExperimentalFlag.variance,
    explicitExperimentalFlags: explicitExperimentalFlags,
  );

  /// A possibly null state object for kernel compilation.
  fe.InitializedCompilerState? kernelInitializedCompilerState;

  /// Whether we allow mocking compilation of libraries such as dart:io and
  /// dart:html for unit testing purposes.
  bool allowMockCompilation = false;

  /// Sets a combination of flags for benchmarking 'production' mode.
  bool benchmarkingProduction = false;

  /// Sets a combination of flags for benchmarking 'experiment' mode.
  bool benchmarkingExperiment = false;

  /// ID associated with this sdk build.
  String buildId = _undeterminedBuildID;

  /// Whether there is a build-id available so we can use it on error messages
  /// and in the emitted output of the compiler.
  bool get hasBuildId => buildId != _undeterminedBuildID;

  /// Whether to compile for the server category. This is used to compile to JS
  /// that is intended to be run on server-side VMs like nodejs.
  bool compileForServer = false;

  /// Location where to generate a map containing details of how deferred
  /// libraries are subdivided.
  Uri? deferredMapUri;

  /// Location to generate a map containing mapping from user-defined deferred
  /// import to Dart2js runtime load ID name.
  Uri? _deferredLoadIdMapUri;

  /// Location where to generate an internal format representing the deferred
  /// graph.
  Uri? deferredGraphUri;

  /// The maximum number of deferred fragments to generate. If the number of
  /// fragments exceeds this amount, then they may be merged.
  /// Note: Currently, we only merge fragments in a single dependency chain. We
  /// will not merge fragments with unrelated dependencies and thus we may
  /// generate more fragments than the 'mergeFragmentsThreshold' under some
  /// situations.
  int? mergeFragmentsThreshold; // default value, no max.
  int? _mergeFragmentsThreshold;

  /// Whether to disable inlining during the backend optimizations.
  // TODO(sigmund): negate, so all flags are positive
  bool disableInlining = false;

  /// Disable deferred loading, instead generate everything in one output unit.
  /// Note: the resulting program still correctly checks that loadLibrary &
  /// checkLibrary calls are correct.
  bool disableProgramSplit = false;

  /// Reads a program split json file and applies the parsed constraints to
  /// deferred loading.
  Uri? readProgramSplit;

  /// Diagnostic option: If `true`, warnings cause the compilation to fail.
  @override
  bool fatalWarnings = false;

  /// Diagnostic option: Emit terse diagnostics without howToFix.
  @override
  bool terseDiagnostics = false;

  /// Diagnostic option: If `true`, warnings are not reported.
  @override
  bool suppressWarnings = false;

  /// Diagnostic option: If `true`, hints are not reported.
  @override
  bool suppressHints = false;

  /// Diagnostic option: List of packages for which warnings and hints are
  /// reported. If `null`, no package warnings or hints are reported. If
  /// empty, all warnings and hints are reported.
  List<String>? shownPackageWarnings;

  /// Whether to disable global type inference.
  bool disableTypeInference = false;

  /// Whether to use the trivial abstract value domain.
  bool useTrivialAbstractValueDomain = false;

  /// Whether to use the wrapped abstract value domain (experimental).
  bool experimentalWrapped = false;

  /// Whether to use the powersets abstract value domain (experimental).
  bool experimentalPowersets = false;

  /// Whether to disable optimization for need runtime type information.
  bool disableRtiOptimization = false;

  /// Uri to read/write dump info requisite data after emitting JS. This
  /// contains data captured from the JS printer and processed for the dump info
  /// task.
  /// The file emitted to the URI can then be read in using to run dump info as
  /// a standalone task (without re-emitting JS).
  Uri? _dumpInfoDataUri;

  /// Whether to use the new dump-info binary format. This will be the default
  /// after a transitional period.
  bool useDumpInfoBinaryFormat = false;

  /// If set, SSA intermediate form is dumped for methods with names matching
  /// this RegExp pattern.
  String? dumpSsaPattern;

  /// Whether to generate a `.resources.json` file detailing the use of resource
  /// identifiers.
  bool writeResources = false;

  /// Whether we allow passing an extra argument to `assert`, containing a
  /// reason for why an assertion fails. (experimental)
  ///
  /// This is only included so that tests can pass the --assert-message flag
  /// without causing dart2js to crash. The flag has no effect.
  bool enableAssertMessage = true;

  /// Whether to enable minification
  // TODO(sigmund): rename to minify
  bool enableMinification = false;

  /// Flag to turn off minification even if enabled elsewhere, e.g. via
  /// -O2. Both [enableMinification] and [_disableMinification] can be true, in
  /// which case [_disableMinification] wins.
  bool _disableMinification = false;

  /// Whether to omit names of late variables from error messages.
  bool omitLateNames = false;

  /// Flag to turn off `omitLateNames` even if enabled elsewhere, e.g. via
  /// `-O2`. Both [omitLateNames] and [_noOmitLateNames] can be true, in which
  /// case [_noOmitLateNames] wins.
  bool _noOmitLateNames = false;

  /// Whether to model which native classes are live based on annotations on the
  /// core libraries. If false, all native classes will be included by default.
  bool enableNativeLiveTypeAnalysis = true;

  /// Whether to generate code containing user's `assert` statements.
  bool enableUserAssertions = false;

  /// Whether to generate code asserting that non-nullable parameters in opt-in
  /// code are not null. In mixed mode code (some opting into non-nullable, some
  /// not), null-safety is unsound, allowing `null` values to be assigned to
  /// variables with non-nullable types. This assertion lets the opt-in code
  /// operate with a stronger guarantee.
  bool enableNullAssertions = false;

  /// Whether to generate code asserting that non-nullable return values of
  /// `@Native` methods or `JS()` invocations are checked for being non-null.
  /// Emits checks only in sound null-safety.
  bool nativeNullAssertions = false;
  bool _noNativeNullAssertions = false;

  /// Whether to generate code asserting that return values of JS-interop APIs
  /// with non-nullable return types are not null.
  bool interopNullAssertions = false;
  bool _noInteropNullAssertions = false;

  /// Whether to generate a source-map file together with the output program.
  bool generateSourceMap = true;

  /// Location of the libraries specification file.
  Uri? librariesSpecificationUri;

  /// Location of the kernel platform `.dill` files.
  Uri? platformBinaries;

  /// Whether to print legacy types as T* rather than T.
  bool printLegacyStars = false;

  /// URI where the compiler should generate the output source map file.
  Uri? sourceMapUri;

  /// The compiler is run from the build bot.
  bool testMode = false;

  /// Whether to use the development type inferrer.
  bool experimentalInferrer = false;

  /// Whether to trust primitive types during inference and optimizations.
  bool trustPrimitives = false;

  /// Whether to omit implicit strong mode checks.
  bool omitImplicitChecks = false;

  /// Whether to omit as casts by default.
  bool omitAsCasts = false;

  /// Whether to omit class type arguments only needed for `toString` on
  /// `Object.runtimeType`.
  bool laxRuntimeTypeToString = false;

  /// What should the compiler do with parameter type assertions.
  ///
  /// This is an internal configuration option derived from other flags.
  late CheckPolicy defaultParameterCheckPolicy;

  /// What should the compiler do with implicit downcasts.
  ///
  /// This is an internal configuration option derived from other flags.
  late CheckPolicy defaultImplicitDowncastCheckPolicy;

  /// What the compiler should do with a boolean value in a condition context
  /// when the language specification says it is a runtime error for it to be
  /// null.
  ///
  /// This is an internal configuration option derived from other flags.
  late CheckPolicy defaultConditionCheckPolicy;

  /// What should the compiler do with explicit casts.
  ///
  /// This is an internal configuration option derived from other flags.
  late CheckPolicy defaultExplicitCastCheckPolicy;

  /// What should the compiler do with List index bounds checks.
  ///
  /// This is an internal configuration option derived from other flags.
  late CheckPolicy defaultIndexBoundsCheckPolicy;

  /// When obfuscating for minification, whether to use the frequency of a name
  /// as an heuristic to pick shorter names.
  bool useFrequencyNamer = true;

  /// Whether to generate source-information from both the old and the new
  /// source-information engines. (experimental)
  bool useMultiSourceInfo = false;

  /// Whether to use the new source-information implementation for source-maps.
  /// (experimental)
  bool useNewSourceInfo = false;

  /// Whether or not use simple load ids.
  bool useSimpleLoadIds = false;

  /// Enable verbose printing during compilation. Includes a time-breakdown
  /// between phases at the end.
  bool verbose = false;

  /// On top of --verbose, enable more verbose printing, like progress messages
  /// during each phase of compilation.
  bool showInternalProgress = false;

  /// Enable printing of metrics at end of compilation.
  // TODO(sra): Add command-line filtering of metrics.
  bool reportPrimaryMetrics = false;

  /// Enable printing of more metrics at end of compilation.
  // TODO(sra): Add command-line filtering of metrics.
  bool reportSecondaryMetrics = false;

  /// Track allocations in the JS output.
  ///
  /// This is an experimental feature.
  bool experimentalTrackAllocations = false;

  /// Experimental part file function generation.
  bool experimentStartupFunctions = false;

  /// Experimental reliance on JavaScript ToBoolean conversions.
  bool experimentToBoolean = false;

  // Experiment to make methods that are inferred as unreachable throw an
  // exception rather than generate suspect code.
  bool experimentUnreachableMethodsThrow = false;

  /// Experimental instrumentation to investigate code bloat.
  ///
  /// If [true], the compiler will emit code that logs whenever a method is
  /// called.
  bool experimentCallInstrumentation = false;

  /// Experiment to add additional runtime checks to detect code whose semantics
  /// will change when sound null safety is enabled.
  ///
  /// In particular, runtime subtype checks (including those via `is` and `as`)
  /// will produce diagnostics when they would provide different results in
  /// sound vs. unsound mode. Note that this adds overhead, both to perform the
  /// extra checks and because some checks that may have been optimized away
  /// will be emitted.
  ///
  /// We assume this option will only be provided when all files have been
  /// migrated to null safety (but before sound null safety is enabled).
  bool experimentNullSafetyChecks = false;

  /// Whether the compiler should emit code with unsound or sound semantics.
  /// Since Dart 3.0 this is no longer inferred from sources, but defaults to
  /// sound semantics.
  ///
  /// This option should rarely need to be accessed directly. Consider using
  /// [useLegacySubtyping] instead.
  NullSafetyMode nullSafetyMode = NullSafetyMode.sound;
  bool _soundNullSafety = false;
  bool _noSoundNullSafety = false;

  /// Whether to use legacy subtype semantics rather than null-safe semantics.
  /// This is `true` if unsound null-safety semantics are being used, since
  /// dart2js does not emit warnings for unsound null-safety.
  bool get useLegacySubtyping {
    return nullSafetyMode == NullSafetyMode.unsound;
  }

  /// If specified, a bundle of optimizations to enable (or disable).
  int? optimizationLevel;

  /// The shard to serialize when using [Flags.writeCodegen].
  int? codegenShard;

  /// The number of shards to serialize when using [Flags.writeCodegen] or to
  /// deserialize when using [Flags.readCodegen].
  int? codegenShards;

  /// Arguments passed to the front end about how it is invoked.
  ///
  /// This is used to selectively emit certain messages depending on how the
  /// CFE is invoked. For instance to emit a message about the null safety
  /// compilation mode when compiling an executable.
  ///
  /// See `InvocationMode` in
  /// `pkg/front_end/lib/src/api_prototype/compiler_options.dart` for all
  /// possible options.
  Set<fe.InvocationMode> cfeInvocationModes = {};

  /// Verbosity level used for filtering messages during compilation.
  fe.Verbosity verbosity = fe.Verbosity.all;

  // Whether or not to dump a list of unused libraries.
  bool dumpUnusedLibraries = false;

  // Whether or not to disable byte cache for sources loaded from Kernel dill.
  bool disableDiagnosticByteCache = false;

  bool enableProtoShaking = false;

  bool get producesModifiedDill =>
      stage == CompilerStage.closedWorld && enableProtoShaking;

  late final CompilerStage stage = _calculateStage();

  CompilerStage _calculateStage() =>
      _cfeOnly ? CompilerStage.cfe : CompilerStage.fromFlag(_stageFlag);

  Uri? _outputUri;
  Uri? outputUri;

  String get _outputFilename => _outputUri?.pathSegments.last ?? '';

  String? get _outputExtension {
    switch (stage) {
      case CompilerStage.all:
      case CompilerStage.dumpInfoAll:
      case CompilerStage.jsEmitter:
      case CompilerStage.codegenAndJsEmitter:
      case CompilerStage.dumpInfo:
        return '.js';
      case CompilerStage.cfe:
        return '.dill';
      case CompilerStage.closedWorld:
        if (producesModifiedDill) return '.dill';
      case CompilerStage.deferredLoadIds:
      case CompilerStage.globalInference:
      case CompilerStage.codegenSharded:
    }
    return null;
  }

  /// Output prefix specified by the user via the `--out` flag. The prefix is
  /// calculated from the final segment of the user provided URI. If the
  /// extension does not match the expected extension for the current [stage]
  /// then the last segment is treated as a prefix. Only set when `--stage` is
  /// specified.
  late final String _outputPrefix =
      (() {
        if (_stageFlag == null) return '';
        final extension = _outputExtension;

        return (extension != null && _outputFilename.endsWith(extension))
            ? ''
            : _outputFilename;
      })();

  /// Output directory specified by the user via the `--out` flag. The directory
  /// is calculated by resolving the substring prior to the final URI segment
  /// (i.e. before the final slash) relative to [Uri.base]. Defaults to
  /// [Uri.base] if `--out` is not provided or does not include a directory.
  late final Uri _outputDir =
      (() =>
          (_outputUri != null)
              ? Uri.base.resolveUri(_outputUri!).resolve('.')
              : Uri.base)();

  /// Computes a resolved output URI based on value provided via the `--out`
  /// flag. Updates [outputUri] based on the result and returns the value.
  Uri? setResolvedOutputUri() {
    final extension = _outputExtension;
    if (extension == null) return null;

    if (_stageFlag == null) {
      return outputUri = _outputDir.resolve(
        _outputFilename.isEmpty ? 'out$extension' : _outputFilename,
      );
    }

    String fullName = _outputFilename;
    if (!fullName.endsWith(extension)) {
      fullName += 'out$extension';
    }
    return outputUri = _outputDir.resolve(fullName);
  }

  /// Sets [outputUri] to the value provided via `--out` without any processing.
  void setDefaultOutputUriForTesting() {
    outputUri = _outputUri;
  }

  Uri? _getSpecifiedDataPath(CompilerStage stage) {
    switch (stage) {
      case CompilerStage.all:
      case CompilerStage.dumpInfoAll:
      case CompilerStage.cfe:
      case CompilerStage.jsEmitter:
      case CompilerStage.codegenAndJsEmitter:
        return null;
      case CompilerStage.deferredLoadIds:
        return _deferredLoadIdMapUri;
      case CompilerStage.closedWorld:
        return _closedWorldUri;
      case CompilerStage.globalInference:
        return _globalInferenceUri;
      case CompilerStage.codegenSharded:
        return _codegenUri;
      case CompilerStage.dumpInfo:
        return _dumpInfoDataUri;
    }
  }

  Uri dataUriForStage(CompilerStage stage) {
    final dataUri = _getSpecifiedDataPath(stage);
    if (dataUri != null) return dataUri;

    if (stage.dataOutputName != null) {
      final filename = '$_outputPrefix${stage.dataOutputName}';
      return _outputDir.resolve(filename);
    }
    throw ArgumentError('No data input generated for stage: $stage');
  }

  late FeatureOptions features;

  // -------------------------------------------------
  // Options for deprecated features
  // -------------------------------------------------

  /// Create an options object by parsing flags from [options].
  static CompilerOptions parse(
    List<String> options, {
    FeatureOptions? featureOptions,
    Uri? librariesSpecificationUri,
    Uri? platformBinaries,
    bool useDefaultOutputUri = false,
    void Function(String)? onError,
    void Function(String)? onWarning,
  }) {
    featureOptions ??= FeatureOptions();
    featureOptions.parse(options);
    Map<fe.ExperimentalFlag, bool> explicitExperimentalFlags =
        _extractExperiments(options, onError: onError, onWarning: onWarning);

    // The null safety experiment can result in requiring different experiments
    // for compiling user code vs. the sdk. To simplify things, we prebuild the
    // sdk with the correct flags.
    platformBinaries ??= fe.computePlatformBinariesLocation();
    return CompilerOptions()
      ..entryUri = _extractUriOption(options, '${Flags.entryUri}=')
      .._inputDillUri = _extractUriOption(options, '${Flags.inputDill}=')
      ..librariesSpecificationUri = librariesSpecificationUri
      ..allowMockCompilation = _hasOption(options, Flags.allowMockCompilation)
      ..benchmarkingProduction = _hasOption(
        options,
        Flags.benchmarkingProduction,
      )
      ..benchmarkingExperiment = _hasOption(
        options,
        Flags.benchmarkingExperiment,
      )
      ..buildId =
          _extractStringOption(options, '--build-id=', _undeterminedBuildID)!
      ..compileForServer = _hasOption(options, Flags.serverMode)
      ..deferredMapUri = _extractUriOption(options, '--deferred-map=')
      .._deferredLoadIdMapUri = _extractUriOption(
        options,
        '${Flags.deferredLoadIdMapUri}=',
      )
      ..deferredGraphUri = _extractUriOption(
        options,
        '${Flags.dumpDeferredGraph}=',
      )
      ..fatalWarnings = _hasOption(options, Flags.fatalWarnings)
      ..terseDiagnostics = _hasOption(options, Flags.terse)
      ..suppressWarnings = _hasOption(options, Flags.suppressWarnings)
      ..suppressHints = _hasOption(options, Flags.suppressHints)
      ..shownPackageWarnings = _extractOptionalCsvOption(
        options,
        Flags.showPackageWarnings,
      )
      ..explicitExperimentalFlags = explicitExperimentalFlags
      ..disableInlining = _hasOption(options, Flags.disableInlining)
      ..disableProgramSplit = _hasOption(options, Flags.disableProgramSplit)
      ..disableTypeInference = _hasOption(options, Flags.disableTypeInference)
      ..useTrivialAbstractValueDomain = _hasOption(
        options,
        Flags.useTrivialAbstractValueDomain,
      )
      ..experimentalWrapped = _hasOption(options, Flags.experimentalWrapped)
      ..experimentalPowersets = _hasOption(options, Flags.experimentalPowersets)
      ..disableRtiOptimization = _hasOption(
        options,
        Flags.disableRtiOptimization,
      )
      .._dumpInfoDataUri = _extractUriOption(
        options,
        '${Flags.dumpInfoDataUri}=',
      )
      ..useDumpInfoBinaryFormat = _hasOption(
        options,
        "${Flags.dumpInfo}=binary",
      )
      ..dumpSsaPattern = _extractStringOption(
        options,
        '${Flags.dumpSsa}=',
        null,
      )
      ..writeResources = _hasOption(options, Flags.writeResources)
      ..enableMinification = _hasOption(options, Flags.minify)
      .._disableMinification = _hasOption(options, Flags.noMinify)
      ..omitLateNames = _hasOption(options, Flags.omitLateNames)
      .._noOmitLateNames = _hasOption(options, Flags.noOmitLateNames)
      ..enableNativeLiveTypeAnalysis =
          !_hasOption(options, Flags.disableNativeLiveTypeAnalysis)
      ..enableUserAssertions =
          _hasOption(options, Flags.enableCheckedMode) ||
          _hasOption(options, Flags.enableAsserts)
      ..enableNullAssertions =
          _hasOption(options, Flags.enableCheckedMode) ||
          _hasOption(options, Flags.enableNullAssertions)
      ..nativeNullAssertions = _hasOption(options, Flags.nativeNullAssertions)
      .._noNativeNullAssertions = _hasOption(
        options,
        Flags.noNativeNullAssertions,
      )
      ..interopNullAssertions = _hasOption(options, Flags.interopNullAssertions)
      .._noInteropNullAssertions = _hasOption(
        options,
        Flags.noInteropNullAssertions,
      )
      ..experimentalTrackAllocations = _hasOption(
        options,
        Flags.experimentalTrackAllocations,
      )
      ..experimentStartupFunctions = _hasOption(
        options,
        Flags.experimentStartupFunctions,
      )
      ..experimentToBoolean = _hasOption(options, Flags.experimentToBoolean)
      ..experimentUnreachableMethodsThrow = _hasOption(
        options,
        Flags.experimentUnreachableMethodsThrow,
      )
      ..experimentCallInstrumentation = _hasOption(
        options,
        Flags.experimentCallInstrumentation,
      )
      ..experimentNullSafetyChecks = _hasOption(
        options,
        Flags.experimentNullSafetyChecks,
      )
      ..generateSourceMap = !_hasOption(options, Flags.noSourceMaps)
      .._outputUri = _extractUriOption(options, '--out=')
      ..platformBinaries = platformBinaries
      ..printLegacyStars = _hasOption(options, Flags.printLegacyStars)
      ..sourceMapUri = _extractUriOption(options, '--source-map=')
      ..omitImplicitChecks = _hasOption(options, Flags.omitImplicitChecks)
      ..omitAsCasts = _hasOption(options, Flags.omitAsCasts)
      ..laxRuntimeTypeToString = _hasOption(
        options,
        Flags.laxRuntimeTypeToString,
      )
      ..enableProtoShaking = _hasOption(options, Flags.enableProtoShaking)
      ..testMode = _hasOption(options, Flags.testMode)
      ..trustPrimitives = _hasOption(options, Flags.trustPrimitives)
      ..useFrequencyNamer =
          !_hasOption(options, Flags.noFrequencyBasedMinification)
      ..useMultiSourceInfo = _hasOption(options, Flags.useMultiSourceInfo)
      ..useNewSourceInfo = _hasOption(options, Flags.useNewSourceInfo)
      ..useSimpleLoadIds = _hasOption(options, Flags.useSimpleLoadIds)
      ..verbose = _hasOption(options, Flags.verbose)
      ..reportPrimaryMetrics = _hasOption(options, Flags.reportMetrics)
      ..reportSecondaryMetrics = _hasOption(options, Flags.reportAllMetrics)
      ..showInternalProgress = _hasOption(options, Flags.progress)
      ..dillDependencies = _extractUriListOption(
        options,
        Flags.dillDependencies,
      )
      ..readProgramSplit = _extractUriOption(
        options,
        '${Flags.readProgramSplit}=',
      )
      .._globalInferenceUri = _extractUriOption(
        options,
        '${Flags.globalInferenceUri}=',
      )
      ..memoryMappedFiles = _hasOption(options, Flags.memoryMappedFiles)
      .._closedWorldUri = _extractUriOption(options, '${Flags.closedWorldUri}=')
      .._codegenUri = _extractUriOption(options, '${Flags.codegenUri}=')
      ..codegenShard = _extractIntOption(options, '${Flags.codegenShard}=')
      ..codegenShards = _extractIntOption(options, '${Flags.codegenShards}=')
      .._cfeOnly = _hasOption(options, Flags.cfeOnly)
      .._stageFlag = _extractStringOption(options, '${Flags.stage}=', null)
      ..debugGlobalInference = _hasOption(options, Flags.debugGlobalInference)
      .._soundNullSafety = _hasOption(options, Flags.soundNullSafety)
      .._noSoundNullSafety = _hasOption(options, Flags.noSoundNullSafety)
      .._mergeFragmentsThreshold = _extractIntOption(
        options,
        '${Flags.mergeFragmentsThreshold}=',
      )
      ..dumpUnusedLibraries = _hasOption(options, Flags.dumpUnusedLibraries)
      ..cfeInvocationModes = fe.InvocationMode.parseArguments(
        _extractStringOption(options, '${Flags.cfeInvocationModes}=', '')!,
        onError: onError,
      )
      ..verbosity = fe.Verbosity.parseArgument(
        _extractStringOption(
          options,
          '${Flags.verbosity}=',
          fe.Verbosity.defaultValue,
        )!,
        onError: onError,
      )
      ..disableDiagnosticByteCache = _hasOption(
        options,
        Flags.disableDiagnosticByteCache,
      )
      ..features = featureOptions;
  }

  String? validateStage() {
    bool expectCodegenIn = false;
    bool expectCodegenOut = false;
    switch (stage) {
      case CompilerStage.all:
      case CompilerStage.dumpInfoAll:
      case CompilerStage.cfe:
      case CompilerStage.deferredLoadIds:
      case CompilerStage.closedWorld:
      case CompilerStage.globalInference:
      case CompilerStage.codegenAndJsEmitter:
      case CompilerStage.dumpInfo:
        break;
      case CompilerStage.codegenSharded:
        expectCodegenOut = true;
        break;
      case CompilerStage.jsEmitter:
        expectCodegenIn = true;
        break;
    }

    if (codegenShard == null && expectCodegenOut) {
      return 'Must specify value for ${Flags.codegenShard} '
          'in stage ${stage.name}.';
    }

    if (codegenShards == null && expectCodegenOut) {
      return 'Must specify value for ${Flags.codegenShards} '
          'in stage ${stage.name}.';
    }
    if (codegenShards == null && expectCodegenIn) {
      return 'Must specify value for ${Flags.codegenShards} '
          'in stage ${stage.name}.';
    }
    return null;
  }

  void validate() {
    if (librariesSpecificationUri == null) {
      throw ArgumentError("[librariesSpecificationUri] is null.");
    }
    if (librariesSpecificationUri!.path.endsWith('/')) {
      throw ArgumentError(
        "[librariesSpecificationUri] should be a file: $librariesSpecificationUri",
      );
    }
    Map<fe.ExperimentalFlag, bool> experimentalFlags = Map.from(
      fe.defaultExperimentalFlags,
    );
    experimentalFlags.addAll(explicitExperimentalFlags);
    if (platformBinaries == null &&
        equalMaps(experimentalFlags, fe.defaultExperimentalFlags)) {
      throw ArgumentError("Missing required ${Flags.platformBinaries}");
    }
    if (_soundNullSafety && _noSoundNullSafety) {
      throw ArgumentError(
        "'${Flags.soundNullSafety}' is incompatible with "
        "'${Flags.noSoundNullSafety}'",
      );
    }
    if (nativeNullAssertions && _noNativeNullAssertions) {
      throw ArgumentError(
        "'${Flags.nativeNullAssertions}' is incompatible with "
        "'${Flags.noNativeNullAssertions}'",
      );
    }
    if (interopNullAssertions && _noInteropNullAssertions) {
      throw ArgumentError(
        "'${Flags.interopNullAssertions}' is incompatible with "
        "'${Flags.noInteropNullAssertions}'",
      );
    }
    if (nullSafetyMode == NullSafetyMode.sound && experimentNullSafetyChecks) {
      throw ArgumentError(
        '${Flags.experimentNullSafetyChecks} is incompatible '
        'with sound null safety.',
      );
    }
  }

  void deriveOptions() {
    if (benchmarkingProduction) {
      trustPrimitives = true;
      omitImplicitChecks = true;
      // TODO(53993):
      //   laxRuntimeTypeToString = true;
      //   omitLateNames = true;
    }

    if (benchmarkingExperiment) {
      // Set flags implied by '--benchmarking-x'.
      // TODO(sra): Use this for some null safety variant.
      features.forceCanary();
    }

    if (_soundNullSafety) nullSafetyMode = NullSafetyMode.sound;
    if (_noSoundNullSafety) nullSafetyMode = NullSafetyMode.unsound;

    if (optimizationLevel != null) {
      if (optimizationLevel == 0) {
        disableInlining = true;
        disableTypeInference = true;
        disableRtiOptimization = true;
      }
      if (optimizationLevel! >= 2) {
        enableMinification = true;
        laxRuntimeTypeToString = true;
        omitLateNames = true;
      }
      if (optimizationLevel! >= 3) {
        omitImplicitChecks = true;
      }
      if (optimizationLevel == 4) {
        trustPrimitives = true;
      }
    }

    // Strong mode always trusts type annotations (inferred or explicit), so
    // assignments checks should be trusted.
    if (omitImplicitChecks) {
      defaultParameterCheckPolicy = CheckPolicy.trusted;
      defaultImplicitDowncastCheckPolicy = CheckPolicy.trusted;
      defaultConditionCheckPolicy = CheckPolicy.trusted;
    } else {
      defaultParameterCheckPolicy = CheckPolicy.checked;
      defaultImplicitDowncastCheckPolicy = CheckPolicy.checked;
      defaultConditionCheckPolicy = CheckPolicy.checked;
    }
    if (omitAsCasts) {
      defaultExplicitCastCheckPolicy = CheckPolicy.trusted;
    } else {
      defaultExplicitCastCheckPolicy = CheckPolicy.checked;
    }
    if (trustPrimitives) {
      defaultIndexBoundsCheckPolicy = CheckPolicy.trusted;
    } else {
      defaultIndexBoundsCheckPolicy = CheckPolicy.checked;
    }

    if (_disableMinification) {
      enableMinification = false;
    }

    if (_noOmitLateNames) {
      omitLateNames = false;
    }

    if (nullSafetyMode != NullSafetyMode.sound) {
      // Technically, we should still assert if the user passed in a flag to
      // assert, but this was not the behavior before, so to avoid a breaking
      // change, we don't assert in unsound mode.
      nativeNullAssertions = false;
    } else if (_noNativeNullAssertions) {
      // Never assert if the user tells us not to.
      nativeNullAssertions = false;
    } else if (!nativeNullAssertions &&
        (optimizationLevel != null && optimizationLevel! >= 3)) {
      // If the user didn't tell us to assert and we're in >= -O3, optimize away
      // the check. This should reduce issues in production.
      nativeNullAssertions = false;
    } else {
      nativeNullAssertions = true;
    }

    if (_noInteropNullAssertions) {
      interopNullAssertions = false;
    }

    if (_mergeFragmentsThreshold != null) {
      mergeFragmentsThreshold = _mergeFragmentsThreshold;
    }

    environment['dart.web.assertions_enabled'] = '$enableUserAssertions';
    environment['dart.tool.dart2js'] = '${true}';
    environment['dart.tool.dart2js.minify'] = '$enableMinification';
    // Eventually pragmas and commandline flags should be aligned so that users
    // setting these flag is equivalent to setting the relevant pragmas
    // globally.
    // See: https://github.com/dart-lang/sdk/issues/49475
    // https://github.com/dart-lang/sdk/blob/main/pkg/compiler/doc/pragmas.md
    environment['dart.tool.dart2js.primitives:trust'] = '$trustPrimitives';
    environment['dart.tool.dart2js.types:trust'] = '$omitImplicitChecks';
  }

  /// Returns `true` if warnings and hints are shown for all packages.
  @override
  bool get showAllPackageWarnings {
    return shownPackageWarnings != null && shownPackageWarnings!.isEmpty;
  }

  /// Returns `true` if warnings and hints are hidden for all packages.
  @override
  bool get hidePackageWarnings => shownPackageWarnings == null;

  /// Returns `true` if warnings should be should for [uri].
  @override
  bool showPackageWarningsFor(Uri uri) {
    if (showAllPackageWarnings) {
      return true;
    }
    if (shownPackageWarnings != null) {
      return uri.isScheme('package') &&
          shownPackageWarnings!.contains(uri.pathSegments.first);
    }
    return false;
  }
}

/// Policy for what to do with a type assertion check.
///
/// This enum is used to configure how the compiler treats type assertions
/// during global type inference and codegen.
enum CheckPolicy {
  trusted(isTrusted: true),
  checked(isEmitted: true);

  /// Whether the type assertion should be trusted.
  final bool isTrusted;

  /// Whether the type assertion should be emitted and checked.
  final bool isEmitted;

  const CheckPolicy({this.isTrusted = false, this.isEmitted = false});

  @override
  String toString() =>
      'CheckPolicy(isTrusted=$isTrusted,'
      'isEmitted=$isEmitted)';
}

String? _extractStringOption(
  List<String> options,
  String prefix,
  String? defaultValue,
) {
  for (String option in options) {
    if (option.startsWith(prefix)) {
      return option.substring(prefix.length);
    }
  }
  return defaultValue;
}

Uri? _extractUriOption(List<String> options, String prefix) {
  String? option = _extractStringOption(options, prefix, null);
  return (option == null) ? null : Uri.parse(option);
}

int? _extractIntOption(List<String> options, String prefix) {
  String? option = _extractStringOption(options, prefix, null);
  return (option == null) ? null : int.parse(option);
}

bool _hasOption(List<String> options, String option) {
  return options.contains(option);
}

/// Extract list of comma separated values provided for [flag]. Returns an
/// empty list if [option] contain [flag] without arguments. Returns `null` if
/// [option] doesn't contain [flag] with or without arguments.
List<String>? _extractOptionalCsvOption(List<String> options, String flag) {
  String prefix = '$flag=';
  for (String option in options) {
    if (option == flag) {
      return const <String>[];
    }
    if (option.startsWith(flag)) {
      return option.substring(prefix.length).split(',');
    }
  }
  return null;
}

/// Extract list of comma separated Uris provided for [flag]. Returns an
/// empty list if [option] contain [flag] without arguments. Returns `null` if
/// [option] doesn't contain [flag] with or without arguments.
List<Uri>? _extractUriListOption(List<String> options, String flag) {
  List<String>? stringUris = _extractOptionalCsvOption(options, flag);
  if (stringUris == null) return null;
  return stringUris.map(Uri.parse).toList();
}

Map<fe.ExperimentalFlag, bool> _extractExperiments(
  List<String> options, {
  void Function(String)? onError,
  void Function(String)? onWarning,
}) {
  List<String>? experiments = _extractOptionalCsvOption(
    options,
    Flags.enableLanguageExperiments,
  );
  onError ??= (String error) => throw ArgumentError(error);
  onWarning ??= (String warning) => print(warning);
  return fe.parseExperimentalFlags(
    fe.parseExperimentalArguments(experiments),
    onError: onError,
    onWarning: onWarning,
  );
}

void _extractFeatures(
  List<String> options,
  List<FeatureOption> features,
  FeatureStatus status,
) {
  bool hasCanaryFlag = _hasOption(options, Flags.canary);
  bool hasNoShippingFlag = _hasOption(options, Flags.noShipping);
  for (var feature in features) {
    String featureFlag = feature.flag;
    String enableFeatureFlag = '--$featureFlag';
    String disableFeatureFlag = '--no-$featureFlag';
    bool enableFeature = _hasOption(options, enableFeatureFlag);
    bool disableFeature = _hasOption(options, disableFeatureFlag);
    if (enableFeature && disableFeature) {
      throw ArgumentError(
        "'$enableFeatureFlag' incompatible with "
        "'$disableFeatureFlag'",
      );
    }
    bool globalEnable =
        hasCanaryFlag ||
        (status == FeatureStatus.shipping && !hasNoShippingFlag);
    globalEnable = feature.isNegativeFlag ? !globalEnable : globalEnable;
    feature.state = (enableFeature || globalEnable) && !disableFeature;
  }
}

void _verifyShippedFeatures(
  List<String> options,
  List<FeatureOption> features,
) {
  for (var feature in features) {
    String featureFlag = feature.flag;
    String enableFeatureFlag = '--$featureFlag';
    String disableFeatureFlag = '--no-$featureFlag';
    bool enableFeature = _hasOption(options, enableFeatureFlag);
    bool disableFeature = _hasOption(options, disableFeatureFlag);
    if (enableFeature && disableFeature) {
      throw ArgumentError(
        "'$enableFeatureFlag' incompatible with "
        "'$disableFeatureFlag'",
      );
    }
    if (enableFeature && feature.isNegativeFlag) {
      throw ArgumentError(
        "$enableFeatureFlag has been removed and cannot be enabled.",
      );
    }
    if (disableFeature && !feature.isNegativeFlag) {
      throw ArgumentError(
        "$enableFeatureFlag has already shipped and cannot be disabled.",
      );
    }
    feature.state = !feature.isNegativeFlag;
  }
}

const String _undeterminedBuildID = "build number could not be determined";
