// Copyright (c) 2014, 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.

import 'dart:async';
import 'dart:io' as io;

import 'package:analysis_server/lsp_protocol/protocol.dart' as lsp;
import 'package:analysis_server/src/analytics/analytics_manager.dart';
import 'package:analysis_server/src/collections.dart';
import 'package:analysis_server/src/context_manager.dart';
import 'package:analysis_server/src/legacy_analysis_server.dart';
import 'package:analysis_server/src/lsp/client_capabilities.dart' as lsp;
import 'package:analysis_server/src/lsp/client_configuration.dart' as lsp;
import 'package:analysis_server/src/lsp/constants.dart' as lsp;
import 'package:analysis_server/src/lsp/error_or.dart' as lsp;
import 'package:analysis_server/src/lsp/handlers/handler_execute_command.dart'
    as lsp;
import 'package:analysis_server/src/lsp/handlers/handler_states.dart' as lsp;
import 'package:analysis_server/src/lsp/handlers/handlers.dart' as lsp;
import 'package:analysis_server/src/lsp/lsp_analysis_server.dart'
    as lsp
    show LspInitializationOptions;
import 'package:analysis_server/src/plugin/notification_manager.dart';
import 'package:analysis_server/src/plugin/plugin_isolate.dart';
import 'package:analysis_server/src/plugin/plugin_manager.dart';
import 'package:analysis_server/src/plugin/plugin_watcher.dart';
import 'package:analysis_server/src/protocol_server.dart'
    as legacy
    show MessageType;
import 'package:analysis_server/src/protocol_server.dart' as server;
import 'package:analysis_server/src/scheduler/message_scheduler.dart';
import 'package:analysis_server/src/scheduler/scheduler_tracking_listener.dart';
import 'package:analysis_server/src/server/crash_reporting_attachments.dart';
import 'package:analysis_server/src/server/diagnostic_server.dart';
import 'package:analysis_server/src/services/completion/completion_performance.dart';
import 'package:analysis_server/src/services/correction/fix_performance.dart';
import 'package:analysis_server/src/services/correction/refactoring_performance.dart';
import 'package:analysis_server/src/services/dart_tooling_daemon/dtd_services.dart';
import 'package:analysis_server/src/services/perf_witness/perf_witness.dart';
import 'package:analysis_server/src/services/pub/pub_api.dart';
import 'package:analysis_server/src/services/pub/pub_command.dart';
import 'package:analysis_server/src/services/pub/pub_package_service.dart';
import 'package:analysis_server/src/services/refactoring/legacy/refactoring.dart';
import 'package:analysis_server/src/services/search/element_visitors.dart';
import 'package:analysis_server/src/services/search/search_engine.dart';
import 'package:analysis_server/src/services/search/search_engine_internal.dart';
import 'package:analysis_server/src/services/user_prompts/dart_fix_prompt_manager.dart';
import 'package:analysis_server/src/services/user_prompts/survey_manager.dart';
import 'package:analysis_server/src/services/user_prompts/user_prompts.dart';
import 'package:analysis_server/src/session_logger/session_logger.dart';
import 'package:analysis_server/src/status/performance_logger.dart';
import 'package:analysis_server/src/status/utilities/report_data.dart';
import 'package:analysis_server/src/utilities/extensions/ast.dart';
import 'package:analysis_server/src/utilities/extensions/object.dart';
import 'package:analysis_server/src/utilities/file_string_sink.dart';
import 'package:analysis_server/src/utilities/process.dart';
import 'package:analysis_server/src/utilities/request_statistics.dart';
import 'package:analysis_server/src/utilities/tee_string_sink.dart';
import 'package:analysis_server/src/utilities/timing_byte_store.dart';
import 'package:analysis_server_plugin/src/correction/assist_performance.dart';
import 'package:analysis_server_plugin/src/correction/performance.dart';
import 'package:analyzer/dart/analysis/results.dart';
import 'package:analyzer/dart/analysis/session.dart';
import 'package:analyzer/dart/element/element.dart';
import 'package:analyzer/exception/exception.dart';
import 'package:analyzer/file_system/file_system.dart';
import 'package:analyzer/file_system/overlay_file_system.dart';
import 'package:analyzer/file_system/physical_file_system.dart';
import 'package:analyzer/instrumentation/instrumentation.dart';
import 'package:analyzer/source/line_info.dart';
import 'package:analyzer/src/dart/analysis/byte_store.dart';
import 'package:analyzer/src/dart/analysis/driver.dart' as analysis;
import 'package:analyzer/src/dart/analysis/driver.dart';
import 'package:analyzer/src/dart/analysis/driver_based_analysis_context.dart';
import 'package:analyzer/src/dart/analysis/file_byte_store.dart'
    show EvictingFileByteStore;
import 'package:analyzer/src/dart/analysis/file_content_cache.dart';
import 'package:analyzer/src/dart/analysis/library_graph.dart';
import 'package:analyzer/src/dart/analysis/performance_logger.dart';
import 'package:analyzer/src/dart/analysis/results.dart';
import 'package:analyzer/src/dart/analysis/session.dart';
import 'package:analyzer/src/dart/analysis/single_file_byte_store.dart';
import 'package:analyzer/src/dart/analysis/status.dart' as analysis;
import 'package:analyzer/src/dart/analysis/unlinked_unit_store.dart';
import 'package:analyzer/src/dartdoc/dartdoc_directive_info.dart';
import 'package:analyzer/src/file_system/timing_resource_provider.dart';
import 'package:analyzer/src/generated/sdk.dart';
import 'package:analyzer/src/util/file_paths.dart' as file_paths;
import 'package:analyzer/src/util/performance/operation_performance.dart';
import 'package:analyzer/src/util/platform_info.dart';
import 'package:analyzer/src/utilities/cancellation.dart';
import 'package:analyzer/src/utilities/extensions/analysis_session.dart';
import 'package:analyzer/src/workspace/basic.dart';
import 'package:analyzer/src/workspace/blaze.dart';
import 'package:analyzer/src/workspace/gn.dart';
import 'package:analyzer/src/workspace/pub.dart';
import 'package:analyzer_plugin/protocol/protocol.dart';
import 'package:analyzer_plugin/src/protocol/protocol_internal.dart'
    as analyzer_plugin;
import 'package:analyzer_plugin/src/utilities/client_uri_converter.dart';
import 'package:collection/collection.dart';
import 'package:http/http.dart' as http;
import 'package:meta/meta.dart';
import 'package:path/path.dart' as path;
import 'package:watcher/watcher.dart';

/// The function for sending `openUri` request to the client.
typedef OpenUriNotificationSender = Future<void> Function(Uri uri);

/// The function for sending prompts to the user and collecting button presses.
typedef UserPromptSender = Future<String?> Function(
  MessageType type,
  String message,
  List<String> actionLabels,
  lsp.CancellationToken cancellationToken,
);

/// Implementations of [AnalysisServer] implement a server that listens
/// on an [AbstractNotificationManager] for analysis messages and process them.
abstract class AnalysisServer {
  /// The options of this server instance.
  AnalysisServerOptions options;

  /// The object through which analytics are to be sent.
  final AnalyticsManager analyticsManager;

  /// The versions of each document known to the server (keyed by path), used to
  /// send back to the client for server-initiated edits so that the client can
  /// ensure they have a matching version of the document before applying them.
  ///
  /// Handlers should prefer to use the `getVersionedDocumentIdentifier` method
  /// which will return a null-versioned identifier if the document version is
  /// not known.
  final Map<String, int> documentVersions = {};

  /// A connection to DTD (the Dart Tooling Daemon) that allows other clients to
  /// call server functionality.
  ///
  /// Initialized by the client through a request that calls [connectToDtd].
  DtdServices? dtd;

  /// The object for managing showing surveys to users and recording their
  /// responses.
  ///
  /// `null` if surveys are not enabled.
  @visibleForTesting
  SurveyManager? surveyManager;

  /// The builder for attachments that should be included into crash reports.
  final CrashReportingAttachmentsBuilder crashReportingAttachmentsBuilder;

  /// The [ContextManager] that handles the mapping from analysis roots to
  /// context directories.
  late final ContextManager contextManager;

  /// The object used to manage sending a subset of notifications to the client.
  /// The subset of notifications are those to which plugins may contribute.
  AbstractNotificationManager notificationManager;

  /// A reference to the handler for executing commands.
  ///
  /// This allows the server to call commands itself, such as "Fix All in
  /// Workspace" triggered from the [DartFixPromptManager].
  lsp.ExecuteCommandHandler? executeCommandHandler;

  /// The object used to manage the execution of plugins.
  late PluginManager pluginManager;

  /// The object used to manage the SDK's known to this server.
  final DartSdkManager sdkManager;

  /// The [SearchEngine] for this server.
  late final SearchEngine searchEngine = SearchEngineImpl(driverMap.values);

  /// The optional [ByteStore] to use as [byteStore].
  final ByteStore? providedByteStore;

  late ByteStore byteStore;

  late FileContentCache fileContentCache;

  final UnlinkedUnitStore unlinkedUnitStore = UnlinkedUnitStoreImpl();

  late final analysis.AnalysisDriverScheduler analysisDriverScheduler;

  late StreamSubscription<Object?>? analysisDriverSchedulerEventsSubscription;

  /// The DiagnosticServer for this AnalysisServer. If available, it can be used
  /// to start an http diagnostics server or return the port for an existing
  /// server.
  final DiagnosticServer? diagnosticServer;

  /// Additional diagnostic info from the client editor to include in diagnostic
  /// reports.
  Object? clientDiagnosticInformation;

  /// A [RecentBuffer] of the most recent exceptions encountered by the analysis
  /// server.
  final RecentBuffer<ServerException> exceptions = RecentBuffer(10);

  /// The instrumentation service that is to be used by this analysis server.
  InstrumentationService instrumentationService;

  /// The session logger that is to be used by this analysis server.
  SessionLogger sessionLogger;

  /// Performance information after initial analysis is complete
  /// or `null` if the initial analysis is not yet complete
  ServerPerformance? performanceAfterStartup;

  /// A client for making requests to the pub.dev API.
  final PubApi pubApi;

  /// The performance logger.
  final PerformanceLogger? performanceLogger;

  /// A service for fetching pub.dev package details.
  late final PubPackageService pubPackageService;

  /// The class into which performance information is currently being recorded.
  /// During startup, this will be the same as [performanceDuringStartup]
  /// and after startup is complete, this switches to [performanceAfterStartup].
  late ServerPerformance performance;

  /// Performance information before initial analysis is complete.
  final ServerPerformance performanceDuringStartup = ServerPerformance();

  /// Performance about recent requests.
  final ServerRecentPerformance recentPerformance = ServerRecentPerformance();

  final RequestStatisticsHelper? requestStatistics;

  final PerformanceLog<TeeStringSink> analysisPerformanceLogger =
      PerformanceLog<TeeStringSink>(TeeStringSink());

  /// Manages prompts telling the user about "dart fix".
  late final DartFixPromptManager _dartFixPrompt;

  /// The set of the files that are currently priority.
  final Set<String> priorityFiles = <String>{};

  /// The [ResourceProvider] using which paths are converted into [Resource]s.
  final OverlayResourceProvider resourceProvider;

  /// The [ClientUriConverter] to use to convert between URIs/Paths when
  /// communicating with the client.
  late ClientUriConverter _uriConverter = ClientUriConverter.noop(
    resourceProvider.pathContext,
  );

  /// The next modification stamp for a changed file in the [resourceProvider].
  ///
  /// This value is increased each time it is used and used instead of real
  /// modification stamps. It's seeded with `millisecondsSinceEpoch` to reduce
  /// the chance of colliding with values used in previous analysis sessions if
  /// used as a cache key.
  int overlayModificationStamp = DateTime.now().millisecondsSinceEpoch;

  /// Indicates whether the next time the server completes analysis is the first
  /// one since analysis contexts were built.
  ///
  /// This is useful for triggering things like [_dartFixPrompt] only when
  /// it may be useful to do so (after initial analysis and
  /// "pub get"/"pub upgrades").
  bool _isFirstAnalysisSinceContextsBuilt = true;

  /// A completer that tracks in-progress analysis context rebuilds.
  ///
  /// Starts completed and will be replaced with a new completer each time an
  /// analysis context rebuild starts.
  Completer<void> analysisContextRebuildCompleter = Completer()..complete();

  /// The workspace for rename refactorings.
  late final refactoringWorkspace = RefactoringWorkspace(
    driverMap.values,
    searchEngine,
  );

  /// The paths of files for which [ResolvedUnitResult] was produced since
  /// the last idle state.
  final Set<String> filesResolvedSinceLastIdle = {};

  /// A completer for [lspInitialized].
  final Completer<lsp.InitializedStateMessageHandler> _lspInitializedCompleter =
      Completer<lsp.InitializedStateMessageHandler>();

  /// The handler passed to [completeLspInitialization], or `null` if LSP
  /// initialization has not completed yet.
  ///
  /// This allows [lspInitialized] to provide the handler synchronously once it
  /// is known.
  lsp.InitializedStateMessageHandler? _initializedLspHandler;

  /// A completer for [lspUninitialized].
  final Completer<void> _lspUninitializedCompleter = Completer<void>();

  /// A scheduler that keeps track of all incoming messages and schedules them
  /// for processing.
  final MessageScheduler messageScheduler;

  /// A [TimingByteStore] that records timings for reads from the byte store.
  TimingByteStore? _timingByteStore;

  /// The file byte store created by [createByteStore], if any.
  EvictingFileByteStore? _fileByteStore;

  /// The memory caching byte store created by [createByteStore], if any.
  MemoryCachingByteStore? _memoryCachingByteStore;

  /// The single-file byte store owned by this server, if any.
  SingleFileByteStore? _singleFileByteStore;

  /// Whether notifications caused by analysis should be suppressed.
  ///
  /// This is used when an operation is temporarily modifying overlays and does
  /// not want the client to be notified of any analysis happening on the
  /// temporary content.
  bool suppressAnalysisResults = false;

  new(
    this.options,
    this.sdkManager,
    this.diagnosticServer,
    this.analyticsManager,
    this.crashReportingAttachmentsBuilder,
    ResourceProvider baseResourceProvider,
    this.instrumentationService,
    this.sessionLogger,
    http.Client? httpClient,
    ProcessRunner? processRunner,
    this.notificationManager, {
    this.requestStatistics,
    // Disable to avoid using this in unit tests.
    @visibleForTesting bool enableBlazeWatcher = false,
    DartFixPromptManager? dartFixPromptManager,
    this.providedByteStore,
    PluginManager? pluginManager,
    MessageSchedulerListener? messageSchedulerListener,
    this.performanceLogger,
    required bool usePlugins,
    Map<String, String>? environment,
  }) : resourceProvider = OverlayResourceProvider(
         TimingResourceProvider(baseResourceProvider),
       ),
       pubApi = PubApi(
         instrumentationService,
         sessionLogger,
         httpClient,
         platform.environment['PUB_HOSTED_URL'],
       ),
       messageScheduler = MessageScheduler(
         listener:
             messageSchedulerListener ??
             SchedulerTrackingListener(analyticsManager, performanceLogger),
       ) {
    messageScheduler.server = this;
    // Set the default URI converter. This uses the resource providers path
    // context (unlike the initialized value) which allows tests to override it.
    uriConverter = ClientUriConverter.noop(baseResourceProvider.pathContext);

    // We can only spawn processes (eg. to run pub commands) when backed by
    // a real file system, otherwise we may try to run commands in folders that
    // don't really exist. If processRunner was supplied, it's likely a mock
    // from a test in which case the pub command should still be created.
    if (baseResourceProvider is PhysicalResourceProvider) {
      processRunner ??= ProcessRunner(environment: environment);
    }
    var disablePubCommandVariable =
        platform.environment[PubCommand.disablePubCommandEnvironmentKey];
    var pubCommand = processRunner != null && disablePubCommandVariable == null
        ? PubCommand(
            instrumentationService,
            sessionLogger,
            resourceProvider.pathContext,
            processRunner,
          )
        : null;

    pubPackageService = PubPackageService(
      instrumentationService,
      sessionLogger,
      baseResourceProvider,
      pubApi,
      pubCommand,
    );
    performance = performanceDuringStartup;

    this.pluginManager = pluginManager ??= PluginManager(
      resourceProvider,
      resourceProvider.byteStorePath,
      sdkManager.defaultSdkDirectory,
      notificationManager,
      instrumentationService,
      sessionLogger,
      processRunner: processRunner ?? ProcessRunner(environment: environment),
    );
    var pluginWatcher = PluginWatcher(
      resourceProvider,
      pluginManager,
      pluginsAreEnabled: usePlugins,
    );

    var logName = options.newAnalysisDriverLog;
    if (logName != null) {
      if (logName == 'stdout') {
        analysisPerformanceLogger.sink.addSink(io.stdout);
      } else if (logName.startsWith('file:')) {
        var path = logName.substring('file:'.length);
        analysisPerformanceLogger.sink.addSink(FileStringSink(path));
      }
    }

    var requestStatistics = this.requestStatistics;
    if (requestStatistics != null) {
      analysisPerformanceLogger.sink.addSink(
        requestStatistics.perfLoggerStringSink,
      );
    }

    byteStore = createByteStore(resourceProvider);
    fileContentCache = FileContentCache(resourceProvider);

    analysisDriverScheduler = analysis.AnalysisDriverScheduler(
      analysisPerformanceLogger,
      driverWatcher: pluginWatcher,
    );

    contextManager = ContextManagerImpl(
      resourceProvider,
      sdkManager,
      options.packagesFile,
      options.enabledExperiments,
      byteStore,
      fileContentCache,
      unlinkedUnitStore,
      analysisPerformanceLogger,
      analysisDriverScheduler,
      instrumentationService,
      sessionLogger,
      enableBlazeWatcher: enableBlazeWatcher,
      withFineDependencies: options.withFineDependencies,
    );

    _dartFixPrompt =
        dartFixPromptManager ??
        DartFixPromptManager(
          this,
          UserPromptPreferences(
            resourceProvider,
            instrumentationService,
            sessionLogger,
          ),
        );
  }

  /// A [Future] that completes when any in-progress analysis context rebuild
  /// completes.
  ///
  /// If no context rebuild is in progress, will return an already complete
  /// [Future].
  Future<void> get analysisContextsRebuilt =>
      analysisContextRebuildCompleter.future;

  /// Statistics for the byte stores created by [createByteStore], or `null`
  /// if the byte store was not created by this server.
  AnalysisServerByteStoreStats? get byteStoreStats {
    var memoryByteStore = _memoryCachingByteStore;
    if (memoryByteStore == null) {
      return null;
    }

    var fileByteStore = _fileByteStore;
    return AnalysisServerByteStoreStats(
      cacheHitCount: memoryByteStore.cacheHitCount,
      cacheMissCount: memoryByteStore.cacheMissCount,
      currentSizeBytes: memoryByteStore.currentSizeBytes,
      entryCount: memoryByteStore.entryCount,
      evictedBytes: memoryByteStore.evictedBytes,
      evictedEntryCount: memoryByteStore.evictedEntryCount,
      evictionCount: memoryByteStore.evictionCount,
      maxSizeBytes: memoryByteStore.maxSizeBytes,
      putCount: memoryByteStore.putCount,
      storeHitCount: memoryByteStore.storeHitCount,
      storeMissCount: memoryByteStore.storeMissCount,
      cleanUpCount: fileByteStore?.cleanUpCount,
      deletedBytes: fileByteStore?.deletedBytes,
      deletedFileCount: fileByteStore?.deletedFileCount,
      failedReadCount: fileByteStore?.failedReadCount,
      failedWriteCount: fileByteStore?.failedWriteCount,
      fileCacheSizeBytes: fileByteStore?.maxSizeBytes,
      fileStorePath: fileByteStore?.cachePath,
      fileStoreSizeBytes: fileByteStore?.lastKnownSizeBytes,
      lastCleanUpTimeMilliseconds: fileByteStore?.lastCleanUpTimeMilliseconds,
      lastScannedFileCount: fileByteStore?.lastScannedFileCount,
      pendingWriteCount: fileByteStore?.pendingWriteCount,
      readCount: fileByteStore?.readCount,
      readMissCount: fileByteStore?.readMissCount,
      writeBytes: fileByteStore?.writeBytes,
      writeCount: fileByteStore?.writeCount,
      singleFileStorePath: _singleFileByteStore?.filePath,
      singleFilePendingEntryCount: _singleFileByteStore?.pendingEntryCount,
    );
  }

  /// A list of timings for the byte store, or `null` if timing is not being
  /// tracked.
  List<ByteStoreTimings>? get byteStoreTimings => _timingByteStore?.timings;

  /// The workspace folders to request resource-scoped configuration for, in
  /// addition to the global configuration.
  ///
  /// Only the LSP server tracks workspace folders, so for other servers this
  /// is always empty and only the global configuration is requested.
  List<String> get configurationWorkspaceFolders => const [];

  /// The list of current analysis sessions in all contexts.
  Future<List<AnalysisSessionImpl>> get currentSessions async {
    var sessions = <AnalysisSessionImpl>[];
    for (var driver in driverMap.values) {
      await driver.applyPendingFileChanges();
      sessions.add(driver.currentSession);
    }
    return sessions;
  }

  /// The default line terminator that should be used by the server when there
  /// is no existing EOL to copy.
  String get defaultEol => platform.lineTerminator;

  /// A table mapping [Folder]s to the [AnalysisDriver]s associated with them.
  Map<Folder, analysis.AnalysisDriver> get driverMap =>
      contextManager.driverMap;

  /// The capabilities of the editor that owns this server.
  ///
  /// Request handlers should be careful to use the correct clients capabilities
  /// if they are available to non-editor clients (such as over DTD). The
  /// capabilities of the caller are available in [lsp.MessageInfo] and should
  /// usually be used when computing the results for requests, but if those
  /// requests additionally trigger requests to the editor, those requests to
  /// the editor should consider these capabilities.
  ///
  /// For the legacy server, this set may be a fixed set that is not actually
  /// configured by the client, but matches what legacy protocol editors expect
  /// when using LSP-over-Legacy.
  lsp.LspClientCapabilities? get editorClientCapabilities;

  /// The initialization options provided by the client for LSP initialization.
  ///
  /// These are only ever set for the LSP server and always null for
  /// LSP-over-Legacy. We now favor using [editorClientCapabilities]
  /// for clients to indicate their capabilities and preferences (and
  /// [lspClientConfiguration] for the users config/preferences).
  lsp.LspInitializationOptions? get initializationOptions;

  /// Whether [completeLspInitialization] has been called, and therefore whether
  /// [lspInitialized] returns the handler itself instead of a [Future].
  bool get isLspInitialized => _initializedLspHandler != null;

  /// The configuration (user/workspace settings) from the LSP client.
  ///
  /// For the legacy server, this set may be a fixed set that is not controlled
  /// by the client.
  lsp.LspClientConfiguration get lspClientConfiguration;

  /// A [Future] that completes when the LSP server moves into the initialized
  /// state and can handle normal LSP requests.
  ///
  /// Completes with the [lsp.InitializedStateMessageHandler] that is active.
  /// Before [completeLspInitialization] has been called this is a [Future],
  /// afterwards it is the handler itself, so callers that are not already async
  /// can avoid an `await`.
  ///
  /// When the server leaves the initialized state, [lspUninitialized] will
  /// complete.
  FutureOr<lsp.InitializedStateMessageHandler> get lspInitialized =>
      _initializedLspHandler ?? _lspInitializedCompleter.future;

  /// A [Future] that completes once the server transitions out of an
  /// initialized state.
  Future<void> get lspUninitialized => _lspUninitializedCompleter.future;

  /// Returns the function that can send `openUri` request to the client.
  /// Returns `null` is the client does not support it.
  OpenUriNotificationSender? get openUriNotificationSender;

  /// Returns owners of files.
  OwnedFiles get ownedFiles => contextManager.ownedFiles;

  path.Context get pathContext => resourceProvider.pathContext;

  /// Whether or not the client supports showMessageRequest to show the user
  /// a message and allow them to respond by clicking buttons.
  ///
  /// Callers should use [userPromptSender] instead of checking this directly.
  @protected
  bool get supportsShowMessageRequest;

  /// Resource operations measured since this server was created.
  TimingResourceProvider get timingResourceProvider =>
      resourceProvider.baseProvider as TimingResourceProvider;

  /// Return the total time the server's been alive.
  Duration get uptime {
    var start = DateTime.fromMillisecondsSinceEpoch(
      performanceDuringStartup.startTime,
    );
    return DateTime.now().difference(start);
  }

  /// The [ClientUriConverter] to use to convert between URIs/Paths when
  /// communicating with the client.
  ClientUriConverter get uriConverter => _uriConverter;

  /// Sets the [ClientUriConverter] to use to convert between URIs/Paths when
  /// communicating with the client.
  set uriConverter(ClientUriConverter value) {
    notificationManager.uriConverter = _uriConverter = value;
  }

  /// Returns the function for sending prompts to the user and collecting button
  /// presses.
  ///
  /// Returns `null` is the client does not support it.
  UserPromptSender? get userPromptSender =>
      supportsShowMessageRequest ? showUserPrompt : null;

  void afterContextsCreated() {
    _timingByteStore?.newTimings('after contexts created');
    _isFirstAnalysisSinceContextsBuilt = true;
  }

  void afterContextsDestroyed() {}

  /// Broadcast a request built from the given [requestParams] to all of the
  /// plugins that are currently associated with the context root from the given
  /// [driver]. Return a list containing futures that will complete when each of
  /// the plugins have sent a response, or an empty list if no [driver] is
  /// provided.
  Map<PluginIsolate, Future<Response>> broadcastRequestToPlugins(
    analyzer_plugin.RequestParams requestParams,
    analysis.AnalysisDriver? driver,
  ) {
    if (driver == null) {
      return <PluginIsolate, Future<Response>>{};
    }
    return pluginManager.broadcastRequest(
      requestParams,
      contextRoot: driver.analysisContext!.contextRoot,
    );
  }

  /// Display a message that will allow us to enable analytics on the next run.
  void checkAnalytics() {
    var unifiedAnalytics = analyticsManager.analytics;
    var prompt = userPromptSender;
    if (!unifiedAnalytics.shouldShowMessage || prompt == null) {
      return;
    }

    unawaited(
      prompt(MessageType.info, unifiedAnalytics.getConsentMessage, [
        lsp.UserPromptActions.ok,
      ], NotCancelableToken()),
    );
    unifiedAnalytics.clientShowedMessage();
  }

  /// Checks that all [sessions] are still consistent, throwing
  /// [InconsistentAnalysisException] if not.
  void checkConsistency(List<AnalysisSessionImpl> sessions) {
    for (var session in sessions) {
      session.checkConsistency();
    }
  }

  /// Completes [lspInitialized], signalling that the server has moved into an
  /// initialized state where it can handle standard LSP requests.
  ///
  /// This must be called exactly once; a second call throws. The legacy server
  /// can have initialization completed from more than one code path and routes
  /// them through `LegacyAnalysisServer.completeLspInitializationIfNeeded`.
  void completeLspInitialization(lsp.InitializedStateMessageHandler handler) {
    _initializedLspHandler = handler;
    _lspInitializedCompleter.complete(handler);
  }

  /// Completes [lspUninitialized], signalling that the server has moved out
  /// of a state where it can handle standard LSP requests.
  void completeLspUninitialization() {
    if (!_lspUninitializedCompleter.isCompleted) {
      _lspUninitializedCompleter.complete();
    }
  }

  /// Connects to DTD at [dtdUri].
  ///
  /// If there is already an active connection to DTD or there is an error
  /// connecting, returns an error, otherwise returns `null`.
  Future<lsp.ErrorOr<Null>> connectToDtd(
    Uri dtdUri, {
    bool registerExperimentalHandlers = false,
  }) async {
    switch (dtd?.state) {
      case DtdConnectionState.connecting || DtdConnectionState.connected:
        return lsp.error(
          lsp.ServerErrorCodes.stateError,
          'Server is already connected to DTD',
        );
      case DtdConnectionState.disconnected || DtdConnectionState.error || null:
        var connectResult = await DtdServices.connect(
          this,
          dtdUri,
          registerExperimentalHandlers: registerExperimentalHandlers,
        );
        return connectResult.mapResultSync((dtd) {
          this.dtd = dtd;
          return lsp.success(null);
        });
    }
  }

  /// If the state location can be accessed, return the file byte store,
  /// otherwise return the memory byte store.
  ByteStore createByteStore(ResourceProvider resourceProvider) {
    const M = 1024 * 1024 /*1 MiB*/;
    const G = 1024 * 1024 * 1024 /*1 GiB*/;

    const fileCacheSize = 4 * G;
    const memoryCacheSize = 256 * M;

    if (providedByteStore case var providedByteStore?) {
      if (providedByteStore is MemoryCachingByteStore) {
        _memoryCachingByteStore = providedByteStore;
      }
      return providedByteStore;
    }

    if (options.disableFileByteStore ?? false) {
      return _memoryCachingByteStore = MemoryCachingByteStore(
        NullByteStore(),
        memoryCacheSize,
      );
    }

    if (resourceProvider is OverlayResourceProvider) {
      resourceProvider = resourceProvider.baseProvider;
    }
    var baseProvider = resourceProvider is TimingResourceProvider
        ? resourceProvider.baseProvider
        : resourceProvider;
    if (baseProvider is PhysicalResourceProvider) {
      var stateLocation = resourceProvider.getStateLocation('.analysis-driver');
      if (stateLocation != null) {
        ByteStore fileByteStore;
        if (options.useSingleFileByteStore) {
          fileByteStore = _singleFileByteStore = SingleFileByteStore.file(
            stateLocation.parent.getFile('cache_v001.bin').path,
            filePageCountLog2: 22, // 4 GiB, including metadata.
            tableSlotCountLog2: 19, // 524,288 entries.
            bufferPoolCapacityLog2: 12, // 4 MiB of cached pages.
            maxPendingValueBytes: M,
            maxPendingEntryCount: 64,
          );
        } else {
          fileByteStore = _fileByteStore = EvictingFileByteStore(
            stateLocation.path,
            fileCacheSize,
          );
        }
        var timingByteStore = _timingByteStore = TimingByteStore(fileByteStore);
        return _memoryCachingByteStore = MemoryCachingByteStore(
          timingByteStore,
          memoryCacheSize,
        );
      }
    }

    return _memoryCachingByteStore = MemoryCachingByteStore(
      NullByteStore(),
      memoryCacheSize,
    );
  }

  void enableSurveys() {
    // TODO(dantup): This is currently gated on an LSP flag and should just
    //  be inlined into the constructor once we're happy for it to show up
    //  without a flag and for both protocols.
    surveyManager = SurveyManager(
      this,
      instrumentationService,
      sessionLogger,
      analyticsManager.analytics,
    );
  }

  /// Fetches the configuration from the client (if supported) and updates
  /// [lspClientConfiguration] with it.
  ///
  /// Configuration is requested for the whole workspace and additionally for
  /// each of [configurationWorkspaceFolders].
  Future<void> fetchClientConfiguration() async {
    if (!(editorClientCapabilities?.configuration ?? false)) {
      return;
    }

    // Take a copy of workspace folders because we need to match up the
    // responses to the request by index and it's possible the folders will
    // change after we sent the request but before we get the response.
    var folders = configurationWorkspaceFolders.toList();

    // Fetch all configuration we care about from the client. This is just
    // "dart" for now, but in future this may be extended to include
    // others (for example "flutter").
    var response = await sendLspRequest(
      lsp.Method.workspace_configuration,
      lsp.ConfigurationParams(
        items: [
          // Dart settings for each workspace folder.
          for (var folder in folders)
            lsp.ConfigurationItem(
              scopeUri: uriConverter.toClientUri(folder),
              section: 'dart',
            ),
          // Global Dart settings. This comes last to simplify matching up the
          // indexes in the results (folder[i] is the i'th item).
          lsp.ConfigurationItem(section: 'dart'),
        ],
      ),
    );

    var result = response.result;

    // Expect the result to be a list with 1 + folders.length items to
    // match the request above, and each should be a standard map of settings.
    // If the above code is extended to support multiple sets of config
    // this will need tweaking to handle the item for each section.
    if (result != null &&
        result is List<Object?> &&
        result.length == 1 + folders.length) {
      // Config is stored as a map keyed by the workspace folder, and a key of
      // null for the global config
      var workspaceFolderConfig = {
        for (var i = 0; i < folders.length; i++)
          folders[i]: result[i] as Map<String, Object?>? ?? {},
      };
      var newGlobalConfig = result.last as Map<String, Object?>? ?? {};

      var oldGlobalConfig = lspClientConfiguration.global;
      lspClientConfiguration.replace(newGlobalConfig, workspaceFolderConfig);

      // Refreshing the analysis roots also re-analyzes, so only one of these is
      // needed. Where [refreshAnalysisRoots] does nothing the settings that
      // affect the roots (such as excluded folders) have no effect either, so
      // skipping the re-analysis only matters for a change that affects both.
      if (lspClientConfiguration.affectsAnalysisRoots(oldGlobalConfig)) {
        await refreshAnalysisRoots();
      } else if (lspClientConfiguration.affectsAnalysisResults(
        oldGlobalConfig,
      )) {
        // Some settings affect analysis results and require re-analysis
        // (such as showTodos).
        await reanalyze();
      }
    }
  }

  /// Return an analysis driver to which the file with the given [path] is
  /// added if one exists, otherwise a driver in which the file was analyzed if
  /// one exists, otherwise the first driver, otherwise `null`.
  analysis.AnalysisDriver? getAnalysisDriver(String path) {
    var drivers = driverMap.values.toList();
    if (drivers.isNotEmpty) {
      // Sort the drivers so that more deeply nested contexts will be checked
      // before enclosing contexts.
      drivers.sort((first, second) {
        var firstRoot = first.analysisContext!.contextRoot.root.path;
        var secondRoot = second.analysisContext!.contextRoot.root.path;
        return secondRoot.length - firstRoot.length;
      });
      var driver = drivers.firstWhereOrNull(
        (driver) => driver.analysisContext!.contextRoot.isAnalyzed(path),
      );
      driver ??= drivers.firstWhereOrNull(
        (driver) => driver.fsState.getExistingFromPath(path) != null,
      );
      driver ??= drivers.first;
      return driver;
    }
    return null;
  }

  /// Return an [AnalysisSession] in which the file with the given [path]
  /// should be analyzed, preferring the one in which it is analyzed, then
  /// the one where it is referenced, then the first, otherwise `null`.
  Future<AnalysisSession?> getAnalysisSession(String path) async {
    var analysisDriver = getAnalysisDriver(path);
    if (analysisDriver != null) {
      await analysisDriver.applyPendingFileChanges();
      return analysisDriver.currentSession;
    }
    return null;
  }

  DartdocDirectiveInfo getDartdocDirectiveInfoFor(ResolvedUnitResult result) {
    return getDartdocDirectiveInfoForSession(result.session);
  }

  DartdocDirectiveInfo getDartdocDirectiveInfoForSession(
    AnalysisSession session,
  ) {
    var analysisContext = session.analysisContext;
    analysisContext as DriverBasedAnalysisContext;
    return analysisContext.driver.dartdocDirectiveInfo;
  }

  /// Gets the current version number of a document.
  int? getDocumentVersion(String path) => documentVersions[path];

  /// Return a [Future] that completes with the [Element] at the given
  /// [offset] of the given [file], or with `null` if there is no node at the
  /// [offset] or the node does not have an element.
  Future<Element?> getElementAtOffset(String file, int offset) async {
    var unitResult = await getResolvedUnit(file);
    if (unitResult == null) {
      return null;
    }

    if (!priorityFiles.contains(file)) {
      var fragment = findFragmentByNameOffset(
        unitResult.libraryFragment,
        offset,
      );
      if (fragment != null) {
        return fragment.element;
      }
    }

    var node = unitResult.unit.nodeCovering(offset: offset);
    return node?.getElement();
  }

  /// Return a [LineInfo] for the file with the given [path].
  ///
  /// If the file does not exist or cannot be read, returns `null`.
  ///
  /// This method supports non-Dart files but uses the current content of the
  /// file which may not be the latest analyzed version of the file if it was
  /// recently modified, so using the LineInfo from an analyzed result may be
  /// preferable. This method exists mainly to support plugins which do not
  /// provide us a matching [LineInfo] for the content they used.
  LineInfo? getLineInfo(String path) {
    try {
      // First try from the overlay because it may be more up-to-date than
      // the file state.
      var content = resourceProvider.getFile(path).readAsStringSync();
      return LineInfo.fromContent(content);
    } on FileSystemException {
      // If the file does not exist or cannot be read, try the file state
      // because this could be something like a macro-generated file.
      var result = getAnalysisDriver(path)?.getFileSync(path);
      if (result is FileResult) {
        return result.lineInfo;
      }

      return null;
    }
  }

  /// Return the unresolved unit for the file with the given [path].
  ///
  /// Callers should handle [InconsistentAnalysisException] exceptions that may
  /// occur if a file is modified during this operation.
  Future<ParsedUnitResult?> getParsedUnit(String path) async {
    if (!file_paths.isDart(resourceProvider.pathContext, path)) {
      return null;
    }

    var session = await getAnalysisSession(path);
    if (session == null) {
      return null;
    }

    try {
      RequestPerformanceAdditionalTimings.current?.pushAnalysis();
      var result = session.getParsedUnit(path);
      return result is ParsedUnitResult ? result : null;
    } finally {
      RequestPerformanceAdditionalTimings.current?.popAnalysis();
    }
  }

  /// Return the resolved library for the library containing the file with the
  /// given [path]. The library is analyzed in one of the analysis drivers to
  /// which the file was added, otherwise in the first driver, otherwise `null`
  /// is returned.
  Future<ResolvedLibraryResult?> getResolvedLibrary(String path) async {
    if (!file_paths.isDart(resourceProvider.pathContext, path)) {
      return null;
    }
    var driver = getAnalysisDriver(path);
    if (driver == null) {
      return null;
    }
    try {
      RequestPerformanceAdditionalTimings.current?.pushAnalysis();
      return await driver.currentSession.getResolvedContainingLibrary(path);
    } on InconsistentAnalysisException {
      return null;
    } catch (exception, stackTrace) {
      instrumentationService.logException(exception, stackTrace);
      sessionLogger.logException(exception: exception, stackTrace: stackTrace);
    } finally {
      RequestPerformanceAdditionalTimings.current?.popAnalysis();
    }
    return null;
  }

  /// Return the resolved unit for the file with the given [path]. The file is
  /// analyzed in one of the analysis drivers to which the file was added,
  /// otherwise in the first driver, otherwise `null` is returned.
  Future<ResolvedUnitResult?>? getResolvedUnit(
    String path, {
    bool sendCachedToStream = false,
    bool interactive = true,
  }) async {
    if (!file_paths.isDart(resourceProvider.pathContext, path)) {
      return null;
    }

    var driver = getAnalysisDriver(path);
    if (driver == null) {
      return Future.value();
    }

    try {
      RequestPerformanceAdditionalTimings.current?.pushAnalysis();
      var value = await driver.getResolvedUnit(
        path,
        sendCachedToStream: sendCachedToStream,
        interactive: interactive,
      );
      return value is ResolvedUnitResult ? value : null;
    } catch (exception, stackTrace) {
      instrumentationService.logException(exception, stackTrace);
      sessionLogger.logException(exception: exception, stackTrace: stackTrace);
      return null;
    } finally {
      RequestPerformanceAdditionalTimings.current?.popAnalysis();
    }
  }

  /// Gets the version of a document known to the server, returning a
  /// [lsp.OptionalVersionedTextDocumentIdentifier] with a version of `null` if the
  /// document version is not known.
  lsp.OptionalVersionedTextDocumentIdentifier getVersionedDocumentIdentifier(
    String path,
  ) {
    return lsp.OptionalVersionedTextDocumentIdentifier(
      uri: uriConverter.toClientUri(path),
      version: getDocumentVersion(path),
    );
  }

  @mustCallSuper
  void handleAnalysisEvent(Object event) {
    switch (event) {
      case FileResult():
        contextManager.callbacks.handleFileResult(event);
      case analysis.AnalysisStatus():
        handleAnalysisStatusChange(event);
    }
  }

  @mustCallSuper
  FutureOr<void> handleAnalysisStatusChange(analysis.AnalysisStatus status) {
    if (!status.isWorking) {
      _singleFileByteStore?.flush();
    }
    if (_isFirstAnalysisSinceContextsBuilt && !status.isWorking) {
      _timingByteStore?.newTimings('initial analysis completed');
      _isFirstAnalysisSinceContextsBuilt = false;
      _dartFixPrompt.triggerCheck();
    }
    analyticsManager.analysisStatusChanged(
      isWorking: status.isWorking,
      statistics: status
          .ifTypeOrNull<analysis.AnalysisStatusIdle>()
          ?.workingStatistics,
    );
  }

  /// Immediately handles an LSP message by delegating to the
  /// [lsp.InitializedStateMessageHandler]. This method does not schedule the
  /// message and is intended to be used by the scheduler (or LSP-over-Legacy
  /// where the original legacy wrapper was already scheduled).
  ///
  /// If the LSP server/support is not yet initialized, will wait until it is.
  FutureOr<lsp.ErrorOr<Object?>> immediatelyHandleLspMessage(
    lsp.IncomingMessage message,
    lsp.MessageInfo messageInfo, {
    lsp.CancellationToken? cancellationToken,
  }) async {
    // `lspInitialized` returns the handler itself once
    // `completeLspInitialization` has run and only before that a future, so the
    // await can usually be skipped.
    var initializedLspHandler = lspInitialized;
    var handler = initializedLspHandler is lsp.InitializedStateMessageHandler
        ? initializedLspHandler
        : await initializedLspHandler;

    return handler.handleMessage(
      message,
      messageInfo,
      cancellationToken: cancellationToken,
    );
  }

  /// Return `true` if the file or directory with the given [path] will be
  /// analyzed in one of the analysis contexts.
  bool isAnalyzed(String path) {
    return contextManager.isAnalyzed(path);
  }

  void logExceptionResult(analysis.ExceptionResult result) {
    var message = 'Analysis failed: ${result.filePath}';
    if (result.contextKey != null) {
      message += ' context: ${result.contextKey}';
    }

    var attachments = crashReportingAttachmentsBuilder.forExceptionResult(
      result,
    );

    // TODO(39284): should this exception be silent?
    instrumentationService.logException(
      SilentException.wrapInMessage(message, result.exception),
      null,
      attachments,
    );
    sessionLogger.logException(
      exception: SilentException.wrapInMessage(message, result.exception),
      attachments: attachments,
    );
  }

  /// Notify the flutter widget properties support that the file with the
  /// given [path] was changed - added, updated, or removed.
  void notifyFlutterWidgetDescriptions(String path) {}

  /// Prevents the scheduler from processing new messages until [operation]
  /// completes.
  ///
  /// This can be used to obtain analysis results/resolved units consistent with
  /// the state of a file at the time this method was called, preventing
  /// changes by incoming file modifications.
  ///
  /// The contents of [operation] should be kept as short as possible and since
  /// cancellation requests will also be blocked for the duration of this
  /// operation, handlers should generally check the cancellation flag
  /// immediately after this function returns.
  Future<T> pauseSchedulerWhile<T>(FutureOr<T> Function() operation) async {
    // TODO(dantup): Prevent this method from locking responses from the client
    //  because this can lead to deadlocks if called during initialization where
    //  the server may wait for something (configuration) from the client. This
    //  might fit in with potential upcoming scheduler changes.
    //
    // This is currently used by Completion+FixAll (which are less likely, but
    // possible to be called during init).
    //
    // https://github.com/dart-lang/sdk/issues/56311#issuecomment-2250089185

    messageScheduler.pause();
    try {
      // `await` here is important to ensure `finally` doesn't execute until
      // `operation()` completes (`whenComplete` is not available on
      // `FutureOr`).
      return await operation();
    } finally {
      messageScheduler.resume();
    }
  }

  void publishLspClosingLabels(String path, List<lsp.ClosingLabel> labels) {
    var params = lsp.PublishClosingLabelsParams(
      uri: uriConverter.toClientUri(path),
      labels: labels,
    );
    var message = lsp.NotificationMessage(
      method: lsp.CustomMethods.publishClosingLabels,
      params: params,
      jsonrpc: lsp.jsonRpcVersion,
    );
    sendLspNotification(message);
  }

  /// Read all files, resolve all URIs, and perform required analysis in
  /// all current analysis drivers.
  Future<void> reanalyze() async {
    await contextManager.refresh();
  }

  /// Recomputes the analysis roots because client configuration that affects
  /// them (such as excluded folders) has changed.
  ///
  /// Analysis roots are only computed from client configuration by the LSP
  /// server. Other clients set their roots explicitly (for the legacy protocol
  /// with `analysis.setAnalysisRoots`) so there is nothing to do here.
  @protected
  Future<void> refreshAnalysisRoots() async {}

  /// Report analytics data related to the number and size of files that were
  /// analyzed.
  void reportAnalysisAnalytics() {
    if (performanceLogger != null) {
      Map<String, Object?> collectedData = {};
      collectContextData(collectedData, this);
      performanceLogger!.logMap(collectedData);
    }
    if (!analyticsManager.needsAnslysisCompleteCall()) {
      return;
    }
    var packagesFileMap = <String, File?>{};
    var immediateFileCount = 0;
    var immediateFileLineCount = 0;
    var transitiveFileCount = 0;
    var transitiveFileLineCount = 0;
    var transitiveFilePaths = <String>{};
    var transitiveFileUniqueLineCount = 0;
    var libraryCycles = <LibraryCycle>{};
    var workspaceTypes = List<int>.filled(5, 0);
    var numberOfPackages = <int>[];
    var driverMap = contextManager.driverMap;
    for (var entry in driverMap.entries) {
      var rootPath = entry.key.path;
      var driver = entry.value;
      var analysisContext = driver.analysisContext;
      if (analysisContext != null) {
        var contextRoot = analysisContext.contextRoot;
        packagesFileMap[rootPath] = contextRoot.packagesFile;
        var workspace = contextRoot.workspace;
        switch (workspace) {
          case PackageConfigWorkspace():
            if (workspace.isPubWorkspace) {
              // Pub workspace index = 2, Package workspace index = 1
              workspaceTypes[2]++;
              numberOfPackages.add(workspace.allPackages.length);
            } else {
              workspaceTypes[1]++;
            }
          case BlazeWorkspace():
            workspaceTypes[3]++;
          case GnWorkspace():
            workspaceTypes[4]++;
          case BasicWorkspace():
            workspaceTypes[0]++;
        }
      }
      var fileSystemState = driver.fsState;
      // Capture the known files before the loop to prevent a concurrent
      // modification exception. The reason for the exception is unknown.
      var knownFiles = fileSystemState.knownFiles.toList();
      for (var fileState in knownFiles) {
        var isImmediate = fileState.path.startsWith(rootPath);
        if (isImmediate) {
          immediateFileCount++;
          immediateFileLineCount += fileState.lineInfo.lineCount;
          var libraryKind = fileState.kind.library;
          if (libraryKind != null) {
            libraryCycles.add(libraryKind.libraryCycle);
          }
        } else {
          var lineCount = fileState.lineInfo.lineCount;
          transitiveFileCount++;
          transitiveFileLineCount += lineCount;
          if (transitiveFilePaths.add(fileState.path)) {
            transitiveFileUniqueLineCount += lineCount;
          }
        }
      }
    }
    var transitiveFileUniqueCount = transitiveFilePaths.length;

    var libraryCycleLibraryCounts = <int>[];
    var libraryCycleLineCounts = <int>[];
    for (var libraryCycle in libraryCycles) {
      var libraries = libraryCycle.libraries;
      var lineCount = 0;
      for (var library in libraries) {
        for (var file in library.files) {
          lineCount += file.lineInfo.lineCount;
        }
      }
      libraryCycleLibraryCounts.add(libraries.length);
      libraryCycleLineCounts.add(lineCount);
    }

    analyticsManager.analysisComplete(
      numberOfContexts: driverMap.length,
      immediateFileCount: immediateFileCount,
      immediateFileLineCount: immediateFileLineCount,
      transitiveFileCount: transitiveFileCount,
      transitiveFileLineCount: transitiveFileLineCount,
      transitiveFileUniqueCount: transitiveFileUniqueCount,
      transitiveFileUniqueLineCount: transitiveFileUniqueLineCount,
      libraryCycleLibraryCounts: libraryCycleLibraryCounts,
      libraryCycleLineCounts: libraryCycleLineCounts,
      contextWorkspaceType: workspaceTypes,
      numberOfPackagesInWorkspace: numberOfPackages,
    );
  }

  Future<ResolvedForCompletionResultImpl?> resolveForCompletion({
    required String path,
    required int offset,
    required OperationPerformanceImpl performance,
  }) async {
    if (!file_paths.isDart(resourceProvider.pathContext, path)) {
      return null;
    }

    var driver = getAnalysisDriver(path);
    if (driver == null) {
      return null;
    }

    var result = _tryGetCachedResolvedUnitAsResolvedForCompletion(driver, path);
    if (result != null) return result;

    try {
      return await driver.resolveForCompletion(
        path: path,
        offset: offset,
        performance: performance,
      );
    } catch (exception, stackTrace) {
      instrumentationService.logException(exception, stackTrace);
      sessionLogger.logException(exception: exception, stackTrace: stackTrace);
    }
    return null;
  }

  Future<ResolvedForCompletionResultImpl?> resolveForCompletionWithLineColumn({
    required String path,
    required int line,
    required int column,
    required OperationPerformanceImpl performance,
  }) async {
    if (!file_paths.isDart(resourceProvider.pathContext, path)) {
      return null;
    }

    var driver = getAnalysisDriver(path);
    if (driver == null) {
      return null;
    }

    var result = _tryGetCachedResolvedUnitAsResolvedForCompletion(driver, path);
    if (result != null) return result;

    try {
      return await driver.resolveForCompletionWithLineColumn(
        path: path,
        line: line,
        column: column,
        performance: performance,
      );
    } catch (exception, stackTrace) {
      instrumentationService.logException(exception, stackTrace);
      sessionLogger.logException(exception: exception, stackTrace: stackTrace);
    }
    return null;
  }

  /// Sends an LSP notification to the client.
  ///
  /// The legacy server will wrap LSP notifications inside an
  /// 'lsp.notification' notification.
  void sendLspNotification(lsp.NotificationMessage notification);

  /// Sends an LSP request with the given [params] to the client and waits for a
  /// response. Completes with the raw [lsp.ResponseMessage] which could be an
  /// error response.
  Future<lsp.ResponseMessage> sendLspRequest(lsp.Method method, Object params);

  /// Sends an error notification to the user.
  void sendServerErrorNotification(
    String message,
    Object exception,
    StackTrace? stackTrace, {
    bool fatal = false,
  });

  /// Shows the user a prompt with some actions to select from using
  /// 'window/showMessageRequest'.
  ///
  /// Callers should use [userPromptSender] instead of calling this method
  /// directly because it returns null if the client does not support user
  /// prompts.
  @visibleForOverriding
  Future<String?> showUserPrompt(
    MessageType type,
    String message,
    List<String> actionLabels,
    lsp.CancellationToken cancellationToken,
  );

  @mustCallSuper
  Future<void> shutdown() async {
    await performanceLogger?.shutdown();
    completeLspUninitialization();

    await analysisDriverSchedulerEventsSubscription?.cancel();
    analysisDriverSchedulerEventsSubscription = null;

    // For now we record plugins only on shutdown. We might want to record them
    // every time the set of plugins changes, in which case we'll need to listen
    // to the `PluginManager.pluginsChanged` stream.
    await analyticsManager.changedPlugins(pluginManager);

    // For now we record context-dependent information only on shutdown. We
    // might want to record it on start-up as well.
    analyticsManager.createdAnalysisContexts(contextManager.analysisContexts);

    pubPackageService.shutdown();
    surveyManager?.shutdown();
    await contextManager.dispose();
    await _fileByteStore?.flush();
    _singleFileByteStore?.close();
    await analyticsManager.shutdown();
    await shutdownPerfWitness();
    await sessionLogger.shutdown();
  }

  ResolvedForCompletionResultImpl?
  _tryGetCachedResolvedUnitAsResolvedForCompletion(
    AnalysisDriver driver,
    String path,
  ) {
    try {
      ResolvedUnitResult? result = driver.getCachedResolvedUnit(path);
      if (result != null) {
        result as ResolvedUnitResultImpl;
        return ResolvedForCompletionResultImpl(
          analysisSession: result.session,
          fileState: result.fileState,
          path: path,
          uri: result.uri,
          exists: result.exists,
          content: result.content,
          lineInfo: result.lineInfo,
          parsedUnit: result.unit,
          libraryFragment: result.libraryFragment,
          resolvedNodes: [result.unit],
        );
      }
    } catch (exception, stackTrace) {
      instrumentationService.logException(exception, stackTrace);
      sessionLogger.logException(exception: exception, stackTrace: stackTrace);
    }
    return null;
  }
}

/// A snapshot of the sizes and counters of the byte stores used by the
/// server, for display on the diagnostics pages.
///
/// Fields specific to a persistent byte store are `null` when that store is
/// not used by the server.
class AnalysisServerByteStoreStats {
  final int cacheHitCount;
  final int cacheMissCount;
  final int? cleanUpCount;
  final int currentSizeBytes;
  final int? deletedBytes;
  final int? deletedFileCount;
  final int entryCount;
  final int evictedBytes;
  final int evictedEntryCount;
  final int evictionCount;
  final int? failedReadCount;
  final int? failedWriteCount;
  final int? fileCacheSizeBytes;
  final String? fileStorePath;
  final int? fileStoreSizeBytes;
  final int? lastCleanUpTimeMilliseconds;
  final int? lastScannedFileCount;
  final int maxSizeBytes;
  final int? pendingWriteCount;
  final int putCount;
  final int? readCount;
  final int? readMissCount;
  final int? singleFilePendingEntryCount;
  final String? singleFileStorePath;
  final int storeHitCount;
  final int storeMissCount;
  final int? writeBytes;
  final int? writeCount;

  const new({
    required this.cacheHitCount,
    required this.cacheMissCount,
    required this.currentSizeBytes,
    required this.entryCount,
    required this.evictedBytes,
    required this.evictedEntryCount,
    required this.evictionCount,
    required this.maxSizeBytes,
    required this.putCount,
    required this.storeHitCount,
    required this.storeMissCount,
    this.cleanUpCount,
    this.deletedBytes,
    this.deletedFileCount,
    this.failedReadCount,
    this.failedWriteCount,
    this.fileCacheSizeBytes,
    this.fileStorePath,
    this.fileStoreSizeBytes,
    this.lastCleanUpTimeMilliseconds,
    this.lastScannedFileCount,
    this.pendingWriteCount,
    this.readCount,
    this.readMissCount,
    this.singleFilePendingEntryCount,
    this.singleFileStorePath,
    this.writeBytes,
    this.writeCount,
  });

  bool get usesFileByteStore => fileStorePath != null;
}

/// ContextManager callbacks that operate on the base server regardless
/// of protocol.
abstract class CommonServerContextManagerCallbacks
    extends ContextManagerCallbacks {
  /// The [ResourceProvider] by which paths are converted into [Resource]s.
  final OverlayResourceProvider resourceProvider;

  /// The set of files for which notifications were sent.
  final Set<String> filesToFlush = {};

  new(this.resourceProvider);

  @override
  @mustCallSuper
  void afterContextsCreated() {
    analysisServer.afterContextsCreated();
  }

  @override
  @mustCallSuper
  void afterContextsDestroyed() {
    flushResults(filesToFlush.toList());
    filesToFlush.clear();
    analysisServer.afterContextsDestroyed();
  }

  @override
  void afterWatchEvent(WatchEvent event) {}

  @override
  @mustCallSuper
  void applyFileRemoved(String file) {
    // If the removed file doesn't have an overlay, we need to clear any
    // previous results.
    if (!resourceProvider.hasOverlay(file)) {
      // Clear the cached errors in the notification manager so we don't
      // re-send stale results if a plugin sends an update and we merge it with
      // previous results.
      analysisServer.notificationManager.errors.clearResultsForFile(file);

      if (filesToFlush.remove(file)) {
        flushResults([file]);
      }
    }
  }

  @override
  @mustCallSuper
  void broadcastWatchEvent(WatchEvent event) {
    analysisServer.notifyFlutterWidgetDescriptions(event.path);
    analysisServer.pluginManager.broadcastWatchEvent(event);
  }

  void flushResults(List<String> files);

  @override
  @mustCallSuper
  void handleFileResult(FileResult result) {
    if (analysisServer.suppressAnalysisResults) {
      return;
    }

    var path = result.path;
    filesToFlush.add(path);

    if (result is AnalysisResultWithDiagnostics) {
      if (analysisServer.isAnalyzed(path)) {
        var serverErrors = server.doAnalysisError_listFromEngine(result);
        recordAnalysisErrors(path, serverErrors);
      }
    }

    if (result is ResolvedUnitResult) {
      analysisServer.filesResolvedSinceLastIdle.add(path);
      handleResolvedUnitResult(result);
    }
  }

  void handleResolvedUnitResult(ResolvedUnitResult result);

  @override
  @mustCallSuper
  void listenAnalysisDriver(analysis.AnalysisDriver driver) {
    driver.exceptions.listen(analysisServer.logExceptionResult);
    driver.priorityFiles = analysisServer.priorityFiles.toList();
  }

  @override
  void pubspecChanged(String path) {
    analysisServer.pubPackageService.fetchPackageVersionsViaPubOutdated(
      path,
      pubspecWasModified: true,
    );
  }

  @override
  void pubspecRemoved(String path) {
    analysisServer.pubPackageService.flushPackageCaches(path);
  }

  @override
  @mustCallSuper
  void recordAnalysisErrors(String path, List<server.AnalysisError> errors) {
    filesToFlush.add(path);
    analysisServer.notificationManager.recordAnalysisErrors(
      NotificationManager.serverId,
      path,
      errors,
    );
  }
}

/// A server-agnostic type for messages sent to the client.
enum MessageType {
  error(lsp.MessageType.Error, legacy.MessageType.ERROR),
  warning(lsp.MessageType.Warning, legacy.MessageType.WARNING),
  info(lsp.MessageType.Info, legacy.MessageType.INFO),
  log(lsp.MessageType.Log, legacy.MessageType.LOG);

  final lsp.MessageType forLsp;
  final legacy.MessageType forLegacy;

  new(this.forLsp, this.forLegacy);

  static MessageType fromLegacy(legacy.MessageType type) {
    return MessageType.values.singleWhere((t) => t.forLegacy == type);
  }

  static MessageType fromLsp(lsp.MessageType type) {
    return MessageType.values.singleWhere((t) => t.forLsp == type);
  }
}

class ServerRecentPerformance {
  /// The maximum number of performance measurements to keep.
  static const int performanceListMaxLength = 250;

  /// The maximum number of slow performance measurements to keep.
  static const int slowRequestsListMaxLength = 1000;

  /// The duration we use to categorize requests as slow.
  static const Duration slowRequestsThreshold = Duration(milliseconds: 500);

  /// A list of code completion performance measurements for the latest
  /// completion operation up to [performanceListMaxLength] measurements.
  final RecentBuffer<CompletionPerformance> completion =
      RecentBuffer<CompletionPerformance>(performanceListMaxLength);

  /// A list of performance measurements for the latest requests to get fixes
  /// up to [performanceListMaxLength] measurements.
  final RecentBuffer<GetAssistsPerformance> getAssists =
      RecentBuffer<GetAssistsPerformance>(performanceListMaxLength);

  /// A list of performance measurements for the latest requests to get fixes
  /// up to [performanceListMaxLength] measurements.
  final RecentBuffer<GetFixesPerformance> getFixes =
      RecentBuffer<GetFixesPerformance>(performanceListMaxLength);

  /// A list of performance measurements for the latest requests to get refactorings
  /// up to [performanceListMaxLength] measurements.
  final RecentBuffer<GetRefactoringsPerformance> getRefactorings =
      RecentBuffer<GetRefactoringsPerformance>(performanceListMaxLength);

  /// A [RecentBuffer] for performance information about the most recent
  /// requests.
  final RecentBuffer<RequestPerformance> requests = RecentBuffer(
    performanceListMaxLength,
  );

  /// A [RecentBuffer] for performance information about the most recent
  /// slow requests.
  final RecentBuffer<RequestPerformance> slowRequests = RecentBuffer(
    slowRequestsListMaxLength,
  );
}

extension on OverlayResourceProvider {
  /// The path to the location of the byte store on disk, or `null` if there is
  /// no on-disk byte store.
  String? get byteStorePath {
    var provider = baseProvider;
    var physicalProvider = provider is TimingResourceProvider
        ? provider.baseProvider
        : provider;
    if (physicalProvider is PhysicalResourceProvider) {
      var stateLocation = provider.getStateLocation('.analysis-driver');
      return stateLocation?.path;
    }
    return null;
  }
}
