// Copyright (c) 2013, 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;

import 'dart:async' show Future, StreamSubscription;
import 'dart:convert' show utf8, LineSplitter;
import 'dart:io' show exit, File, FileMode, Platform, stdin, stderr;
import 'dart:isolate' show Isolate;

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

import '../compiler_api.dart' as api;
import 'commandline_options.dart';
import 'common/ram_usage.dart';
import 'compiler.dart' as default_compiler show Compiler;
import 'io/mapped_file.dart';
import 'options.dart'
    show CompilerOptions, CompilerStage, DumpInfoFormat, FeatureOptions;
import 'source_file_provider.dart';
import 'util/util.dart' show stackTraceFilePrefix;

const String _defaultSpecificationUri = '../../../../sdk/lib/libraries.json';
const String outputLanguageDart = 'Dart';

/// A string to identify the revision or build.
///
/// This ID is displayed if the compiler crashes and in verbose mode, and is
/// an aid in reproducing bug reports.
///
/// The actual string is rewritten by a wrapper script when included in the sdk.
String? buildID;

/// The data passed to the [HandleOption] callback is either a single
/// string argument, or the arguments iterator for multiple arguments
/// handlers.
typedef HandleOption = void Function(String data);
typedef HandleMultiOption = void Function(Iterator<String> data);

abstract class OptionHandler<T extends Object> {
  String get pattern;
  void handle(T argument);
}

class _OneOption implements OptionHandler<String> {
  @override
  final String pattern;
  final HandleOption _handle;

  @override
  void handle(String argument) {
    _handle(argument);
  }

  _OneOption(this.pattern, this._handle);
}

class _ManyOptions implements OptionHandler<Iterator<String>> {
  @override
  final String pattern;
  final HandleMultiOption _handle;

  @override
  void handle(Iterator<String> argument) {
    _handle(argument);
  }

  _ManyOptions(this.pattern, this._handle);
}

/// Extract the parameter of an option.
///
/// For example, in ['--out=fisk.js'] and ['-ohest.js'], the parameters
/// are ['fisk.js'] and ['hest.js'], respectively.
String? extractOptionalParameter(String argument) {
  // m[0] is the entire match (which will be equal to argument). m[1]
  // is something like "-o" or "--out=", and m[2] is the parameter.
  final m = RegExp('^(-[a-zA-Z]|--.+=)(.*)').firstMatch(argument);
  return m?[2];
}

/// Extract the parameter of an option.
///
/// For example, in ['--out=fisk.js'] and ['-ohest.js'], the parameters
/// are ['fisk.js'] and ['hest.js'], respectively.
String extractParameter(String argument) {
  // m[0] is the entire match (which will be equal to argument). m[1]
  // is something like "-o" or "--out=", and m[2] is the parameter.
  final m = RegExp('^(-[a-zA-Z]|--.+=)(.*)').firstMatch(argument);
  if (m == null) {
    _helpAndFail('Unknown option "$argument".');
  }
  return m[2]!;
}

String extractPath(String argument, {bool isDirectory = true}) {
  String path = fe.nativeToUriPath(extractParameter(argument));
  return !path.endsWith("/") && isDirectory ? "$path/" : path;
}

void parseCommandLine(List<OptionHandler> handlers, List<String> argv) {
  // TODO(ahe): Use ../../args/args.dart for parsing options instead.
  var patterns = <String>[];
  for (OptionHandler handler in handlers) {
    patterns.add(handler.pattern);
  }
  var pattern = RegExp('^(${patterns.join(")\$|^(")})\$');

  Iterator<String> arguments = argv.iterator;
  OUTER:
  while (arguments.moveNext()) {
    String argument = arguments.current;
    final match = pattern.firstMatch(argument)!;
    assert(match.groupCount == handlers.length);
    for (int i = 0; i < handlers.length; i++) {
      if (match[i + 1] != null) {
        OptionHandler handler = handlers[i];
        if (handler is _ManyOptions) {
          handler.handle(arguments);
        } else {
          handler.handle(argument);
        }
        continue OUTER;
      }
    }
    throw 'Internal error: "$argument" did not match';
  }
}

FormattingDiagnosticHandler? diagnosticHandler;

Future<api.CompilationResult> compile(
  List<String> argv, {
  fe.InitializedCompilerState? kernelInitializedCompilerState,
}) {
  Stopwatch wallclock = Stopwatch()..start();
  stackTraceFilePrefix = '${Uri.base}';
  Uri? entryUri;
  Uri? inputDillUri;
  Uri librariesSpecificationUri = Uri.base.resolve('lib/libraries.json');
  Uri? out;
  Uri? sourceMapOut;
  List<String>? bazelPaths;
  List<Uri>? multiRoots;
  String? multiRootScheme = 'org-dartlang-app';
  Uri? packageConfig;
  List<String> options = <String>[];
  bool wantHelp = false;
  bool wantVersion = false;
  bool trustTypeAnnotations = false;
  bool checkedMode = false;
  bool strongMode = true;
  List<String> hints = <String>[];
  bool? verbose;
  bool? throwOnError;
  int? throwOnErrorCount;
  bool? showWarnings;
  bool? showHints;
  bool? enableColors;
  int? optimizationLevel;
  Uri? platformBinaries;
  Map<String, String> environment = <String, String>{};
  FeatureOptions features = FeatureOptions();
  String? invoker;

  void passThrough(String argument) => options.add(argument);
  void ignoreOption(String argument) {}

  if (buildID != null) {
    passThrough("--build-id=$buildID");
  }

  Uri extractResolvedFileUri(String argument) {
    return Uri.base.resolve(extractPath(argument, isDirectory: false));
  }

  void setEntryUri(String argument) {
    entryUri = extractResolvedFileUri(argument);
    options.add('${Flags.entryUri}=$entryUri');
  }

  void setInputDillUri(String argument) {
    inputDillUri = extractResolvedFileUri(argument);
    options.add('${Flags.inputDill}=$inputDillUri');
  }

  void setLibrarySpecificationUri(String argument) {
    librariesSpecificationUri = extractResolvedFileUri(argument);
  }

  void setPackageConfig(String argument) {
    packageConfig = extractResolvedFileUri(argument);
  }

  void Function(String) setDataUri(String flag) {
    return (String argument) {
      final uri = fe.nativeToUri(extractPath(argument, isDirectory: false));
      options.add('$flag=$uri');
    };
  }

  void setOutput(Iterator<String> arguments) {
    String option = arguments.current;
    String path;
    if (option == '-o' || option == '--out' || option == '--output') {
      if (!arguments.moveNext()) {
        _helpAndFail("Missing file after '$option' option.");
      }
      path = arguments.current;
    } else {
      path = extractParameter(option);
    }
    out = Uri.base.resolve(fe.nativeToUriPath(path));
    options.add('--out=$out');
  }

  void setOptimizationLevel(String argument) {
    final value = int.tryParse(extractParameter(argument));
    if (value == null || value < 0 || value > 4) {
      _helpAndFail(
        "Unsupported optimization level '$argument', "
        "supported levels are: 0, 1, 2, 3, 4",
      );
    }
    if (optimizationLevel != null) {
      print(
        "Optimization level '$argument' ignored "
        "due to preceding '-O$optimizationLevel'",
      );
      return;
    }
    optimizationLevel = value;
  }

  void setOutputType(String argument) {
    if (argument == '--output-type=dart' ||
        argument == '--output-type=dart-multi') {
      _helpAndFail(
        "--output-type=dart is no longer supported. It was deprecated "
        "since Dart 1.11 and removed in Dart 1.19.",
      );
    }
  }

  Never setStrip(String argument) {
    _helpAndFail(
      "Option '--force-strip' is not in use now that"
      "--output-type=dart is no longer supported.",
    );
  }

  void setBazelPaths(String argument) {
    String paths = extractParameter(argument);
    bazelPaths = <String>[...paths.split(',')];
  }

  void setMultiRoots(String argument) {
    String paths = extractParameter(argument);
    (multiRoots ??= <Uri>[]).addAll(paths.split(',').map(fe.nativeToUri));
  }

  void setMultiRootScheme(String argument) {
    multiRootScheme = extractParameter(argument);
  }

  String getDepsOutput(Iterable<Uri> sourceFiles) {
    var filenames = sourceFiles.map((uri) => '$uri').toList();
    filenames.sort();
    return filenames.join("\n");
  }

  void setAllowNativeExtensions(String argument) {
    _helpAndFail("Option '${Flags.allowNativeExtensions}' is not supported.");
  }

  void setVerbose(_) {
    verbose = true;
    passThrough('--verbose');
  }

  void setTrustTypeAnnotations(String argument) {
    trustTypeAnnotations = true;
  }

  void setCheckedMode(String argument) {
    checkedMode = true;
    passThrough(argument);
  }

  void addInEnvironment(Iterator<String> arguments) {
    final isDefine = arguments.current.startsWith('--define');
    String argument;
    if (arguments.current == '--define') {
      arguments.moveNext();
      argument = arguments.current;
    } else {
      argument = arguments.current.substring(isDefine ? '--define='.length : 2);
    }
    // Allow for ' ' or '=' after --define
    int eqIndex = argument.indexOf('=');
    if (eqIndex <= 0) {
      _helpAndFail('Invalid value for --define: $argument');
    }
    String name = argument.substring(0, eqIndex);
    String value = argument.substring(eqIndex + 1);
    environment[name] = value;
  }

  void setCategories(String argument) {
    List<String> categories = extractParameter(argument).split(',');
    bool isServerMode = categories.length == 1 && categories.single == "Server";
    if (isServerMode) {
      hints.add(
        "The --categories flag is deprecated and will be deleted in a "
        "future release, please use '${Flags.serverMode}' instead of "
        "'--categories=Server'.",
      );
      passThrough(Flags.serverMode);
    } else {
      hints.add(
        "The --categories flag is deprecated, see the usage for details.",
      );
    }
  }

  void setPlatformBinaries(String argument) {
    platformBinaries = Uri.base.resolve(
      extractPath(argument, isDirectory: true),
    );
  }

  List<Uri> setUriList(String flag, String argument) {
    String list = extractParameter(argument);
    List<Uri> uris = list.split(',').map(fe.nativeToUri).toList();
    String uriList = uris.map((uri) => '$uri').join(',');
    options.add('$flag=$uriList');
    return uris;
  }

  void setDillDependencies(String argument) {
    setUriList(Flags.dillDependencies, argument);
  }

  void setDumpInfo(String argument) {
    final hasEnumFormatMatch = DumpInfoFormat.values.any(
      (e) => '${Flags.dumpInfo}=${e.name}' == argument,
    );
    if (argument == Flags.dumpInfo || hasEnumFormatMatch) {
      passThrough(argument);
      return;
    }
    _helpAndFail(
      "Unsupported dump-info format '$argument', "
      "supported formats: "
      "${DumpInfoFormat.values.map((e) => e.name).join(', ')}",
    );
  }

  void setInvoker(String argument) {
    invoker = extractParameter(argument);
  }

  void handleThrowOnError(String argument) {
    throwOnError = true;
    final parameter = extractOptionalParameter(argument);
    if (parameter != null) {
      var count = int.parse(parameter);
      throwOnErrorCount = count;
    }
  }

  void handleShortOptions(String argument) {
    var shortOptions = argument.substring(1).split("");
    for (var shortOption in shortOptions) {
      switch (shortOption) {
        case 'v':
          setVerbose(null);
          break;
        case 'h':
        case '?':
          wantHelp = true;
          break;
        case 'c':
          setCheckedMode(Flags.enableCheckedMode);
          break;
        case 'm':
          passThrough(Flags.minify);
          break;
        default:
          throw 'Internal error: "$shortOption" did not match';
      }
    }
  }

  List<String> arguments = <String>[];
  List<OptionHandler> handlers = <OptionHandler>[
    _OneOption('${Flags.entryUri}=.+', setEntryUri),
    _OneOption('${Flags.inputDill}=.+', setInputDillUri),
    _OneOption('-[chvm?]+', handleShortOptions),
    _OneOption('--throw-on-error(?:=[0-9]+)?', handleThrowOnError),
    _OneOption(Flags.suppressWarnings, (String argument) {
      showWarnings = false;
      passThrough(argument);
    }),
    _OneOption(Flags.fatalWarnings, passThrough),
    _OneOption(Flags.suppressHints, (String argument) {
      showHints = false;
      passThrough(argument);
    }),
    // TODO(sigmund): remove entirely after Dart 1.20
    _OneOption(
      '--output-type=dart|--output-type=dart-multi|--output-type=js',
      setOutputType,
    ),
    _OneOption('--use-kernel', ignoreOption),
    _OneOption(Flags.platformBinaries, setPlatformBinaries),
    _OneOption(Flags.noFrequencyBasedMinification, passThrough),
    _OneOption(Flags.verbose, setVerbose),
    _OneOption(Flags.progress, passThrough),
    _OneOption(Flags.reportMetrics, passThrough),
    _OneOption(Flags.reportAllMetrics, passThrough),
    _OneOption(Flags.version, (_) => wantVersion = true),
    _OneOption('--library-root=.+', ignoreOption),
    _OneOption('--libraries-spec=.+', setLibrarySpecificationUri),
    _OneOption('${Flags.dillDependencies}=.+', setDillDependencies),
    _OneOption('${Flags.sources}=.+', ignoreOption),
    _OneOption(
      '${Flags.globalInferenceUri}=.+',
      setDataUri(Flags.globalInferenceUri),
    ),
    _OneOption('${Flags.closedWorldUri}=.+', setDataUri(Flags.closedWorldUri)),
    _OneOption('${Flags.codegenUri}=.+', setDataUri(Flags.codegenUri)),
    _OneOption('${Flags.codegenShard}=.+', passThrough),
    _OneOption('${Flags.codegenShards}=.+', passThrough),
    _OneOption(Flags.cfeOnly, passThrough),
    _OneOption(Flags.memoryMappedFiles, passThrough),
    _OneOption('${Flags.stage}=.+', passThrough),
    _OneOption(Flags.debugGlobalInference, passThrough),
    _ManyOptions('--output(?:=.+)?|--out(?:=.+)?|-o.*', setOutput),
    _OneOption('-O.*', setOptimizationLevel),
    _OneOption(Flags.allowMockCompilation, ignoreOption),
    _OneOption(Flags.fastStartup, ignoreOption),
    _OneOption(Flags.genericMethodSyntax, ignoreOption),
    _OneOption(Flags.initializingFormalAccess, ignoreOption),
    _OneOption(Flags.minify, passThrough),
    _OneOption(Flags.noMinify, passThrough),
    _OneOption(Flags.omitLateNames, passThrough),
    _OneOption(Flags.noOmitLateNames, passThrough),
    _OneOption(Flags.preserveUris, ignoreOption),
    _OneOption('--force-strip=.*', setStrip),
    _OneOption(Flags.disableDiagnosticColors, (_) {
      enableColors = false;
    }),
    _OneOption(Flags.enableDiagnosticColors, (_) {
      enableColors = true;
    }),
    _OneOption(
      '--enable[_-]checked[_-]mode|--checked',
      (_) => setCheckedMode(Flags.enableCheckedMode),
    ),
    _OneOption(Flags.enableAsserts, passThrough),
    _OneOption(Flags.enableNullAssertions, passThrough),
    _OneOption(Flags.nativeNullAssertions, passThrough),
    _OneOption(Flags.noNativeNullAssertions, passThrough),
    _OneOption(Flags.interopNullAssertions, passThrough),
    _OneOption(Flags.noInteropNullAssertions, passThrough),
    _OneOption(Flags.trustTypeAnnotations, setTrustTypeAnnotations),
    _OneOption(Flags.trustPrimitives, passThrough),
    _OneOption(Flags.trustJSInteropTypeAnnotations, ignoreOption),
    _OneOption(r'--help|/\?|/h', (_) => wantHelp = true),
    _OneOption('--packages=.+', setPackageConfig),
    _OneOption(Flags.noSourceMaps, passThrough),
    _OneOption(Option.resolutionInput, ignoreOption),
    _OneOption(Option.bazelPaths, setBazelPaths),
    _OneOption(Option.multiRoots, setMultiRoots),
    _OneOption(Option.multiRootScheme, setMultiRootScheme),
    _OneOption(Flags.resolveOnly, ignoreOption),
    _OneOption(Flags.disableNativeLiveTypeAnalysis, passThrough),
    _OneOption('--categories=.*', setCategories),
    _OneOption(Flags.serverMode, passThrough),
    _OneOption(Flags.disableInlining, passThrough),
    _OneOption(Flags.disableProgramSplit, passThrough),
    _OneOption(Flags.stopAfterProgramSplit, passThrough),
    _OneOption(Flags.disableTypeInference, passThrough),
    _OneOption(Flags.useTrivialAbstractValueDomain, passThrough),
    _OneOption(Flags.disableRtiOptimization, passThrough),
    _OneOption(Flags.terse, passThrough),
    _OneOption('--deferred-map=.+', passThrough),
    _OneOption(
      '${Flags.deferredLoadIdMapUri}=.+',
      setDataUri(Flags.deferredLoadIdMapUri),
    ),
    _OneOption('${Flags.writeProgramSplit}=.+', passThrough),
    _OneOption('${Flags.readProgramSplit}=.+', passThrough),
    _OneOption('${Flags.dumpInfo}|${Flags.dumpInfo}=.+', setDumpInfo),
    _OneOption(
      '${Flags.dumpInfoDataUri}=.+',
      setDataUri(Flags.dumpInfoDataUri),
    ),
    _OneOption('--disallow-unsafe-eval', ignoreOption),
    _OneOption(Option.showPackageWarnings, passThrough),
    _OneOption(Option.enableLanguageExperiments, passThrough),
    _OneOption('--enable-experimental-mirrors', ignoreOption),
    _OneOption(Flags.enableAssertMessage, passThrough),
    _OneOption('--strong', ignoreOption),
    _OneOption(Flags.previewDart2, ignoreOption),
    _OneOption(Flags.omitImplicitChecks, passThrough),
    _OneOption(Flags.omitAsCasts, passThrough),
    _OneOption(Flags.laxRuntimeTypeToString, passThrough),
    _OneOption(Flags.enableProtoShaking, passThrough),
    _OneOption(Flags.enableProtoMixinShaking, passThrough),
    _OneOption(Flags.benchmarkingProduction, passThrough),
    _OneOption(Flags.benchmarkingExperiment, passThrough),
    _OneOption(Flags.soundNullSafety, passThrough),
    _OneOption(Flags.dumpUnusedLibraries, passThrough),
    _OneOption(Flags.writeResources, passThrough),

    // TODO(floitsch): remove conditional directives flag.
    // We don't provide the info-message yet, since we haven't publicly
    // launched the feature yet.
    _OneOption(Flags.conditionalDirectives, ignoreOption),
    _OneOption('--enable-async', ignoreOption),
    _OneOption('--enable-null-aware-operators', ignoreOption),
    _OneOption('--enable-enum', ignoreOption),
    _OneOption(Flags.allowNativeExtensions, setAllowNativeExtensions),
    _OneOption(Flags.generateCodeWithCompileTimeErrors, ignoreOption),
    _OneOption(Flags.useMultiSourceInfo, passThrough),
    _OneOption(Flags.useNewSourceInfo, passThrough),
    _OneOption(Flags.useSimpleLoadIds, passThrough),
    _OneOption(Flags.testMode, passThrough),
    _OneOption('${Flags.dumpSsa}=.+', passThrough),
    _OneOption('${Flags.cfeInvocationModes}=.+', passThrough),
    _OneOption('${Flags.invoker}=.+', setInvoker),
    _OneOption('${Flags.verbosity}=.+', passThrough),
    _OneOption(Flags.disableDiagnosticByteCache, passThrough),
    _OneOption(Flags.enableDeferredLoadingEventLog, passThrough),
    _OneOption(Flags.omitMemorySummary, passThrough),

    // Experimental features.
    // We don't provide documentation for these yet.
    // TODO(29574): provide documentation when this feature is supported.
    // TODO(29574): provide a warning/hint/error, when profile-based data is
    // used without `--fast-startup`.
    _OneOption(Flags.experimentalTrackAllocations, passThrough),

    _OneOption(Flags.experimentLocalNames, ignoreOption),
    _OneOption(Flags.experimentStartupFunctions, passThrough),
    _OneOption(Flags.experimentToBoolean, passThrough),
    _OneOption(Flags.experimentUnreachableMethodsThrow, passThrough),
    _OneOption(Flags.experimentCallInstrumentation, passThrough),
    _OneOption('${Flags.mergeFragmentsThreshold}=.+', passThrough),

    // Wire up feature flags.
    _OneOption(Flags.canary, passThrough),
    _OneOption(Flags.noShipping, passThrough),
    // Shipped features.
    for (var feature in features.shipped)
      _OneOption('--${feature.flag}', passThrough),
    for (var feature in features.shipped)
      _OneOption('--no-${feature.flag}', passThrough),
    // Shipping features.
    for (var feature in features.shipping)
      _OneOption('--${feature.flag}', passThrough),
    for (var feature in features.shipping)
      _OneOption('--no-${feature.flag}', passThrough),
    // Canary features.
    for (var feature in features.canary)
      _OneOption('--${feature.flag}', passThrough),
    for (var feature in features.canary)
      _OneOption('--no-${feature.flag}', passThrough),

    // The following three options must come last.
    _ManyOptions('-D.+=.*|--define=.+=.*|--define', addInEnvironment),
    _OneOption('-.*', (String argument) {
      _helpAndFail("Unknown option '$argument'.");
    }),
    _OneOption('.*', (String argument) {
      arguments.add(fe.nativeToUriPath(argument));
    }),
  ];

  parseCommandLine(handlers, argv);

  final diagnostic = diagnosticHandler = FormattingDiagnosticHandler();
  if (verbose != null) {
    diagnostic.verbose = verbose!;
  }
  if (throwOnError != null) {
    diagnostic.throwOnError = throwOnError!;
  }
  if (throwOnErrorCount != null) {
    diagnostic.throwOnErrorCount = throwOnErrorCount!;
  }
  if (showWarnings != null) {
    diagnostic.showWarnings = showWarnings!;
  }
  if (showHints != null) {
    diagnostic.showHints = showHints!;
  }
  if (enableColors != null) {
    diagnostic.enableColors = enableColors!;
  }

  if (checkedMode && strongMode) {
    checkedMode = false;
    hints.add(
      "Option '${Flags.enableCheckedMode}' is not needed in Dart 2.0. "
      "To enable assertions use '${Flags.enableAsserts}' instead.",
    );
  }

  if (trustTypeAnnotations && strongMode) {
    hints.add(
      "Option '${Flags.trustTypeAnnotations}' is not available "
      "in Dart 2.0. Try using '${Flags.omitImplicitChecks}' instead.",
    );
  }

  if (options.contains(Flags.soundNullSafety)) {
    warning(
      "Option '${Flags.soundNullSafety}' is deprecated. As of Dart 3, Dart "
      "only supports sound null safety. This flag will be removed in a future "
      "version of Dart.",
    );
  }

  for (String hint in hints) {
    diagnostic.info(hint, api.Diagnostic.hint);
  }

  if (wantHelp || wantVersion) {
    helpAndExit(wantHelp, wantVersion, diagnostic.verbose);
  }

  if (invoker == null) {
    final message =
        "The 'dart2js' entrypoint script is deprecated, "
        "please use 'dart compile js' instead.";
    // Aside from asking for `-h`, dart2js fails when it is invoked from its
    // snapshot directly and not using the supported workflows.  However, we
    // allow invoking dart2js from Dart sources to support the dart2js team
    // local workflows and testing.
    if (!Platform.script.path.endsWith(".dart")) {
      _fail(message);
    } else {
      warning(message);
    }
  } else if (verbose != null) {
    print("Compiler invoked from: '$invoker'");
  }

  if (arguments.isEmpty && entryUri == null && inputDillUri == null) {
    _helpAndFail('No Dart file specified.');
  }

  if (arguments.length > 1) {
    var extra = arguments.sublist(1);
    _helpAndFail('Extra arguments: ${extra.join(" ")}');
  }

  if (trustTypeAnnotations && checkedMode) {
    _helpAndFail(
      "Option '${Flags.trustTypeAnnotations}' may not be used in "
      "checked mode.",
    );
  }

  if (arguments.isNotEmpty) {
    String sourceOrDill = arguments[0];
    Uri file = Uri.base.resolve(fe.nativeToUriPath(sourceOrDill));
    if (sourceOrDill.endsWith('.dart')) {
      options.add('${Flags.entryUri}=$file');
      entryUri = file;
    } else {
      assert(sourceOrDill.endsWith('.dill'));
      options.add('${Flags.inputDill}=$file');
      inputDillUri = file;
    }
  }

  // Make [scriptName] a relative path.
  String scriptName = fe.relativizeUri(
    Uri.base,
    inputDillUri ?? entryUri!,
    Platform.isWindows,
  );

  CompilerOptions compilerOptions =
      CompilerOptions.parse(
          options,
          featureOptions: features,
          librariesSpecificationUri: librariesSpecificationUri,
          platformBinaries: platformBinaries,
          useDefaultOutputUri: true,
          onError: (String message) => _fail(message),
          onWarning: (String message) => print(message),
        )
        ..packageConfig = packageConfig
        ..environment = environment
        ..kernelInitializedCompilerState = kernelInitializedCompilerState
        ..optimizationLevel = optimizationLevel;

  final errorMessage = compilerOptions.validateStage();
  if (errorMessage != null) {
    _fail(errorMessage);
  }

  out = compilerOptions.setResolvedOutputUri();

  if (compilerOptions.stage.emitsJs) {
    sourceMapOut = Uri.parse('$out.map');
    compilerOptions.sourceMapUri ??= sourceMapOut;
  }

  // TODO(johnniwinther): Measure time for reading files.
  SourceFileByteReader byteReader = compilerOptions.memoryMappedFiles
      ? const MemoryMapSourceFileByteReader()
      : const MemoryCopySourceFileByteReader();

  SourceFileProvider inputProvider;
  if (bazelPaths != null) {
    if (multiRoots != null) {
      _helpAndFail(
        'The options --bazel-root and --multi-root cannot be supplied '
        'together, please choose one or the other.',
      );
    }
    inputProvider = BazelInputProvider(
      bazelPaths!,
      byteReader,
      disableByteCache: compilerOptions.disableDiagnosticByteCache,
    );
  } else if (multiRoots != null) {
    inputProvider = MultiRootInputProvider(
      multiRootScheme!,
      multiRoots!,
      byteReader,
      disableByteCache: compilerOptions.disableDiagnosticByteCache,
    );
  } else {
    inputProvider = CompilerSourceFileProvider(
      byteReader: byteReader,
      disableByteCache: compilerOptions.disableDiagnosticByteCache,
    );
  }

  diagnostic.registerFileProvider(inputProvider);

  RandomAccessFileOutputProvider outputProvider =
      RandomAccessFileOutputProvider(
        out,
        sourceMapOut,
        onInfo: diagnostic.info,
        onFailure: _fail,
      );

  Future<api.CompilationResult> compilationDone(
    api.CompilationResult result,
  ) async {
    if (!result.isSuccess) {
      _fail('Compilation failed.');
    }
    if (out != null) {
      writeString(
        Uri.parse('$out.deps'),
        getDepsOutput(inputProvider.getSourceUris()),
      );
    }

    String input = scriptName;
    int inputSize;
    String processName;
    String inputName;

    int outputSize;
    int? primaryOutputSize;
    String outputName;

    String? summary;
    switch (compilerOptions.stage) {
      case CompilerStage.all:
      case CompilerStage.cfe:
      case CompilerStage.dumpInfoAll:
        final sourceCharCount = _formatCharacterCount(
          inputProvider.sourceBytesFromDill,
        );
        inputName = 'input bytes ($sourceCharCount characters source)';
        inputSize = inputProvider.bytesRead;
        summary = 'Dart file $input ';
        break;
      case CompilerStage.closedWorld:
      case CompilerStage.deferredLoadIds:
        inputName = 'input bytes';
        inputSize = inputProvider.bytesRead;
        summary = 'Dart file $input ';
        break;
      case CompilerStage.globalInference:
        inputName = 'bytes data';
        inputSize = inputProvider.bytesRead;
        String dataInput = fe.relativizeUri(
          Uri.base,
          compilerOptions.dataUriForStage(CompilerStage.closedWorld),
          Platform.isWindows,
        );
        summary = 'Data files $input and $dataInput ';
        break;
      case CompilerStage.codegenSharded:
      case CompilerStage.codegenAndJsEmitter:
      case CompilerStage.dumpInfo:
        inputName = 'bytes data';
        inputSize = inputProvider.bytesRead;
        String worldInput = fe.relativizeUri(
          Uri.base,
          compilerOptions.dataUriForStage(CompilerStage.closedWorld),
          Platform.isWindows,
        );
        String dataInput = fe.relativizeUri(
          Uri.base,
          compilerOptions.dataUriForStage(CompilerStage.globalInference),
          Platform.isWindows,
        );
        summary = 'Data files $input, $worldInput, and $dataInput ';
        break;
      case CompilerStage.jsEmitter:
        inputName = 'bytes data';
        inputSize = inputProvider.bytesRead;
        String worldInput = fe.relativizeUri(
          Uri.base,
          compilerOptions.dataUriForStage(CompilerStage.closedWorld),
          Platform.isWindows,
        );
        String dataInput = fe.relativizeUri(
          Uri.base,
          compilerOptions.dataUriForStage(CompilerStage.globalInference),
          Platform.isWindows,
        );
        String codeInput = fe.relativizeUri(
          Uri.base,
          compilerOptions.dataUriForStage(CompilerStage.codegenSharded),
          Platform.isWindows,
        );
        summary =
            'Data files $input, $worldInput, $dataInput and '
            '$codeInput[0-${compilerOptions.codegenShards! - 1}] ';
        break;
    }

    switch (compilerOptions.stage) {
      case CompilerStage.all:
      case CompilerStage.dumpInfoAll:
      case CompilerStage.jsEmitter:
      case CompilerStage.codegenAndJsEmitter:
      case CompilerStage.dumpInfo:
        processName = 'Compiled';
        outputName = 'characters JavaScript';
        outputSize = outputProvider.totalCharactersWrittenJavaScript;
        primaryOutputSize = outputProvider.totalCharactersWrittenPrimary;
        String output = fe.relativizeUri(
          Uri.base,
          out ?? Uri.parse('out.js'),
          Platform.isWindows,
        );
        summary += 'compiled to JavaScript: $output';
        break;
      case CompilerStage.cfe:
        processName = 'Compiled';
        outputName = 'kernel bytes';
        outputSize = outputProvider.totalDataWritten;
        String output = fe.relativizeUri(Uri.base, out!, Platform.isWindows);
        summary += 'compiled to dill: $output.';
        break;
      case CompilerStage.closedWorld:
        processName = 'Serialized';
        outputName = 'bytes data';
        outputSize = outputProvider.totalDataWritten;
        final producesDill = compilerOptions.producesModifiedDill;
        String dataOutput = fe.relativizeUri(
          Uri.base,
          compilerOptions.dataUriForStage(compilerOptions.stage),
          Platform.isWindows,
        );
        String summaryLine = dataOutput;
        if (producesDill) {
          summaryLine += ' and ';
          summaryLine += fe.relativizeUri(Uri.base, out!, Platform.isWindows);
        }
        summary += 'serialized to data: $summaryLine.';
        break;
      case CompilerStage.deferredLoadIds:
        processName = 'Serialized';
        outputName = 'character map';
        outputSize = outputProvider.totalCharactersWritten;
        String dataOutput = fe.relativizeUri(
          Uri.base,
          compilerOptions.dataUriForStage(compilerOptions.stage),
          Platform.isWindows,
        );
        summary += 'mapped to: $dataOutput.';
        break;
      case CompilerStage.globalInference:
        processName = 'Serialized';
        outputName = 'bytes data';
        outputSize = outputProvider.totalDataWritten;
        String dataOutput = fe.relativizeUri(
          Uri.base,
          compilerOptions.dataUriForStage(compilerOptions.stage),
          Platform.isWindows,
        );
        summary += 'serialized to data: $dataOutput.';
        break;
      case CompilerStage.codegenSharded:
        processName = 'Serialized';
        outputName = 'bytes data';
        outputSize = outputProvider.totalDataWritten;
        String codeOutput = fe.relativizeUri(
          Uri.base,
          compilerOptions.dataUriForStage(compilerOptions.stage),
          Platform.isWindows,
        );
        summary +=
            'serialized to codegen data: '
            '$codeOutput${compilerOptions.codegenShard}.';
        break;
    }

    final memoryUsed = compilerOptions.omitMemorySummary
        ? null
        : await currentHeapCapacityInMb();
    final memoryUsedString = memoryUsed != null
        ? ' using $memoryUsed of memory'
        : '';

    print(
      '$processName '
      '${_formatCharacterCount(inputSize)} $inputName to '
      '${_formatCharacterCount(outputSize)} $outputName in '
      '${_formatDurationAsSeconds(wallclock.elapsed)} seconds$memoryUsedString',
    );
    if (primaryOutputSize != null && out != null) {
      diagnostic.info(
        '${_formatCharacterCount(primaryOutputSize)} $outputName '
        'in ${fe.relativizeUri(Uri.base, out!, Platform.isWindows)}',
      );
    }
    if (compilerOptions.stage.emitsJs) {
      if (diagnostic.verbose) {
        print(summary);
        if (diagnostic.verbose) {
          var files = outputProvider.allOutputFiles;
          int jsCount = files.where((f) => f.endsWith('.js')).length;
          print('Emitted file $jsCount JavaScript files.');
        }
      }
    } else {
      print(summary);
    }

    return result;
  }

  return compileFunc(
    compilerOptions,
    inputProvider,
    diagnostic,
    outputProvider,
  ).then(compilationDone);
}

/// Returns the non-negative integer formatted with a thousands separator.
String _formatCharacterCount(int value, [String separator = ',']) {
  String text = '$value';
  // 'Insert' separators right-to-left. Inefficient, but used just a few times.
  for (int position = text.length - 3; position > 0; position -= 3) {
    text = text.substring(0, position) + separator + text.substring(position);
  }
  return text;
}

/// Formats [duration] in seconds in fixed-point format, preferring to keep the
/// result at to below [width] characters.
String _formatDurationAsSeconds(Duration duration, [int width = 4]) {
  num seconds = duration.inMilliseconds / 1000.0;
  late String text;
  for (int digits = 3; digits >= 0; digits--) {
    text = seconds.toStringAsFixed(digits);
    if (text.length <= width) return text;
  }
  return text;
}

void writeString(Uri uri, String text) {
  if (!enableWriteString) return;
  if (!uri.isScheme('file')) {
    _fail('Unhandled scheme ${uri.scheme}.');
  }
  var file = (File(
    uri.toFilePath(),
  )..createSync(recursive: true)).openSync(mode: FileMode.write);
  file.writeStringSync(text);
  file.closeSync();
}

Never _fail(String message) {
  if (diagnosticHandler != null) {
    diagnosticHandler!.report(
      null,
      null,
      -1,
      -1,
      message,
      api.Diagnostic.error,
    );
  } else {
    print('Error: $message');
  }
  exitFunc(1);
}

Future<api.CompilationResult> compilerMain(
  List<String> arguments, {
  fe.InitializedCompilerState? kernelInitializedCompilerState,
}) async {
  if (!arguments.any((a) => a.startsWith('--libraries-spec='))) {
    Uri script = Platform.script;
    if (script.isScheme("package")) {
      script = (await Isolate.resolvePackageUri(script))!;
    }
    Uri librariesJson = script.resolve(_defaultSpecificationUri);
    arguments = <String>[
      '--libraries-spec=${librariesJson.toFilePath()}',
      ...arguments,
    ];
  }
  return compile(
    arguments,
    kernelInitializedCompilerState: kernelInitializedCompilerState,
  );
}

void help() {
  // This message should be no longer than 20 lines. The default
  // terminal size normally 80x24. Two lines are used for the prompts
  // before and after running the compiler. Another two lines may be
  // used to print an error message.
  print(
    '''
Compile Dart to JavaScript.

Usage: dart compile js [arguments] <dart entry point>
  -h, --help      Print this usage information.
  -h -v           Show detailed information about all options.
  -o, --output    Write the output to <file name>.
  -O<0,1,2,3,4>   Set the compiler optimization level (defaults to -O1).
     -O0          No optimizations (only meant for debugging the compiler).
     -O1          Default (includes whole program analyses and inlining).
     -O2          Safe production-oriented optimizations (like minification).
     -O3          Potentially unsafe optimizations (see -h -v for details).
     -O4          More aggressive unsafe optimizations (see -h -v for details).
'''
        .trim(),
  );
}

void verboseHelp() {
  print(
    r'''
Compile Dart to JavaScript.

Usage: dart compile js [arguments] <dart entry point>
  -h, /h, /?, --help
    Print this usage information (add -v for information about all options).

  -o <file name>, --output=<file name>
    Write the output to <file name>.

  -m, --minify
    Generate minified output.

  --enable-asserts
    Enable assertions.

  -v, --verbose
    Display verbose information.

  -D<name>=<value>, --define=<name>=<value>
    Define an environment declaration.

  --version
    Display version information.

  --packages=<path>
    Path to the package resolution configuration file, which supplies a mapping
    of package names to paths.

  --suppress-warnings
    Do not display any warnings.

  --fatal-warnings
    Treat warnings as compilation errors.

  --suppress-hints
    Do not display any hints.

  --enable-diagnostic-colors
    Add colors to diagnostic messages.

  --terse
    Emit diagnostics without suggestions for how to get rid of the diagnosed
    problems.

  --show-package-warnings
    Show warnings and hints generated from packages.

  --csp
    Disable dynamic generation of code in the generated output. This is
    necessary to satisfy CSP restrictions (see https://www.w3.org/TR/CSP/).

  --no-source-maps
    Do not generate a source map file.

  --omit-late-names
    Do not include names of late variables in error messages. This allows
    the compiler to generate smaller code by removing late variable names from
    the generated JavaScript.

  --native-null-assertions
    Add assertions to web library APIs to ensure that non-nullable APIs do not
    return null. This is set to true by default unless -O3 or higher is passed.

  -O<0,1,2,3,4>
    Controls optimizations that can help reduce code-size and improve
    performance of the generated code for deployment.

    -O0
       Disables all optimizations. Equivalent to calling the compiler with these
       extra flags:
        --disable-inlining
        --disable-type-inference
        --disable-rti-optimizations


       Some optimizations cannot be disabled at this time, as we add the option
       to disable them, they will be added here as well.

    -O1
       Enables default optimizations. Equivalent to calling the compiler with no
       extra flags.

    -O2
       Enables optimizations that respect the language semantics and are safe
       for all programs. It however changes the string representation of types,
       which will no longer be consistent with the Dart VM or DDC.

       Equivalent to calling the compiler with these extra flags:
        --minify
        --lax-runtime-type-to-string
        --omit-late-names

    -O3
       Enables optimizations that respect the language semantics only on
       programs that do not ever throw any subtype of `Error`.  These
       optimizations improve the generated code, but they may cause programs to
       behave unexpectedly if this assumption is not met.  To use this
       option, we recommend that you properly test your application first
       without it, and ensure that no subtype of `Error` (such as `TypeError`)
       is ever thrown.

       Equivalent to calling the compiler with these extra flags:
         -O2
         --omit-implicit-checks

    -O4
       Enables more aggressive optimizations than -O3, but with the same
       assumptions. These optimizations are on a separate group because they
       are more susceptible to variations in input data. To use this option we
       recommend to pay special attention to test edge cases in user input.

       Equivalent to calling the compiler with these extra flags:
         -O3
         --trust-primitives

    While some of the individual optimizations and flags may change with time,
    we intend to keep the -O* flags stable. New safe optimizations may be added
    on any level, and optimizations that only work on some programs may move up
    from one level to the next (for instance, once alternative safe
    optimizations are implemented, `omit-implicit-checks` may be removed or may
    move to the O4 level).

The following individual options are included in some of the -O optimization
levels above. They help reduce the size of the generated code, but they may
cause programs to behave unexpectedly if assumptions are not met. Only turn on
these flags if you have enough test coverage to ensure they are safe to use:

  --omit-implicit-checks
    Omit implicit runtime checks, such as parameter checks and implicit
    downcasts. These checks are included by default in Dart 2.0. By
    using this flag the checks are removed, however the compiler will assume
    that all such checks were valid and may use this information for
    optimizations. Use this option only if you have enough testing to ensure
    that your program works with the checks.

  --trust-primitives
    Assume that operations on numbers, strings, and lists have valid inputs.
    This option allows the compiler to drop runtime checks for those operations.
    Note: a well-typed program is not guaranteed to have valid inputs. For
    example, an int index argument may be null or out of range.

  --lax-runtime-type-to-string
    Omits reified class type arguments when these are only needed for `toString`
    on `runtimeType`. This is useful if `runtimeType.toString()` is only used
    for debugging. Note that semantics of other uses of `.runtimeType`, for
    instance `a.runtimeType == b.runtimeType`, is not affected by this flag.

The following options are only used for compiler development and may
be removed in a future version:

  --throw-on-error
    Throw an exception if a compile-time error is detected.

  --libraries-spec=<file>
    A .json file containing the SDK libraries specification.

  --disable-native-live-type-analysis
    Disable the optimization that removes unused native types from dart:html
    and related libraries.

  --server-mode
    Compile with server support. The compiler will use a library specification
    that disables dart:html but supports dart:js in conditional imports.

  --categories=<categories>
    (deprecated)
    Use '--server-mode' instead of '--categories=Server'. All other category
    values have no effect on the compiler behavior.

  --deferred-map=<file>
    Generates a json file with a mapping from each deferred import to a list of
    the part.js files that will be loaded.

  --dump-info[=<format>]
    Generates information about the generated code. 'format' can be either
    'json' or 'binary'.
    You can inspect the generated data using tools from 'package:dart2js_info'.

  --generate-code-with-compile-time-errors
    Generates output even if the program contains compile-time errors. Use the
    exit code to determine if compilation failed.

  --no-frequency-based-minification
    Experimental. Disable the new frequency based minifying namer and use the
    old namer instead.
'''
        .trim(),
  );
}

void helpAndExit(bool wantHelp, bool wantVersion, bool verbose) {
  if (wantVersion) {
    var version = (buildID == null) ? '<non-SDK build>' : buildID;
    print('Dart-to-JavaScript compiler (dart2js) version: $version');
  }
  if (wantHelp) {
    if (verbose) {
      verboseHelp();
    } else {
      help();
    }
  }
  exitFunc(0);
}

Never _helpAndFail(String message) {
  help();
  print('');
  _fail(message);
}

void warning(String message) {
  if (diagnosticHandler != null) {
    diagnosticHandler!.report(
      null,
      null,
      -1,
      -1,
      message,
      api.Diagnostic.warning,
    );
  } else {
    print('Warning: $message');
  }
}

Future<void> main(List<String> arguments) async {
  // Expand `@path/to/file`
  // When running from bazel, argument of the form `@path/to/file` might be
  // provided. It needs to be replaced by reading all the contents of the
  // file and expanding them into the resulting argument list.
  //
  // TODO: Remove when internal tooling targets bazelMain instead of this.
  if (arguments.isNotEmpty && arguments.last.startsWith('@')) {
    var extra = _readLines(arguments.last.substring(1));
    arguments = arguments.take(arguments.length - 1).followedBy(extra).toList();
  }

  // Since the sdk/bin/dart2js script adds its own arguments in front of
  // user-supplied arguments we search for '--batch' at the end of the list.
  if (arguments.isNotEmpty && arguments.last == "--batch") {
    batchMain(arguments.sublist(0, arguments.length - 1));
    return;
  }
  await internalMain(arguments);
}

Future<String?> bazelMain(List<String> arguments) async {
  if (arguments.isNotEmpty && arguments.last.startsWith('@')) {
    var extra = _readLines(arguments.last.substring(1));
    arguments = arguments.take(arguments.length - 1).followedBy(extra).toList();
  }
  final compiler = (await internalMain(arguments)).compiler;
  if (compiler is default_compiler.Compiler) {
    final buffer = StringBuffer();
    compiler.collectMetrics(buffer);
    return buffer.toString();
  }
  return null;
}

/// Return all non-empty lines in a file found at [path].
Iterable<String> _readLines(String path) {
  return File(path).readAsLinesSync().where((line) => line.isNotEmpty);
}

typedef ExitFunc = Never Function(int exitCode);
typedef CompileFunc =
    Future<api.CompilationResult> Function(
      CompilerOptions compilerOptions,
      api.CompilerInput compilerInput,
      api.CompilerDiagnostics compilerDiagnostics,
      api.CompilerOutput compilerOutput,
    );

ExitFunc exitFunc = exit;
CompileFunc compileFunc = api.compile;

/// If `true` a '.deps' file will be generated after compilation.
///
/// Set this to `false` in end-to-end tests to avoid generating '.deps' files.
bool enableWriteString = true;

Future<api.CompilationResult> internalMain(
  List<String> arguments, {
  fe.InitializedCompilerState? kernelInitializedCompilerState,
}) {
  Future<api.CompilationResult> onError(Object exception, StackTrace? trace) {
    // If we are already trying to exit, just continue exiting.
    if (exception == _exitSignal) throw exception;

    try {
      print('The compiler crashed: $exception');
    } catch (ignored) {
      print('The compiler crashed: error while printing exception');
    }

    try {
      if (trace != null) {
        print(trace);
      }
    } finally {
      exitFunc(253); // 253 is recognized as a crash by our test scripts.
    }
  }

  try {
    return compilerMain(
      arguments,
      kernelInitializedCompilerState: kernelInitializedCompilerState,
    ).catchError(onError);
  } catch (exception, trace) {
    return onError(exception, trace);
  }
}

class _ExitSignal {
  const _ExitSignal();
}

const _exitSignal = _ExitSignal();

void batchMain(List<String> batchArguments) {
  int? exitCode;
  exitFunc = (errorCode) {
    // Since we only throw another part of the compiler might intercept our
    // exception and try to exit with a different code.
    if (exitCode == 0) {
      exitCode = errorCode;
    }
    throw _exitSignal;
  };

  var stream = stdin.transform(utf8.decoder).transform(LineSplitter());
  late StreamSubscription<String> subscription;
  fe.InitializedCompilerState? kernelInitializedCompilerState;
  subscription = stream.listen((String line) {
    Future.sync(() {
          subscription.pause();
          exitCode = 0;
          List<String> testArgs = splitLine(line, windows: Platform.isWindows);

          // Ignore experiment flags given to the batch runner.
          //
          // Batch arguments are provided when the batch compiler is created, and
          // contain flags that are generally enabled for all tests. Tests
          // may have more specific flags that could conflict with the batch flags.
          // For example, the batch runner might be setup to run the non-nullable
          // experiment, but the test may enable more experiments.
          //
          // At this time we are only aware of these kind of conflicts with
          // experiment flags, so we handle those directly. Currently the test
          // runner passes experiment flags on both the batch runner and the test
          // itself, so it is safe to ignore the flag that was given to the batch
          // runner.
          List<String> args = [
            for (var arg in batchArguments)
              if (!arg.startsWith('--enable-experiment')) arg,
            ...testArgs,
          ];
          return internalMain(
            args,
            kernelInitializedCompilerState: kernelInitializedCompilerState,
          );
        })
        .then((api.CompilationResult? result) {
          if (result != null) {
            kernelInitializedCompilerState =
                result.kernelInitializedCompilerState;
          }
        })
        .catchError((Object exception, StackTrace trace) {
          if (!identical(exception, _exitSignal)) {
            exitCode = 253;
          }
        })
        .whenComplete(() {
          // The testing framework waits for a status line on stdout and
          // stderr before moving to the next test.
          if (exitCode == 0) {
            print(">>> TEST OK");
          } else if (exitCode == 253) {
            print(">>> TEST CRASH");
          } else {
            print(">>> TEST FAIL");
          }
          stderr.writeln(">>> EOF STDERR");
          subscription.resume();
        });
  });
}
