// 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;

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

import 'package:compiler/src/universe/use.dart' show StaticUse;
// ignore: implementation_imports
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/trivial.dart' show TrivialAbstractValueStrategy;
import 'inferrer/typemasks/masks.dart' show TypeMaskStrategy;
import 'inferrer/types.dart'
    show GlobalTypeInferenceResults, GlobalTypeInferenceTask;
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.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(noLocationSpannable, 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;
    final trimmedComponent = ir.Component(
      libraries: irLibraries,
      uriToSource: component.uriToSource,
      nameRoot: component.root,
    );
    trimmedComponent.setMainMethodAndMode(mainMethod, true);
    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,
          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 Function(Enqueuer enqueuer)? onProgress,
  }) {
    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 Function(Enqueuer enqueuer)? onProgress,
  }) {
    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> benignErrors = <MessageKind>[
    MessageKind.invalidMetadata,
    MessageKind.invalidMetadataGeneric,
  ];

  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 !benignErrors.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)
    : _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();
    }
  }
}
