// Copyright (c) 2012, 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 dart2js.compiler_base;

import 'dart:async' show Future;
import 'dart:convert' show jsonEncode;
import 'dart:typed_data';

import 'package:compiler/src/universe/use.dart' show StaticUse;
import 'package:front_end/src/api_unstable/dart2js.dart' as fe;
import 'package:kernel/ast.dart' as ir;

import '../compiler_api.dart' as api;
import 'common.dart';
import 'common/codegen.dart';
import 'common/elements.dart' show ElementEnvironment;
import 'common/metrics.dart' show Metric;
import 'common/names.dart' show Selectors;
import 'common/tasks.dart'
    show CompilerTask, GenericTask, GenericTaskWithMetrics, Measurer;
import 'common/work.dart' show WorkItem;
import 'deferred_load/deferred_load.dart' show DeferredLoadTask;
import 'deferred_load/output_unit.dart' show OutputUnitData;
import 'deferred_load/program_split_constraints/nodes.dart' as psc
    show ConstraintData;
import 'deferred_load/program_split_constraints/parser.dart' as psc show Parser;
import 'diagnostics/diagnostic_listener.dart';
import 'diagnostics/messages.dart' show Message;
import 'dump_info.dart'
    show
        DumpInfoJsAstRegistry,
        DumpInfoProgramData,
        DumpInfoStateData,
        DumpInfoTask;
import 'elements/entities.dart';
import 'enqueue.dart' show Enqueuer;
import 'environment.dart';
import 'inferrer/abstract_value_domain.dart';
import 'inferrer/abstract_value_strategy.dart';
import 'inferrer/computable.dart' show ComputableAbstractValueStrategy;
import 'inferrer/powersets/powersets.dart' show PowersetStrategy;
import 'inferrer/trivial.dart' show TrivialAbstractValueStrategy;
import 'inferrer/typemasks/masks.dart' show TypeMaskStrategy;
import 'inferrer/types.dart'
    show GlobalTypeInferenceResults, GlobalTypeInferenceTask;
import 'inferrer/wrapped.dart' show WrappedAbstractValueStrategy;
import 'io/source_information.dart';
import 'js_backend/codegen_inputs.dart' show CodegenInputs;
import 'js_backend/enqueuer.dart';
import 'js_backend/inferred_data.dart';
import 'js_model/js_strategy.dart';
import 'js_model/js_world.dart';
import 'js_model/locals.dart';
import 'kernel/front_end_adapter.dart' show CompilerFileSystem;
import 'kernel/kernel_strategy.dart';
import 'kernel/kernel_world.dart';
import 'null_compiler_output.dart' show NullCompilerOutput;
import 'options.dart' show CompilerOptions, CompilerStage;
import 'phase/load_kernel.dart' as load_kernel;
import 'resolution/enqueuer.dart';
import 'serialization/serialization.dart';
import 'serialization/task.dart';
import 'serialization/strategies.dart';
import 'source_file_provider.dart';
import 'universe/selector.dart' show Selector;
import 'universe/codegen_world_builder.dart';
import 'universe/resolution_world_builder.dart';
import 'universe/world_impact.dart' show WorldImpact, WorldImpactBuilderImpl;

enum _ResolutionStatus {
  resolving,
  doneResolving,
  compiling,
}

/// Implementation of the compiler using a [api.CompilerInput] for supplying
/// the sources.
class Compiler {
  final Measurer measurer;
  final api.CompilerInput provider;
  final api.CompilerDiagnostics handler;

  late final KernelFrontendStrategy frontendStrategy;
  late final JsBackendStrategy backendStrategy;
  late final DiagnosticReporter _reporter;
  late final Map<Entity, WorldImpact> _impactCache;
  late final GenericTask userHandlerTask;
  late final GenericTask userProviderTask;

  /// Options provided from command-line arguments.
  final CompilerOptions options;

  // These internal flags are used to stop compilation after a specific phase.
  // Used only for debugging and testing purposes only.
  bool stopAfterClosedWorldForTesting = false;
  bool stopAfterGlobalTypeInferenceForTesting = false;

  /// Output provider from user of Compiler API.
  late final api.CompilerOutput _outputProvider;

  api.CompilerOutput get outputProvider => _outputProvider;

  late ir.Component componentForTesting;
  late JClosedWorld? backendClosedWorldForTesting;
  late ResolutionEnqueuer resolutionEnqueuerForTesting;
  late CodegenEnqueuer codegenEnqueuerForTesting;
  late DumpInfoStateData dumpInfoStateForTesting;

  ir.Component? untrimmedComponentForDumpInfo;

  DiagnosticReporter get reporter => _reporter;
  Map<Entity, WorldImpact> get impactCache => _impactCache;

  late final Environment environment;
  final DataReadMetrics dataReadMetrics = DataReadMetrics();

  late final List<CompilerTask> tasks;
  late final GenericTask loadKernelTask;
  fe.InitializedCompilerState? initializedCompilerState;
  bool forceSerializationForTesting = false;
  late final GlobalTypeInferenceTask globalInference;
  late final CodegenWorldBuilder _codegenWorldBuilder;

  late AbstractValueStrategy abstractValueStrategy;

  late final GenericTask selfTask;

  late final GenericTask enqueueTask;
  late final DeferredLoadTask deferredLoadTask;
  late final DumpInfoTask dumpInfoTask;
  final DumpInfoJsAstRegistry dumpInfoRegistry;
  late final SerializationTask serializationTask;

  Progress progress = const Progress();

  _ResolutionStatus? _resolutionStatus;

  CompilerStage get stage => options.stage;

  bool compilationFailed = false;

  psc.ConstraintData? programSplitConstraintsData;

  // Callback function used for testing resolution enqueuing.
  void Function()? onResolutionQueueEmptyForTesting;

  // Callback function used for testing codegen enqueuing.
  void Function()? onCodegenQueueEmptyForTesting;

  Compiler(this.provider, api.CompilerOutput outputProvider, this.handler,
      this.options)
      // NOTE: allocating measurer is done upfront to ensure the wallclock is
      // started before other computations.
      : measurer = Measurer(enableTaskMeasurements: options.verbose),
        dumpInfoRegistry = DumpInfoJsAstRegistry(options) {
    options.deriveOptions();
    options.validate();
    environment = Environment(options.environment);

    abstractValueStrategy = options.useTrivialAbstractValueDomain
        ? const TrivialAbstractValueStrategy()
        : const TypeMaskStrategy();
    if (options.experimentalWrapped || options.testMode) {
      abstractValueStrategy =
          WrappedAbstractValueStrategy(abstractValueStrategy);
    } else if (options.experimentalPowersets) {
      abstractValueStrategy = PowersetStrategy(abstractValueStrategy);
    }
    if (options.debugGlobalInference) {
      abstractValueStrategy =
          ComputableAbstractValueStrategy(abstractValueStrategy);
    }

    CompilerTask kernelFrontEndTask;
    selfTask = GenericTaskWithMetrics('self', measurer, dataReadMetrics);
    _outputProvider = _CompilerOutput(this, outputProvider);
    _reporter = DiagnosticReporter(this);
    kernelFrontEndTask = GenericTask('Front end', measurer);
    frontendStrategy =
        KernelFrontendStrategy(kernelFrontEndTask, options, reporter);
    backendStrategy = createBackendStrategy();
    _impactCache = <Entity, WorldImpact>{};

    if (options.showInternalProgress) {
      progress = InteractiveProgress();
    }

    tasks = [
      // [enqueueTask] is created earlier because it contains the resolution
      // world objects needed by other tasks.
      enqueueTask = GenericTask('Enqueue', measurer),
      loadKernelTask = GenericTask('kernel loader', measurer),
      kernelFrontEndTask,
      globalInference = GlobalTypeInferenceTask(this),
      deferredLoadTask = frontendStrategy.createDeferredLoadTask(this),
      dumpInfoTask = DumpInfoTask(options, measurer, _outputProvider, reporter),
      selfTask,
      serializationTask = SerializationTask(
          options, reporter, provider, outputProvider, measurer),
      ...backendStrategy.tasks,
      userHandlerTask = GenericTask('Diagnostic handler', measurer),
      userProviderTask = GenericTask('Input provider', measurer)
    ];

    initializedCompilerState = options.kernelInitializedCompilerState;
  }

  /// Creates the backend strategy.
  ///
  /// Override this to mock the backend strategy for testing.
  JsBackendStrategy createBackendStrategy() {
    return JsBackendStrategy(this);
  }

  ResolutionWorldBuilder? resolutionWorldBuilderForTesting;

  KClosedWorld? get frontendClosedWorldForTesting =>
      resolutionWorldBuilderForTesting?.closedWorldForTesting;

  CodegenWorldBuilder get codegenWorldBuilder => _codegenWorldBuilder;

  CodegenWorld? codegenWorldForTesting;

  bool get disableTypeInference =>
      options.disableTypeInference || compilationFailed;

  // Compiles the dart program as specified in [options].
  //
  // The resulting future will complete with true if the compilation
  // succeeded.
  Future<bool> run() => selfTask.measureSubtask("run", () async {
        measurer.startWallClock();
        var setupDuration = measurer.elapsedWallClock;
        try {
          await runInternal();
        } catch (error, stackTrace) {
          await _reporter.onError(options.compilationTarget, error, stackTrace);
        } finally {
          measurer.stopWallClock();
        }
        dataReadMetrics.addDataRead(provider);
        if (options.verbose) {
          var timings = StringBuffer();
          computeTimings(setupDuration, timings);
          logVerbose('$timings');
        }
        if (options.reportPrimaryMetrics || options.reportSecondaryMetrics) {
          var metrics = StringBuffer();
          collectMetrics(metrics);
          logInfo('$metrics');
        }
        return !compilationFailed;
      });

  /// Dumps a list of unused [ir.Library]'s in the [KernelResult]. This *must*
  /// be called before [setMainAndTrimComponent], because that method will
  /// discard the unused [ir.Library]s.
  void dumpUnusedLibraries(ir.Component component, Set<Uri> libraries) {
    bool isUnused(ir.Library l) => !libraries.contains(l.importUri);
    String libraryString(ir.Library library) {
      return '${library.importUri}(${library.fileUri})';
    }

    var unusedLibraries =
        component.libraries.where(isUnused).map(libraryString).toList();
    unusedLibraries.sort();
    var jsonLibraries = jsonEncode(unusedLibraries);
    outputProvider.createOutputSink(options.outputUri!.pathSegments.last,
        'unused.json', api.OutputType.dumpUnusedLibraries)
      ..add(jsonLibraries)
      ..close();
    reporter.reportInfo(
        reporter.createMessage(NO_LOCATION_SPANNABLE, MessageKind.GENERIC, {
      'text': "${unusedLibraries.length} unused libraries out of "
          "${component.libraries.length}. Dumping to JSON."
    }));
  }

  /// Trims a component down to only the provided library uris.
  ir.Component trimComponent(
      ir.Component component, Set<Uri> librariesToInclude) {
    var irLibraryMap = <Uri, ir.Library>{};
    var irLibraries = <ir.Library>[];
    for (var library in component.libraries) {
      irLibraryMap[library.importUri] = library;
    }
    for (var library in librariesToInclude) {
      irLibraries.add(irLibraryMap[library]!);
    }
    var mainMethod = component.mainMethodName;
    var componentMode = component.mode;
    final trimmedComponent = ir.Component(
        libraries: irLibraries,
        uriToSource: component.uriToSource,
        nameRoot: component.root);
    trimmedComponent.setMainMethodAndMode(mainMethod, true, componentMode);
    return trimmedComponent;
  }

  Future<void> runInternal() async {
    clearState();
    var compilationTarget = options.compilationTarget;
    reporter.log('Compiling $compilationTarget (${options.buildId})');

    if (options.readProgramSplit != null) {
      var constraintUri = options.readProgramSplit;
      var constraintParser = psc.Parser();
      var programSplitJson = await CompilerFileSystem(provider)
          .entityForUri(constraintUri!)
          .readAsString();
      programSplitConstraintsData = constraintParser.read(programSplitJson);
    }

    await selfTask.measureSubtask("compileFromKernel", () async {
      await runSequentialPhases();
    });
  }

  /// Clear the internal compiler state to prevent memory leaks when invoking
  /// the compiler multiple times (e.g. in batch mode).
  // TODO(ahe): implement a better mechanism where we can store
  // such caches in the compiler and get access to them through a
  // suitably maintained static reference to the current compiler.
  void clearState() {
    Selector.canonicalizedValues.clear();
    StaticUse.clearCache();

    // The selector objects held in static fields must remain canonical.
    for (Selector selector in Selectors.ALL) {
      Selector.canonicalizedValues
          .putIfAbsent(selector.hashCode, () => <Selector>[])
          .add(selector);
    }
  }

  JClosedWorld? computeClosedWorld(
      ir.Component component, Uri rootLibraryUri, List<Uri> libraries) {
    frontendStrategy.registerLoadedLibraries(component, libraries);
    ResolutionEnqueuer resolutionEnqueuer = frontendStrategy
        .createResolutionEnqueuer(enqueueTask, this)
      ..onEmptyForTesting = onResolutionQueueEmptyForTesting;
    if (retainDataForTesting) {
      resolutionEnqueuerForTesting = resolutionEnqueuer;
      resolutionWorldBuilderForTesting = resolutionEnqueuer.worldBuilder;
    }
    frontendStrategy.onResolutionStart();
    for (LibraryEntity library
        in frontendStrategy.elementEnvironment.libraries) {
      frontendStrategy.elementEnvironment.forEachClass(library,
          (ClassEntity cls) {
        // Register all classes eagerly to optimize closed world computation in
        // `ClassWorldBuilder.isInheritedInSubtypeOf`.
        resolutionEnqueuer.worldBuilder.registerClass(cls);
      });
    }
    WorldImpactBuilderImpl mainImpact = WorldImpactBuilderImpl();
    final mainFunction = frontendStrategy.computeMain(mainImpact);

    // In order to see if a library is deferred, we must compute the
    // compile-time constants that are metadata.  This means adding
    // something to the resolution queue.  So we cannot wait with
    // this until after the resolution queue is processed.
    deferredLoadTask.beforeResolution(rootLibraryUri, libraries);

    _resolutionStatus = _ResolutionStatus.resolving;
    resolutionEnqueuer.applyImpact(mainImpact);
    if (options.showInternalProgress) reporter.log('Computing closed world');

    processQueue(
        frontendStrategy.elementEnvironment, resolutionEnqueuer, mainFunction,
        onProgress: showResolutionProgress);
    resolutionEnqueuer.logSummary(reporter.log);

    _reporter.reportSuppressedMessagesSummary();

    if (compilationFailed) {
      return null;
    }

    checkQueue(resolutionEnqueuer);

    JClosedWorld? closedWorld =
        closeResolution(mainFunction!, resolutionEnqueuer.worldBuilder);
    return closedWorld;
  }

  Future<load_kernel.Output?> loadKernel() async {
    final input = load_kernel.Input(options, provider, reporter,
        initializedCompilerState, forceSerializationForTesting);
    load_kernel.Output? output =
        await loadKernelTask.measure(() async => load_kernel.run(input));
    reporter.log("Kernel load complete");
    return output;
  }

  Future<load_kernel.Output?> produceKernel() async {
    if (!stage.shouldReadClosedWorld) {
      load_kernel.Output? output = await loadKernel();
      if (output == null) return null;
      if (compilationFailed) {
        // Some tests still use the component, even if the CFE failed.
        frontendStrategy.registerComponent(output.component);
        return null;
      }
      ir.Component component = output.component;
      if (retainDataForTesting) {
        componentForTesting = component;
      }
      if (options.features.newDumpInfo.isEnabled && stage.emitsDumpInfo) {
        untrimmedComponentForDumpInfo = component;
      }
      if (stage.shouldOnlyComputeDill) {
        Set<Uri> includedLibraries = output.libraries!.toSet();
        if (options.shouldLoadFromDill) {
          if (options.dumpUnusedLibraries) {
            dumpUnusedLibraries(component, includedLibraries);
          }
          if (options.entryUri != null) {
            component = trimComponent(component, includedLibraries);
          }
        }
        serializationTask.serializeComponent(component,
            includeSourceBytes: false);
      }
      return output.withNewComponent(component);
    } else {
      ir.Component component =
          await serializationTask.deserializeComponentAndUpdateOptions();
      if (retainDataForTesting) {
        componentForTesting = component;
      }
      return load_kernel.Output(component, null, null, null);
    }
  }

  bool shouldStopAfterLoadKernel(load_kernel.Output? output) =>
      output == null || compilationFailed || stage.shouldOnlyComputeDill;

  GlobalTypeInferenceResults performGlobalTypeInference(
      JClosedWorld closedWorld) {
    FunctionEntity mainFunction = closedWorld.elementEnvironment.mainFunction!;
    reporter.log('Performing global type inference');
    GlobalLocalsMap globalLocalsMap =
        GlobalLocalsMap(closedWorld.closureDataLookup.getEnclosingMember);
    InferredDataBuilder inferredDataBuilder =
        InferredDataBuilderImpl(closedWorld.annotationsData);
    return globalInference.runGlobalTypeInference(
        mainFunction, closedWorld, globalLocalsMap, inferredDataBuilder);
  }

  int runCodegenEnqueuer(
      CodegenResults codegenResults,
      InferredData inferredData,
      SourceLookup sourceLookup,
      JClosedWorld closedWorld) {
    CodegenInputs codegenInputs = codegenResults.codegenInputs;
    CodegenEnqueuer codegenEnqueuer = backendStrategy.createCodegenEnqueuer(
        enqueueTask,
        closedWorld,
        inferredData,
        codegenInputs,
        codegenResults,
        sourceLookup)
      ..onEmptyForTesting = onCodegenQueueEmptyForTesting;
    if (retainDataForTesting) {
      codegenEnqueuerForTesting = codegenEnqueuer;
    }
    _codegenWorldBuilder = codegenEnqueuer.worldBuilder;

    reporter.log('Compiling methods');
    FunctionEntity mainFunction = closedWorld.elementEnvironment.mainFunction!;
    processQueue(closedWorld.elementEnvironment, codegenEnqueuer, mainFunction,
        onProgress: showCodegenProgress);
    codegenEnqueuer.logSummary(reporter.log);
    CodegenWorld codegenWorld = codegenWorldBuilder.close();
    if (retainDataForTesting) {
      codegenWorldForTesting = codegenWorld;
    }
    reporter.log('Emitting JavaScript');
    int programSize = backendStrategy.assembleProgram(
        closedWorld, inferredData, codegenInputs, codegenWorld);

    backendStrategy.onCodegenEnd(codegenInputs);

    checkQueue(codegenEnqueuer);
    return programSize;
  }

  JClosedWorld closedWorldTestMode(JClosedWorld closedWorld) {
    SerializationIndices indices = SerializationIndices(testMode: true);
    final strategy =
        const BytesInMemorySerializationStrategy(useDataKinds: true);
    // TODO(natebiggs): Add when kernel offsets are consistent across
    //   serialization layer.
    // List<int> irData = strategy
    //     .serializeComponent(closedWorld.elementMap.programEnv.mainComponent);
    // final component = strategy.deserializeComponent(irData);
    List<int> closedWorldData =
        strategy.serializeClosedWorld(closedWorld, options, indices);
    final component = closedWorld.elementMap.programEnv.mainComponent;
    return strategy.deserializeClosedWorld(options, reporter,
        abstractValueStrategy, component, closedWorldData, indices);
  }

  GlobalTypeInferenceResults globalTypeInferenceResultsTestMode(
      GlobalTypeInferenceResults results) {
    SerializationIndices indices = SerializationIndices(testMode: true);
    final strategy =
        const BytesInMemorySerializationStrategy(useDataKinds: true);
    final closedWorld = results.closedWorld;
    final component = closedWorld.elementMap.programEnv.mainComponent;
    List<int> globalTypeInferenceResultsData =
        strategy.serializeGlobalTypeInferenceResults(results, options, indices);
    return strategy.deserializeGlobalTypeInferenceResults(
        options,
        reporter,
        environment,
        abstractValueStrategy,
        component,
        closedWorld,
        globalTypeInferenceResultsData,
        indices);
  }

  Future<JClosedWorld?> produceClosedWorld(
      load_kernel.Output output, SerializationIndices indices) async {
    ir.Component component = output.component;
    JClosedWorld? closedWorld;
    if (!stage.shouldReadClosedWorld) {
      Uri rootLibraryUri = output.rootLibraryUri!;
      List<Uri> libraries = output.libraries!;
      closedWorld = computeClosedWorld(component, rootLibraryUri, libraries);
      if (stage.shouldWriteClosedWorld && closedWorld != null) {
        serializationTask.serializeClosedWorld(closedWorld, indices);
        if (options.producesModifiedDill) {
          serializationTask.serializeComponent(component,
              includeSourceBytes: false);
        }
      } else if (options.testMode && closedWorld != null) {
        closedWorld = closedWorldTestMode(closedWorld);
        backendStrategy.registerJClosedWorld(closedWorld);
      }
    } else {
      closedWorld = await serializationTask.deserializeClosedWorld(
          abstractValueStrategy, component, useDeferredSourceReads, indices);
    }
    if (retainDataForTesting) {
      backendClosedWorldForTesting = closedWorld;
    }
    return closedWorld;
  }

  bool shouldStopAfterClosedWorld(JClosedWorld? closedWorld) =>
      closedWorld == null ||
      stage.shouldWriteClosedWorld ||
      stage.emitsDeferredLoadIds ||
      stopAfterClosedWorldForTesting;

  Future<GlobalTypeInferenceResults> produceGlobalTypeInferenceResults(
      JClosedWorld closedWorld,
      ir.Component component,
      SerializationIndices indices) async {
    GlobalTypeInferenceResults globalTypeInferenceResults;
    if (!stage.shouldReadGlobalInference) {
      globalTypeInferenceResults = performGlobalTypeInference(closedWorld);
      if (stage.shouldWriteGlobalInference) {
        serializationTask.serializeGlobalTypeInference(
            globalTypeInferenceResults, indices);
      } else if (options.testMode) {
        globalTypeInferenceResults =
            globalTypeInferenceResultsTestMode(globalTypeInferenceResults);
      }
    } else {
      globalTypeInferenceResults =
          await serializationTask.deserializeGlobalTypeInferenceResults(
              environment,
              abstractValueStrategy,
              closedWorld.elementMap.programEnv.mainComponent,
              closedWorld,
              useDeferredSourceReads,
              indices);
    }
    return globalTypeInferenceResults;
  }

  bool get shouldStopAfterGlobalTypeInference =>
      stage.shouldWriteGlobalInference ||
      stopAfterGlobalTypeInferenceForTesting;

  CodegenInputs initializeCodegen(
      GlobalTypeInferenceResults globalTypeInferenceResults) {
    backendStrategy
        .registerJClosedWorld(globalTypeInferenceResults.closedWorld);
    _resolutionStatus = _ResolutionStatus.compiling;
    return backendStrategy.onCodegenStart(globalTypeInferenceResults);
  }

  Future<CodegenResults> produceCodegenResults(
      GlobalTypeInferenceResults globalTypeInferenceResults,
      SourceLookup sourceLookup,
      SerializationIndices indices) async {
    CodegenInputs codegenInputs = initializeCodegen(globalTypeInferenceResults);
    CodegenResults codegenResults;
    if (stage.shouldReadCodegenShards && options.codegenShards != null) {
      codegenResults = await serializationTask.deserializeCodegen(
          backendStrategy,
          globalTypeInferenceResults.closedWorld,
          codegenInputs,
          useDeferredSourceReads,
          sourceLookup,
          indices);
    } else {
      codegenResults = OnDemandCodegenResults(
          codegenInputs, backendStrategy.functionCompiler);
      if (stage.shouldWriteCodegen) {
        serializationTask.serializeCodegen(
            backendStrategy,
            globalTypeInferenceResults.closedWorld.abstractValueDomain,
            codegenResults,
            indices);
      }
    }
    return codegenResults;
  }

  bool get shouldStopAfterCodegen => stage.shouldWriteCodegen;

  bool get useDeferredSourceReads => stage.shouldUseDeferredSourceReads;

  Future<void> runSequentialPhases() async {
    // Load kernel.
    final output = await produceKernel();
    if (shouldStopAfterLoadKernel(output)) return;

    final indices = SerializationIndices();

    // Compute closed world.
    JClosedWorld? closedWorld = await produceClosedWorld(output!, indices);
    if (shouldStopAfterClosedWorld(closedWorld)) return;

    // Run global analysis.
    GlobalTypeInferenceResults globalTypeInferenceResults =
        await produceGlobalTypeInferenceResults(
            closedWorld!, output.component, indices);
    if (shouldStopAfterGlobalTypeInference) return;
    closedWorld = globalTypeInferenceResults.closedWorld;

    // Allow the original references to these to be GCed and only hold
    // references to them if we are actually running the dump info task later.
    SerializationIndices? indicesForDumpInfo;
    GlobalTypeInferenceResults? globalTypeInferenceResultsForDumpInfo;
    AbstractValueDomain? abstractValueDomainForDumpInfo;
    OutputUnitData? outputUnitDataForDumpInfo;
    DataSinkWriter? sinkForDumpInfo;
    if (stage.emitsDumpInfo) {
      globalTypeInferenceResultsForDumpInfo = globalTypeInferenceResults;
      abstractValueDomainForDumpInfo = closedWorld.abstractValueDomain;
      outputUnitDataForDumpInfo = closedWorld.outputUnitData;
      indicesForDumpInfo = indices;
    } else if (stage.shouldWriteDumpInfoData) {
      sinkForDumpInfo = serializationTask.dataSinkWriterForDumpInfo(
          closedWorld.abstractValueDomain, indices);
      dumpInfoRegistry.registerDataSinkWriter(sinkForDumpInfo);
    }

    // Run codegen.
    final sourceLookup = SourceLookup(output.component);
    CodegenResults codegenResults = await produceCodegenResults(
        globalTypeInferenceResults, sourceLookup, indices);
    if (shouldStopAfterCodegen) return;
    final inferredData = globalTypeInferenceResults.inferredData;

    if (stage.shouldReadDumpInfoData) {
      final dumpInfoData =
          await serializationTask.deserializeDumpInfoProgramData(
              backendStrategy,
              abstractValueDomainForDumpInfo!,
              outputUnitDataForDumpInfo!,
              indicesForDumpInfo!);
      await runDumpInfo(
          codegenResults, globalTypeInferenceResultsForDumpInfo!, dumpInfoData);
    } else {
      // Link.
      final programSize = runCodegenEnqueuer(
          codegenResults, inferredData, sourceLookup, closedWorld);
      if (stage.emitsDumpInfo || stage.shouldWriteDumpInfoData) {
        final dumpInfoData = DumpInfoProgramData.fromEmitterResults(
            backendStrategy.emitterTask,
            dumpInfoRegistry,
            codegenResults,
            programSize);
        dumpInfoRegistry.close();
        if (stage.shouldWriteDumpInfoData) {
          serializationTask.serializeDumpInfoProgramData(sinkForDumpInfo!,
              backendStrategy, dumpInfoData, dumpInfoRegistry);
        } else {
          await runDumpInfo(codegenResults,
              globalTypeInferenceResultsForDumpInfo!, dumpInfoData);
        }
      }
    }
  }

  Future<void> runDumpInfo(
      CodegenResults codegenResults,
      GlobalTypeInferenceResults globalTypeInferenceResults,
      DumpInfoProgramData dumpInfoProgramData) async {
    JClosedWorld closedWorld = globalTypeInferenceResults.closedWorld;

    DumpInfoStateData dumpInfoState;
    dumpInfoTask.registerDumpInfoProgramData(dumpInfoProgramData);
    if (options.features.newDumpInfo.isEnabled) {
      untrimmedComponentForDumpInfo ??= (await produceKernel())!.component;
      dumpInfoState = await dumpInfoTask.dumpInfoNew(
          untrimmedComponentForDumpInfo!,
          closedWorld,
          globalTypeInferenceResults,
          codegenResults,
          backendStrategy);
    } else {
      dumpInfoState = await dumpInfoTask.dumpInfo(closedWorld,
          globalTypeInferenceResults, codegenResults, backendStrategy);
    }
    if (retainDataForTesting) {
      dumpInfoStateForTesting = dumpInfoState;
    }
  }

  /// Perform the steps needed to fully end the resolution phase.
  JClosedWorld? closeResolution(FunctionEntity mainFunction,
      ResolutionWorldBuilder resolutionWorldBuilder) {
    _resolutionStatus = _ResolutionStatus.doneResolving;

    KClosedWorld kClosedWorld = resolutionWorldBuilder.closeWorld(reporter);
    OutputUnitData result = deferredLoadTask.run(mainFunction, kClosedWorld);
    if (stage.emitsDeferredLoadIds) return null;

    // Impact data is no longer needed.
    if (!retainDataForTesting) {
      _impactCache.clear();
    }
    JClosedWorld jClosedWorld =
        backendStrategy.createJClosedWorld(kClosedWorld, result);
    return jClosedWorld;
  }

  /// Empty the [enqueuer] queue.
  void emptyQueue(Enqueuer enqueuer, {void onProgress(Enqueuer enqueuer)?}) {
    selfTask.measureSubtask("emptyQueue", () {
      enqueuer.forEach((WorkItem work) {
        if (onProgress != null) {
          onProgress(enqueuer);
        }
        reporter.withCurrentElement(
            work.element,
            () => selfTask.measureSubtask("applyImpact", () {
                  enqueuer.applyImpact(
                      selfTask.measureSubtask("work.run", () => work.run()));
                }));
      });
    });
  }

  void processQueue(ElementEnvironment elementEnvironment, Enqueuer enqueuer,
      FunctionEntity? mainMethod,
      {void onProgress(Enqueuer enqueuer)?}) {
    selfTask.measureSubtask("processQueue", () {
      enqueuer.open(
          mainMethod,
          elementEnvironment.libraries
              .map((LibraryEntity library) => library.canonicalUri));
      progress.startPhase();
      emptyQueue(enqueuer, onProgress: onProgress);
      enqueuer.queueIsClosed = true;
      enqueuer.close();
      assert(compilationFailed ||
          enqueuer.checkNoEnqueuedInvokedInstanceMethods(elementEnvironment));
    });
  }

  /// Perform various checks of the queue. This includes checking that the
  /// queues are empty (nothing was added after we stopped processing the
  /// queues).
  void checkQueue(Enqueuer enqueuer) {
    enqueuer.checkQueueIsEmpty();
  }

  void showResolutionProgress(Enqueuer enqueuer) {
    assert(_resolutionStatus == _ResolutionStatus.resolving,
        'Unexpected phase: $_resolutionStatus');
    progress.showProgress(
        'Resolved ', enqueuer.processedEntities.length, ' elements.');
  }

  void showCodegenProgress(Enqueuer enqueuer) {
    progress.showProgress(
        'Compiled ', enqueuer.processedEntities.length, ' methods.');
  }

  void reportDiagnostic(DiagnosticMessage message,
      List<DiagnosticMessage> infos, api.Diagnostic kind) {
    _reportDiagnosticMessage(message, kind);
    for (DiagnosticMessage info in infos) {
      _reportDiagnosticMessage(info, api.Diagnostic.context);
    }
  }

  void _reportDiagnosticMessage(
      DiagnosticMessage diagnosticMessage, api.Diagnostic kind) {
    var span = diagnosticMessage.sourceSpan;
    var message = diagnosticMessage.message;
    // If the message came from the CFE use the message code as the text
    // so that tests can determine the cause of the message.
    final messageText =
        diagnosticMessage is DiagnosticCfeMessage && options.testMode
            ? diagnosticMessage.messageCode
            : '$message';
    if (span.isUnknown) {
      callUserHandler(message, null, null, null, messageText, kind);
    } else {
      callUserHandler(
          message, span.uri, span.begin, span.end, messageText, kind);
    }
  }

  void callUserHandler(Message? message, Uri? uri, int? begin, int? end,
      String text, api.Diagnostic kind) {
    try {
      userHandlerTask.measure(() {
        handler.report(message, uri, begin, end, text, kind);
      });
    } catch (ex, s) {
      reportCrashInUserCode('Uncaught exception in diagnostic handler', ex, s);
      rethrow;
    }
  }

  Future<api.Input<Uint8List>> callUserProvider(
      Uri uri, api.InputKind inputKind) {
    try {
      return userProviderTask
          .measureIo(() => provider.readFromUri(uri, inputKind: inputKind));
    } catch (ex, s) {
      reportCrashInUserCode('Uncaught exception in input provider', ex, s);
      rethrow;
    }
  }

  void reportCrashInUserCode(
      String message, Object exception, StackTrace stackTrace) {
    reporter.onCrashInUserCode(message, exception, stackTrace);
  }

  /// Messages for which compile-time errors are reported but compilation
  /// continues regardless.
  static const List<MessageKind> BENIGN_ERRORS = <MessageKind>[
    MessageKind.INVALID_METADATA,
    MessageKind.INVALID_METADATA_GENERIC,
  ];

  bool markCompilationAsFailed(DiagnosticMessage message, api.Diagnostic kind) {
    if (options.testMode) {
      // When in test mode, i.e. on the build-bot, we always stop compilation.
      return true;
    }
    if (reporter.options.fatalWarnings) {
      return true;
    }
    return !BENIGN_ERRORS.contains(message.message.kind);
  }

  void fatalDiagnosticReported(DiagnosticMessage message,
      List<DiagnosticMessage> infos, api.Diagnostic kind) {
    if (markCompilationAsFailed(message, kind)) {
      compilationFailed = true;
    }
  }

  /// Compute a [SourceSpan] from spannable using the [currentElement] as
  /// context.
  SourceSpan spanFromSpannable(Spannable spannable, Entity? currentElement) {
    SourceSpan span;
    if (_resolutionStatus == _ResolutionStatus.compiling) {
      span = backendStrategy.spanFromSpannable(spannable, currentElement);
    } else {
      span = frontendStrategy.spanFromSpannable(spannable, currentElement);
    }
    return span;
  }

  /// Helper for determining whether [element] is declared within 'user code'.
  bool inUserCode(Entity? element) {
    return element == null || _uriFromElement(element) != null;
  }

  /// Return a canonical URI for the source of [element].
  ///
  /// For a package library with canonical URI 'package:foo/bar/baz.dart' the
  /// return URI is 'package:foo'. For non-package libraries the returned URI is
  /// the canonical URI of the library itself.
  Uri? getCanonicalUri(Entity element) {
    final libraryUri = _uriFromElement(element);
    if (libraryUri == null) return null;
    if (libraryUri.isScheme('package')) {
      int slashPos = libraryUri.path.indexOf('/');
      if (slashPos != -1) {
        String packageName = libraryUri.path.substring(0, slashPos);
        return Uri(scheme: 'package', path: packageName);
      }
    }
    return libraryUri;
  }

  Uri? _uriFromElement(Entity element) {
    if (element is LibraryEntity) {
      return element.canonicalUri;
    } else if (element is ClassEntity) {
      return element.library.canonicalUri;
    } else if (element is MemberEntity) {
      return element.library.canonicalUri;
    }
    return null;
  }

  void logInfo(String message) {
    callUserHandler(null, null, null, null, message, api.Diagnostic.info);
  }

  void logVerbose(String message) {
    callUserHandler(
        null, null, null, null, message, api.Diagnostic.verboseInfo);
  }

  String _formatMs(int ms) {
    return (ms / 1000).toStringAsFixed(3) + 's';
  }

  void computeTimings(Duration setupDuration, StringBuffer timings) {
    timings.writeln("Timings:");
    var totalDuration = measurer.elapsedWallClock;
    var asyncDuration = measurer.elapsedAsyncWallClock;
    var cumulatedDuration = Duration.zero;
    var timingData = <_TimingData>[];
    for (final task in tasks) {
      var running = task.isRunning ? "*" : " ";
      var duration = task.duration;
      if (duration != Duration.zero) {
        cumulatedDuration += duration;
        var milliseconds = duration.inMilliseconds;
        timingData.add(_TimingData('   $running${task.name}:', milliseconds,
            milliseconds * 100 / totalDuration.inMilliseconds));
        for (String subtask in task.subtasks) {
          var subtime = task.getSubtaskTime(subtask);
          var running = task.getSubtaskIsRunning(subtask) ? "*" : " ";
          timingData.add(_TimingData('   $running${task.name} > $subtask:',
              subtime, subtime * 100 / totalDuration.inMilliseconds));
        }
      }
    }
    int longestDescription = timingData
        .map((d) => d.description.length)
        .fold(0, (a, b) => a < b ? b : a);
    for (var data in timingData) {
      var ms = _formatMs(data.milliseconds);
      var padding =
          " " * (longestDescription + 10 - data.description.length - ms.length);
      var percentPadding = data.percent < 10 ? " " : "";
      timings.writeln('${data.description}$padding $ms '
          '$percentPadding(${data.percent.toStringAsFixed(1)}%)');
    }
    var unaccountedDuration =
        totalDuration - cumulatedDuration - setupDuration - asyncDuration;
    var percent =
        unaccountedDuration.inMilliseconds * 100 / totalDuration.inMilliseconds;
    timings.write(
        '    Total compile-time ${_formatMs(totalDuration.inMilliseconds)};'
        ' setup ${_formatMs(setupDuration.inMilliseconds)};'
        ' async ${_formatMs(asyncDuration.inMilliseconds)};'
        ' unaccounted ${_formatMs(unaccountedDuration.inMilliseconds)}'
        ' (${percent.toStringAsFixed(2)}%)');
  }

  void collectMetrics(StringBuffer buffer) {
    buffer.writeln('Metrics:');
    for (final task in tasks) {
      var metrics = task.metrics;
      var namespace = metrics.namespace;
      if (namespace == '') {
        namespace =
            task.name.toLowerCase().replaceAll(RegExp(r'[^a-z0-9]+'), '_');
      }
      void report(Metric metric) {
        buffer
            .writeln('  ${namespace}.${metric.name}: ${metric.formatValue()}');
      }

      for (final metric in metrics.primary) {
        report(metric);
      }
      if (options.reportSecondaryMetrics) {
        for (final metric in metrics.secondary) {
          report(metric);
        }
      }
    }
  }
}

class _CompilerOutput implements api.CompilerOutput {
  final Compiler _compiler;
  final api.CompilerOutput _userOutput;

  _CompilerOutput(this._compiler, api.CompilerOutput? output)
      : this._userOutput = output ?? const NullCompilerOutput();

  @override
  api.OutputSink createOutputSink(
      String name, String extension, api.OutputType type) {
    if (_compiler.compilationFailed) {
      // Ensure that we don't emit output when the compilation has failed.
      return const NullCompilerOutput().createOutputSink(name, extension, type);
    }
    return _userOutput.createOutputSink(name, extension, type);
  }

  @override
  api.BinaryOutputSink createBinarySink(Uri uri) {
    return _userOutput.createBinarySink(uri);
  }
}

class _TimingData {
  final String description;
  final int milliseconds;
  final double percent;

  _TimingData(this.description, this.milliseconds, this.percent);
}

/// Interface for showing progress during compilation.
class Progress {
  const Progress();

  /// Starts a new phase for which to show progress.
  void startPhase() {}

  /// Shows progress of the current phase if needed. The shown message is
  /// computed as '$prefix$count$suffix'.
  void showProgress(String prefix, int count, String suffix) {}
}

/// Progress implementations that prints progress to the [DiagnosticReporter]
/// with 500ms intervals.
class ProgressImpl implements Progress {
  final DiagnosticReporter _reporter;
  final Stopwatch _stopwatch = Stopwatch()..start();

  ProgressImpl(this._reporter);

  @override
  void showProgress(String prefix, int count, String suffix) {
    if (_stopwatch.elapsedMilliseconds > 500) {
      _reporter.log('$prefix$count$suffix');
      _stopwatch.reset();
    }
  }

  @override
  void startPhase() {
    _stopwatch.reset();
  }
}

/// Progress implementations that prints progress to the [DiagnosticReporter]
/// with 500ms intervals using escape sequences to keep the progress data on a
/// single line.
class InteractiveProgress implements Progress {
  final Stopwatch _stopwatchPhase = Stopwatch()..start();
  final Stopwatch _stopwatchInterval = Stopwatch()..start();

  @override
  void startPhase() {
    print('');
    _stopwatchPhase.reset();
    _stopwatchInterval.reset();
  }

  @override
  void showProgress(String prefix, int count, String suffix) {
    if (_stopwatchInterval.elapsedMilliseconds > 500) {
      var time = _stopwatchPhase.elapsedMilliseconds / 1000;
      var rate = count / _stopwatchPhase.elapsedMilliseconds;
      var s = StringBuffer('\x1b[1A\x1b[K') // go up and clear the line.
        ..write('\x1b[48;5;40m\x1b[30m==>\x1b[0m $prefix')
        ..write(count)
        ..write('$suffix Elapsed time: ')
        ..write(time.toStringAsFixed(2))
        ..write(' s. Rate: ')
        ..write(rate.toStringAsFixed(2))
        ..write(' units/ms');
      print('$s');
      _stopwatchInterval.reset();
    }
  }
}
